diff --git a/app/src/androidTest/java/com/nmc/android/AppColorTest.kt b/app/src/androidTest/java/com/nmc/android/AppColorTest.kt new file mode 100644 index 000000000000..cffd91becec9 --- /dev/null +++ b/app/src/androidTest/java/com/nmc/android/AppColorTest.kt @@ -0,0 +1,363 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nmc.android + +import android.content.Context +import android.content.res.Configuration +import android.graphics.Color +import androidx.core.content.ContextCompat +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.owncloud.android.R +import junit.framework.TestCase.assertEquals +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Test class to verify the colors customized in this branch PR for NMC + */ +@RunWith(AndroidJUnit4::class) +class AppColorTest { + private val expectedColorMap = mapOf( + R.color.list_item_lastmod_and_filesize_text to ExpectedColor( + light = "#666666", + dark = "#B2B2B2" + ), + R.color.text_color to ExpectedColor( + light = "#191919", + dark = "#E3E3E3" + ), + R.color.light_grey to ExpectedColor( + light = "#F5F5F5", + dark = "#F5F5F5" // same for light and dark + ), + R.color.secondary_text_color to ExpectedColor( + light = "#B2B2B2", + dark = "#A5A5A5" + ), + R.color.action_mode_background to ExpectedColor( + light = "#FFFFFF", + dark = "#121212" + ), + R.color.selected_item_background to ExpectedColor( + light = "#F2F2F2", + dark = "#4C4C4C" + ), + R.color.drawer_active_item_background to ExpectedColor( + light = "#919191", + dark = "#FFFFFF" + ), + R.color.fontAppbar to ExpectedColor( + light = "#191919", + dark = "#FFFFFF" + ), + R.color.icon_color to ExpectedColor( + light = "#191919", + dark = "#FFFFFF" + ), + R.color.sort_text_color to ExpectedColor( + light = "#E20074", // primary magenta color + dark = "#B2B2B2" + ), + R.color.list_icon_color to ExpectedColor( + light = "#191919", + dark = "#B2B2B2" + ), + R.color.warning_icon_color to ExpectedColor( + light = "#191919", + dark = "#CCCCCC" + ), + R.color.divider_color to ExpectedColor( + light = "#B2B2B2", + dark = "#4C4C4C" + ), + R.color.spinner_bg_color to ExpectedColor( + light = "#FFFFFF", + dark = "#333333" + ), + R.color.refresh_layout_bg_color to ExpectedColor( + light = "#FFFFFF", + dark = "#2D2D2D" + ), + R.color.primary_button_disabled_color to ExpectedColor( + light = "#F2F2F2", + dark = "#4C4C4C" + ), + R.color.toolbar_divider_color to ExpectedColor( + light = "#CCCCCC", + dark = "#4C4C4C" + ), + R.color.et_highlight_color to ExpectedColor( + light = "#77c4ff", + dark = "#77c4ff" // same for light and dark + ), + R.color.white_trans_70 to ExpectedColor( + light = "#B3FFFFFF", + dark = "#B3FFFFFF" // same for light and dark + ), + R.color.progress_bar_background to ExpectedColor( + light = "#E5E5E5", + dark = "#E5E5E5" // same for light and dark + ), + R.color.dark_grey to ExpectedColor( + light = "#101010", + dark = "#101010" // same for light and dark + ), + R.color.grey_0 to ExpectedColor( + light = "#F2F2F2", + dark = "#F2F2F2" // same for light and dark + ), + R.color.grey_10 to ExpectedColor( + light = "#E5E5E5", + dark = "#E5E5E5" // same for light and dark + ), + R.color.grey_30 to ExpectedColor( + light = "#B2B2B2", + dark = "#B2B2B2" // same for light and dark + ), + R.color.grey_60 to ExpectedColor( + light = "#666666", + dark = "#666666" // same for light and dark + ), + R.color.grey_70 to ExpectedColor( + light = "#4C4C4C", + dark = "#4C4C4C" // same for light and dark + ), + R.color.grey_80 to ExpectedColor( + light = "#333333", + dark = "#333333" // same for light and dark + ), + R.color.snackbar_bg_color to ExpectedColor( + light = "#323232", + dark = "#333333" + ), + R.color.snackbar_txt_color to ExpectedColor( + light = "#FFFFFF", + dark = "#F2F2F2" + ), + R.color.alert_bg_color to ExpectedColor( + light = "#FFFFFF", + dark = "#333333" + ), + R.color.alert_txt_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.nav_selected_bg_color to ExpectedColor( + light = "#F2F2F2", + dark = "#666666" + ), + R.color.nav_txt_unselected_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.nav_txt_selected_color to ExpectedColor( + light = "#E20074", // primary magenta color + dark = "#F2F2F2" + ), + R.color.nav_icon_unselected_color to ExpectedColor( + light = "#191919", + dark = "#B2B2B2" + ), + R.color.nav_icon_selected_color to ExpectedColor( + light = "#E20074", // primary magenta color + dark = "#FFFFFF" + ), + R.color.nav_divider_color to ExpectedColor( + light = "#B2B2B2", + dark = "#B2B2B2" // same for light and dark + ), + R.color.nav_bg_color to ExpectedColor( + light = "#FFFFFF", + dark = "#333333" + ), + R.color.drawer_quota_txt_color to ExpectedColor( + light = "#191919", + dark = "#FFFFFF" + ), + R.color.bottom_sheet_bg_color to ExpectedColor( + light = "#FFFFFF", + dark = "#333333" + ), + R.color.bottom_sheet_icon_color to ExpectedColor( + light = "#191919", + dark = "#B2B2B2" + ), + R.color.bottom_sheet_txt_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.popup_menu_bg to ExpectedColor( + light = "#FFFFFF", + dark = "#333333" + ), + R.color.popup_menu_txt_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.overflow_bg_color to ExpectedColor( + light = "#FFFFFF", + dark = "#333333" + ), + R.color.switch_thumb_checked_enabled to ExpectedColor( + light = "#E20074", // primary magenta color + dark = "#E20074", // same for light and dark + ), + R.color.switch_track_checked_enabled to ExpectedColor( + light = "#F399C7", + dark = "#F399C7" // same for light and dark + ), + R.color.switch_thumb_unchecked_enabled to ExpectedColor( + light = "#FFFFFF", + dark = "#FFFFFF" // same for light and dark + ), + R.color.switch_track_unchecked_enabled to ExpectedColor( + light = "#B2B2B2", + dark = "#B2B2B2" // same for light and dark + ), + R.color.switch_thumb_disabled to ExpectedColor( + light = "#E5E5E5", + dark = "#4C4C4C" + ), + R.color.switch_track_disabled to ExpectedColor( + light = "#F2F2F2", + dark = "#666666" + ), + R.color.checkbox_checked_enabled to ExpectedColor( + light = "#E20074", // primary magenta color + dark = "#E20074", // same for light and dark + ), + R.color.checkbox_unchecked_enabled to ExpectedColor( + light = "#B2B2B2", + dark = "#B2B2B2" // same for light and dark + ), + R.color.checkbox_checked_disabled to ExpectedColor( + light = "#B2B2B2", + dark = "#4C4C4C" + ), + R.color.checkbox_unchecked_disabled to ExpectedColor( + light = "#CCCCCC", + dark = "#4C4C4C" + ), + R.color.share_title_txt_color to ExpectedColor( + light = "#191919", + dark = "#FFFFFF" + ), + R.color.share_subtitle_txt_color to ExpectedColor( + light = "#B2B2B2", + dark = "#B2B2B2" + ), + R.color.share_info_txt_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.share_search_border_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.share_btn_txt_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.share_list_item_txt_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.share_disabled_txt_color to ExpectedColor( + light = "#B2B2B2", + dark = "#666666" + ), + R.color.share_txt_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.share_et_divider to ExpectedColor( + light = "#000000", + dark = "#FFFFFF" + ), + R.color.share_warning_txt_color to ExpectedColor( + light = "#191919", + dark = "#191919" // same for light and dark + ), + R.color.sharing_warning_bg_color to ExpectedColor( + light = "#F6E5EB", + dark = "#F6E5EB" // same for light and dark + ), + R.color.sharing_warning_border_color to ExpectedColor( + light = "#C16F81", + dark = "#C16F81" // same for light and dark + ), + R.color.share_color to ExpectedColor( + light = "#0D39DF", + dark = "#0D39DF" // same for light and dark + ), + R.color.shared_with_me_color to ExpectedColor( + light = "#0099ff", + dark = "#0099ff" // same for light and dark + ), + R.color.share_blue_color to ExpectedColor( + light = "#2238df", + dark = "#7d94f9" + ), + R.color.scan_doc_bg_color to ExpectedColor( + light = "#F2F2F2", + dark = "#121212" + ), + R.color.scan_text_color to ExpectedColor( + light = "#191919", + dark = "#F2F2F2" + ), + R.color.scan_edit_bottom_color to ExpectedColor( + light = "#F2F2F2", + dark = "#333333" + ), + R.color.scan_count_bg_color to ExpectedColor( + light = "#B2B2B2", + dark = "#333333" + ), + R.color.neptune to ExpectedColor( + light = "#77b6bb", + dark = "#77b6bb" // same for light and dark + ), + R.color.neptune_50 to ExpectedColor( + light = "#5077b6bb", + dark = "#5077b6bb" // same for light and dark + ), + ) + + @Test + fun validateLightModeColors() { + validateColors(Configuration.UI_MODE_NIGHT_NO) { Color.parseColor(it.light) } + } + + @Test + fun validateDarkModeColors() { + validateColors(Configuration.UI_MODE_NIGHT_YES) { Color.parseColor(it.dark) } + } + + private fun validateColors( + nightMode: Int, + expectedSelector: (ExpectedColor) -> Int + ) { + val appContext = ApplicationProvider.getApplicationContext() + val conf = Configuration(appContext.resources.configuration) + conf.uiMode = (conf.uiMode and Configuration.UI_MODE_NIGHT_MASK.inv()) or nightMode + val ctx = appContext.createConfigurationContext(conf) + + expectedColorMap.forEach { (colorRes, expectedColor) -> + val expected = expectedSelector(expectedColor) + val actual = ContextCompat.getColor(ctx, colorRes) + assertEquals( + "Color mismatch: ${ctx.resources.getResourceName(colorRes)}", + expected, actual + ) + } + } + + data class ExpectedColor(val light: String, val dark: String) +} diff --git a/app/src/androidTest/java/com/nmc/android/GeneralThemingResourceTest.kt b/app/src/androidTest/java/com/nmc/android/GeneralThemingResourceTest.kt new file mode 100644 index 000000000000..61440cb5f62c --- /dev/null +++ b/app/src/androidTest/java/com/nmc/android/GeneralThemingResourceTest.kt @@ -0,0 +1,275 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2025 TSI-mc + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nmc.android + +import android.content.Context +import android.content.res.Configuration +import android.util.DisplayMetrics +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.owncloud.android.R +import junit.framework.TestCase.assertEquals +import junit.framework.TestCase.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import java.util.Locale + +/** + * Test class to verify the strings, dimens and bool customized in this branch PR for NMC + */ +@RunWith(AndroidJUnit4::class) +class GeneralThemingResourceTest { + + private val baseContext = ApplicationProvider.getApplicationContext() + + private val localizedStringMap = mapOf( + R.string.camera_permission_rationale to ExpectedLocalizedString( + translations = mapOf( + Locale.ENGLISH to "Please navigate to App info in settings and give permission manually.", + Locale.GERMAN to "Bitte geben Sie unter Apps & Benachrichtigungen in den Einstellungen manuell die Erlaubnis." + ) + ), + ) + + @Test + fun verifyLocalizedStrings() { + localizedStringMap.forEach { (stringRes, expected) -> + expected.translations.forEach { (locale, expectedText) -> + + val config = Configuration(baseContext.resources.configuration) + config.setLocale(locale) + + val localizedContext = baseContext.createConfigurationContext(config) + val actualText = localizedContext.getString(stringRes) + + assertEquals( + "Mismatch for ${baseContext.resources.getResourceEntryName(stringRes)} in $locale", + expectedText, + actualText + ) + } + } + } + + data class ExpectedLocalizedString(val translations: Map) + + private val expectedDimenMap = mapOf( + R.dimen.grid_recyclerview_padding to ExpectedDimen( + default = 4f, + unit = DimenUnit.DP + ), + R.dimen.list_item_icons_size to ExpectedDimen( + default = 16f, + unit = DimenUnit.DP + ), + R.dimen.grid_item_icons_size to ExpectedDimen( + default = 24f, + unit = DimenUnit.DP + ), + R.dimen.grid_item_shared_icon_layout_top_margin to ExpectedDimen( + default = 24f, + unit = DimenUnit.DP + ), + R.dimen.media_grid_item_rv_spacing to ExpectedDimen( + default = 6f, + unit = DimenUnit.DP + ), + R.dimen.txt_size_18sp to ExpectedDimen( + default = 18f, + unit = DimenUnit.SP + ), + R.dimen.txt_size_15sp to ExpectedDimen( + default = 15f, + unit = DimenUnit.SP + ), + R.dimen.crop_corner_size to ExpectedDimen( + default = 15f, + unit = DimenUnit.DP + ), + R.dimen.edit_scan_bottom_bar_height to ExpectedDimen( + default = 56f, + unit = DimenUnit.DP + ), + R.dimen.standard_folders_grid_item_size to ExpectedDimen( + default = 86f, + unit = DimenUnit.DP + ), + R.dimen.standard_files_grid_item_size to ExpectedDimen( + default = 80f, + unit = DimenUnit.DP + ), + R.dimen.txt_size_11sp to ExpectedDimen( + default = 11f, + unit = DimenUnit.SP + ), + R.dimen.share_row_icon_size to ExpectedDimen( + default = 30f, + unit = DimenUnit.DP + ), + R.dimen.create_link_button_height to ExpectedDimen( + default = 55f, + unit = DimenUnit.DP + ), + R.dimen.note_et_height to ExpectedDimen( + default = 258f, + unit = DimenUnit.DP + ), + R.dimen.txt_size_17sp to ExpectedDimen( + default = 17f, + unit = DimenUnit.SP + ), + R.dimen.share_exp_date_divider_margin to ExpectedDimen( + default = 20f, + unit = DimenUnit.DP + ), + R.dimen.privacy_btn_width to ExpectedDimen( + default = 160f, + unit = DimenUnit.DP + ), + R.dimen.privacy_icon_size to ExpectedDimen( + default = 50f, + unit = DimenUnit.DP + ), + R.dimen.login_btn_width to ExpectedDimen( + default = 150f, + unit = DimenUnit.DP + ), + R.dimen.login_btn_height to ExpectedDimen( + default = 55f, + unit = DimenUnit.DP + ), + R.dimen.login_btn_bottom_margin to ExpectedDimen( + default = 48f, + unit = DimenUnit.DP + ), + R.dimen.login_btn_bottom_margin_land to ExpectedDimen( + default = 48f, + unit = DimenUnit.DP + ), + R.dimen.login_btn_bottom_margin_small_screen to ExpectedDimen( + default = 24f, + unit = DimenUnit.DP + ), + R.dimen.shared_with_me_icon_size to ExpectedDimen( + default = 26f, + unit = DimenUnit.DP + ), + R.dimen.txt_size_20sp to ExpectedDimen( + default = 20f, + unit = DimenUnit.SP + ), + R.dimen.notification_row_item_height to ExpectedDimen( + default = 145f, + unit = DimenUnit.DP + ), + R.dimen.button_stroke_width to ExpectedDimen( + default = 1f, + unit = DimenUnit.DP + ), + R.dimen.txt_size_13sp to ExpectedDimen( + default = 13f, + unit = DimenUnit.SP + ), + R.dimen.file_icon_rounded_corner_radius_for_grid_mode to ExpectedDimen( + default = 4f, + unit = DimenUnit.DP, + alt = 16f + ), + R.dimen.file_icon_rounded_corner_radius to ExpectedDimen( + default = 8f, + unit = DimenUnit.DP, + alt = 32f + ), + R.dimen.grid_item_text_size to ExpectedDimen( + default = 14f, + unit = DimenUnit.SP + ), + R.dimen.grid_item_local_file_indicator_layout_width to ExpectedDimen( + default = 24f, + unit = DimenUnit.DP + ), + R.dimen.grid_item_local_file_indicator_layout_height to ExpectedDimen( + default = 24f, + unit = DimenUnit.DP + ), + R.dimen.list_item_local_file_indicator_layout_width to ExpectedDimen( + default = 24f, + unit = DimenUnit.DP + ), + R.dimen.list_item_local_file_indicator_layout_height to ExpectedDimen( + default = 24f, + unit = DimenUnit.DP + ), + ) + + @Test + fun validateDefaultDimens() { + validateDimens( + configModifier = { it }, // no change → default values + ) { it.default to it.unit } + } + + @Test + fun validate_sw600dp_Dimens() { + validateDimens(configModifier = { config -> + config.smallestScreenWidthDp = 600 + config + }) { it.alt to it.unit } + } + + private fun validateDimens( + configModifier: (Configuration) -> Configuration, + selector: (ExpectedDimen) -> Pair + ) { + val baseConfig = Configuration(baseContext.resources.configuration) + val testConfig = configModifier(baseConfig) + val testContext = baseContext.createConfigurationContext(testConfig) + val dm = testContext.resources.displayMetrics + val config = testContext.resources.configuration + expectedDimenMap.forEach { (resId, entry) -> + val (value, unit) = selector(entry) + val actualPx = testContext.resources.getDimension(resId) + value?.let { + val expectedPx = convertToPx(value, unit, dm, config) + assertEquals( + "Mismatch for ${testContext.resources.getResourceEntryName(resId)} ($unit)", + expectedPx, + actualPx, + 0.01f + ) + } + } + } + + private fun convertToPx( + value: Float, + unit: DimenUnit, + dm: DisplayMetrics, + config: Configuration + ): Float { + return when (unit) { + DimenUnit.DP -> value * dm.density + DimenUnit.SP -> value * dm.density * config.fontScale + DimenUnit.PX -> value + } + } + + data class ExpectedDimen( + val default: Float, + val alt: Float? = null, + val unit: DimenUnit, + ) + + enum class DimenUnit { DP, SP, PX } + + @Test + fun assertShowCalendarBackupBooleanFalse() { + val actualValue = baseContext.resources.getBoolean(R.bool.show_calendar_backup) + assertTrue(!actualValue) + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1f1c5a60abbe..d31328232256 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -284,6 +284,7 @@ android:exported="false" /> @@ -314,6 +315,7 @@ android:exported="false" /> @@ -436,6 +438,7 @@ fileThumbnailGenerator.setOfflineOperationThumbnail(ocFile, view) - ocFile.isFolder -> folderThumbnailGenerator.setFolderThumbnail(ocFile, view, arguments.shimmer) + ocFile.isFolder -> { + // NMC Customization + fileThumbnailGenerator.updateThumbnailViewSize( + view, + arguments.isGrid, + arguments.isMediaGallery, + R.dimen.standard_folders_grid_item_size + ) + // reset the padding as this will change for files and we don't this for folders + view.setPadding(0, 0, 0, 0) + + folderThumbnailGenerator.setFolderThumbnail(ocFile, view, arguments.shimmer) + } + else -> fileThumbnailGenerator.setThumbnail(ocFile, view, arguments) } } diff --git a/app/src/main/java/com/nmc/android/ui/utils/Log_NMC.kt b/app/src/main/java/com/nmc/android/ui/utils/Log_NMC.kt new file mode 100644 index 000000000000..e111bbd395a7 --- /dev/null +++ b/app/src/main/java/com/nmc/android/ui/utils/Log_NMC.kt @@ -0,0 +1,42 @@ +package com.nmc.android.ui.utils + +import com.owncloud.android.BuildConfig +import com.owncloud.android.lib.common.utils.Log_OC + +/** + * NMC log interpreter class + * this class will be used whenever we have to reduce the logs writing + * this will avoid printing logs in release builds + * todo: can be extended later for more functions + */ +object Log_NMC { + @JvmStatic + fun v(tag: String?, msg: String?) { + if (BuildConfig.DEBUG) Log_OC.v(tag, msg) + } + + @JvmStatic + fun d(tag: String?, msg: String?) { + if (BuildConfig.DEBUG) Log_OC.d(tag, msg) + } + + @JvmStatic + fun d(tag: String, msg: String, e: Exception) { + if (BuildConfig.DEBUG) Log_OC.d(tag, msg, e) + } + + @JvmStatic + fun i(tag: String?, msg: String?) { + if (BuildConfig.DEBUG) Log_OC.i(tag, msg) + } + + @JvmStatic + fun e(tag: String?, msg: String?) { + if (BuildConfig.DEBUG) Log_OC.e(tag, msg) + } + + @JvmStatic + fun w(tag: String?, msg: String?) { + if (BuildConfig.DEBUG) Log_OC.w(tag, msg) + } +} diff --git a/app/src/main/java/com/owncloud/android/MainApp.java b/app/src/main/java/com/owncloud/android/MainApp.java index 0454dc11a200..8faf90075566 100644 --- a/app/src/main/java/com/owncloud/android/MainApp.java +++ b/app/src/main/java/com/owncloud/android/MainApp.java @@ -1005,11 +1005,8 @@ public AndroidInjector androidInjector() { } public static void setAppTheme(DarkMode mode) { - switch (mode) { - case LIGHT -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); - case DARK -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); - case SYSTEM -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); - } + // NMC Customization -> Always follow system theme + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); } @Override diff --git a/app/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java b/app/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java index ec0cdc6f10f6..fafac24eda01 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java @@ -32,6 +32,7 @@ import com.nextcloud.utils.extensions.FileExtensionsKt; import com.nextcloud.utils.thumbnail.VideoOverlayGenerator; import com.nextcloud.utils.view.ScreenMetrics; +import com.nmc.android.ui.utils.Log_NMC; import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.lib.common.OwnCloudAccount; @@ -118,7 +119,7 @@ public static void initDiskCacheAsync() { } String cachePath = cacheDir.getPath() + File.separator + CACHE_FOLDER; - Log_OC.d(TAG, "thumbnail cache dir: " + cachePath); + Log_NMC.d(TAG, "thumbnail cache dir: " + cachePath); File diskCacheDir = new File(cachePath); // migrate from external cache to internal cache @@ -135,7 +136,7 @@ public static void initDiskCacheAsync() { mThumbnailCache = new DiskLruImageCache(diskCacheDir, DISK_CACHE_SIZE, mCompressFormat, mCompressQuality); } catch (Exception e) { - Log_OC.d(TAG, "Disk cache init failed", e); + Log_NMC.d(TAG, "Disk cache init failed", e); mThumbnailCache = null; } } @@ -460,13 +461,13 @@ private Bitmap doThumbnailFromOCFileInBackground() { if (!updateEnforced) { thumbnail = getBitmapFromDiskCache(imageKey); if (thumbnail != null) { - Log_OC.d(TAG, "Thumbnail found in disk cache for file: " + file.getFileName()); + Log_NMC.d(TAG, "Thumbnail found in disk cache for file: " + file.getFileName()); return thumbnail; } else { - Log_OC.d(TAG, "Thumbnail not found in cache for file: " + file.getFileName()); + Log_NMC.d(TAG, "Thumbnail not found in cache for file: " + file.getFileName()); } } else { - Log_OC.d(TAG, "Thumbnail update enforced for file: " + file.getFileName()); + Log_NMC.d(TAG, "Thumbnail update enforced for file: " + file.getFileName()); thumbnail = null; } @@ -476,7 +477,7 @@ private Bitmap doThumbnailFromOCFileInBackground() { // Generate thumbnail from local file if available if (file instanceof OCFile ocFile && ocFile.isDown()) { - Log_OC.d(TAG, "Generating thumbnail from local file: " + ocFile.getFileName()); + Log_NMC.d(TAG, "Generating thumbnail from local file: " + ocFile.getFileName()); Bitmap bitmap; if (MimeTypeUtil.isVideo(ocFile)) { @@ -508,9 +509,9 @@ private Bitmap doThumbnailFromOCFileInBackground() { if (resizedImage != null) { thumbnail = ThumbnailUtils.extractThumbnail(resizedImage, pxW, pxH, ThumbnailUtils.OPTIONS_RECYCLE_INPUT); - Log_OC.d(TAG, "Thumbnail generated from resized image cache for file: " + file.getFileName()); + Log_NMC.d(TAG, "Thumbnail generated from resized image cache for file: " + file.getFileName()); } else { - Log_OC.d(TAG, "No resized image cache available for file: " + file.getFileName()); + Log_NMC.d(TAG, "No resized image cache available for file: " + file.getFileName()); } } @@ -522,7 +523,7 @@ private Bitmap doThumbnailFromOCFileInBackground() { // Download thumbnail from server if still null if (thumbnail == null && mClient != null && serverHasPreview) { - Log_OC.d(TAG, "Attempting to download thumbnail from server for file: " + file.getFileName()); + Log_NMC.d(TAG, "Attempting to download thumbnail from server for file: " + file.getFileName()); GetMethod getMethod = null; try { @@ -536,7 +537,7 @@ private Bitmap doThumbnailFromOCFileInBackground() { + file.getLocalId() + "&x=" + pxW + "&y=" + pxH; } - Log_OC.d(TAG, "Downloading thumbnail URI: " + uri); + Log_NMC.d(TAG, "Downloading thumbnail URI: " + uri); getMethod = new GetMethod(uri); getMethod.setRequestHeader("Cookie", "nc_sameSiteCookielax=true;nc_sameSiteCookiestrict=true"); @@ -551,9 +552,9 @@ private Bitmap doThumbnailFromOCFileInBackground() { Bitmap bitmap = BitmapFactory.decodeStream(inputStream); if (bitmap != null) { thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH, ThumbnailUtils.OPTIONS_RECYCLE_INPUT); - Log_OC.d(TAG, "Thumbnail downloaded and extracted for file: " + file.getFileName()); + Log_NMC.d(TAG, "Thumbnail downloaded and extracted for file: " + file.getFileName()); } else { - Log_OC.w(TAG, "Downloaded thumbnail bitmap is null for file: " + file.getFileName()); + Log_NMC.w(TAG, "Downloaded thumbnail bitmap is null for file: " + file.getFileName()); } } } else { @@ -563,7 +564,7 @@ private Bitmap doThumbnailFromOCFileInBackground() { if (thumbnail != null && PNG_MIMETYPE.equalsIgnoreCase(file.getMimeType())) { thumbnail = BitmapUtils.centerCropOnPngBackground(thumbnail, pxW, pxH); - Log_OC.d(TAG, "Handled PNG thumbnail for downloaded file: " + file.getFileName()); + Log_NMC.d(TAG, "Handled PNG thumbnail for downloaded file: " + file.getFileName()); } } catch (Exception e) { Log_OC.e(TAG, "Exception downloading thumbnail for file: " + file.getFileName(), e); @@ -576,10 +577,10 @@ private Bitmap doThumbnailFromOCFileInBackground() { // Add to disk cache if obtained if (thumbnail != null) { - Log_OC.d(TAG, "Adding final thumbnail to cache for file: " + file.getFileName()); + Log_NMC.d(TAG, "Adding final thumbnail to cache for file: " + file.getFileName()); addBitmapToCache(imageKey, thumbnail); } else { - Log_OC.w(TAG, "Failed to obtain thumbnail for file: " + file.getFileName()); + Log_NMC.w(TAG, "Failed to obtain thumbnail for file: " + file.getFileName()); } return thumbnail; @@ -713,7 +714,7 @@ public static void generateThumbnailFromOCFile(OCFile file, User user, Context c String uri = client.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" + pxW + "/" + pxH + Uri.encode(file.getRemotePath(), "/"); - Log_OC.d(TAG, "generate thumbnail: " + file.getFileName() + " URI: " + uri); + Log_NMC.d(TAG, "generate thumbnail: " + file.getFileName() + " URI: " + uri); getMethod = new GetMethod(uri); getMethod.setRequestHeader("Cookie", "nc_sameSiteCookielax=true;nc_sameSiteCookiestrict=true"); @@ -736,7 +737,7 @@ public static void generateThumbnailFromOCFile(OCFile file, User user, Context c thumbnail = BitmapUtils.centerCropOnPngBackground(thumbnail, pxW, pxH); } - Log_OC.d(TAG, "add thumbnail to cache: " + file.getFileName()); + Log_NMC.d(TAG, "add thumbnail to cache: " + file.getFileName()); addBitmapToCache(imageKey, thumbnail); } } catch (Exception e) { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index ff83034b36db..1c559195ed36 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -665,6 +665,9 @@ class FileDisplayActivity : PermissionUtil.PERMISSIONS_CAMERA -> if (grantResults.isPermissionGranted()) { withOCFileListFragment { it.directCameraUpload() } + } else if (!shouldShowRequestPermissionRationale(permissions[0])) { + // NMC: user CHECKED "never ask again" + SnackbarUtil.show(this, R.string.camera_permission_rationale) } else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.kt index 8f18d5af87a6..3892667c4d4d 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/PassCodeActivity.kt @@ -21,7 +21,6 @@ import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.google.android.material.snackbar.Snackbar -import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.client.di.Injectable import com.nextcloud.client.preferences.AppPreferences import com.nextcloud.utils.extensions.setVisibleIf @@ -89,7 +88,6 @@ class PassCodeActivity : setContentView(binding.root) PassCodeManager.setSecureFlag(this, true) - applyTint() setupPasscodeEditTexts() setSoftInputMode() setupUI(savedInstanceState) @@ -110,23 +108,12 @@ class PassCodeActivity : ) } - private fun applyTint() { - viewThemeUtils.platform.colorViewBackground(binding.cardViewContent, ColorRole.SURFACE_VARIANT) - viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(binding.cancel) - } - private fun setupPasscodeEditTexts() { passCodeEditTexts[0] = binding.txt0 passCodeEditTexts[1] = binding.txt1 passCodeEditTexts[2] = binding.txt2 passCodeEditTexts[3] = binding.txt3 - passCodeEditTexts.forEach { - it?.let { editText -> - viewThemeUtils.platform.colorEditText(editText) - } - } - passCodeEditTexts[0]?.requestFocus() binding.cardViewContent.setOnClickListener { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ShareActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/ShareActivity.kt index a0df0673cf4c..c65eb9b8aab8 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ShareActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/ShareActivity.kt @@ -24,6 +24,7 @@ import com.owncloud.android.databinding.ShareActivityBinding import com.owncloud.android.datamodel.OCFile import com.owncloud.android.datamodel.SyncedFolderObserver import com.owncloud.android.datamodel.SyncedFolderProvider +import com.owncloud.android.datamodel.ThumbnailsCacheManager.ThumbnailGenerationTask import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt b/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt index 3b3406503203..e574817d447d 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt @@ -93,7 +93,8 @@ class GalleryAdapter( transferServiceGetter, showMetadata = false, showShareAvatar = false, - viewThemeUtils + viewThemeUtils, + true ) } diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/GalleryRowHolder.kt b/app/src/main/java/com/owncloud/android/ui/adapter/GalleryRowHolder.kt index 0f482a3364d5..e826c2954b58 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/GalleryRowHolder.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/GalleryRowHolder.kt @@ -40,15 +40,14 @@ class GalleryRowHolder( private val cells = mutableListOf() private val selectedOutline by lazy { - val resources = context.resources - val radiusDp = resources.getDimension(R.dimen.activity_icon_radius) / resources.displayMetrics.density - createRoundedOutline(context, radiusDp) + // NMC Customization: no need for rounding + // we want a normal view without any corners + createRoundedOutline(context, 0f) } private val checkedDrawable by lazy { - ContextCompat.getDrawable(context, R.drawable.ic_checkbox_marked)?.also { - viewThemeUtils.platform.tintDrawable(context, it, ColorRole.PRIMARY) - } + // NMC Customization: no need to tint the color + ContextCompat.getDrawable(context, R.drawable.ic_checkbox_marked) } private val uncheckedDrawable by lazy { @@ -83,9 +82,7 @@ class GalleryRowHolder( } private fun createCell(): GalleryCellBinding = - GalleryCellBinding.inflate(LayoutInflater.from(context), binding.rowLayout, false).apply { - viewThemeUtils.platform.colorViewBackground(selectionBackground, ColorRole.SURFACE_CONTAINER_HIGHEST) - } + GalleryCellBinding.inflate(LayoutInflater.from(context), binding.rowLayout, false) private fun bindCell(cell: GalleryCellBinding, file: OCFile, size: GalleryCellSize) = with(cell) { root.applySize(size) @@ -124,7 +121,6 @@ class GalleryRowHolder( cell.thumbnail.applySelectedOutline(isChecked) cell.unsupported.root.applySelectedOutline(isChecked) - cell.root.isSelected = isChecked if (!isSameFileRebound) { cell.root.jumpDrawablesToCurrentState() } diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/TrashbinListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/TrashbinListAdapter.java index 601ba3a207b2..399a7d81b208 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/TrashbinListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/TrashbinListAdapter.java @@ -17,7 +17,6 @@ import android.view.ViewGroup; import android.widget.ImageView; -import com.nextcloud.android.common.ui.theme.utils.ColorRole; import com.nextcloud.client.account.User; import com.nextcloud.client.preferences.AppPreferences; import com.nextcloud.utils.AppConstants; @@ -158,8 +157,8 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int positi // checkbox if (isCheckedFile(file)) { - trashbinFileViewHolder.binding.customCheckbox.setImageDrawable( - viewThemeUtils.platform.tintDrawable(context, R.drawable.ic_checkbox_marked, ColorRole.PRIMARY)); + // NMC Customization + trashbinFileViewHolder.binding.customCheckbox.setImageResource(R.drawable.ic_checkbox_marked); } else { trashbinFileViewHolder.binding.customCheckbox.setImageResource(R.drawable.ic_checkbox_blank_outline); } @@ -177,17 +176,9 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int positi float cornerRadius = context.getResources().getDimension(R.dimen.selected_grid_container_radius); - boolean isDarkModeActive = (syncedFolderProvider.preferences.isDarkModeEnabled()); - int selectedItemBackgroundColorId; - if (isDarkModeActive) { - selectedItemBackgroundColorId = R.color.action_mode_background; - } else { - selectedItemBackgroundColorId = R.color.selected_item_background; - } - int itemLayoutBackgroundColorId; if (isCheckedFile(file)) { - itemLayoutBackgroundColorId = selectedItemBackgroundColorId; + itemLayoutBackgroundColorId = R.color.selected_item_background; } else { itemLayoutBackgroundColorId = R.color.bg_default; } diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/OCFileListAdapter.kt b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/OCFileListAdapter.kt index 4a1db86037aa..9b7915fdb6c6 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/OCFileListAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/OCFileListAdapter.kt @@ -141,6 +141,7 @@ class OCFileListAdapter( showMetadata = true, showShareAvatar = true, viewThemeUtils, + false, syncedFolderProvider ) @@ -571,6 +572,7 @@ class OCFileListAdapter( fun setGridView(bool: Boolean) { gridView = bool + ocFileListDelegate.setGridView(bool) } fun setShowMetadata(bool: Boolean) { diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/footer/OCFileListFooterBinder.kt b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/footer/OCFileListFooterBinder.kt index 97ba1787e172..5b6ac272e55c 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/footer/OCFileListFooterBinder.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/footer/OCFileListFooterBinder.kt @@ -25,7 +25,6 @@ internal class OCFileListFooterBinder( // region Public methods fun bind(holder: OCFileListFooterViewHolder, files: List) { holder.footerText.text = fileCountSummary(files) - viewThemeUtils.platform.colorCircularProgressBar(holder.loadingProgressBar, ColorRole.ON_SURFACE_VARIANT) holder.loadingProgressBar.setVisibleIf(fragmentInterface.isLoading) } // endregion diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListDelegate.kt b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListDelegate.kt index 5d603aba1461..b5a30abc8930 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListDelegate.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListDelegate.kt @@ -63,11 +63,12 @@ class OCFileListDelegate( private val user: User, private val storageManager: FileDataStorageManager, private val hideItemOptions: Boolean, - private val gridView: Boolean, + private var gridView: Boolean, private val transferServiceGetter: ComponentsGetter, private val showMetadata: Boolean, private var showShareAvatar: Boolean, private var viewThemeUtils: ViewThemeUtils, + private val isMediaGallery: Boolean, private val syncFolderProvider: SyncedFolderProvider? = null ) { private val checkedFiles: MutableSet = HashSet() @@ -228,7 +229,10 @@ class OCFileListDelegate( thumbnailGenerator.setThumbnail( file, viewHolder.thumbnail, - ThumbnailArguments(isGrid = gridView, hideVideoOverlay = false, viewHolder.shimmerThumbnail) + ThumbnailArguments( + isGrid = gridView, hideVideoOverlay = false, viewHolder.shimmerThumbnail, + isMediaGallery = isMediaGallery + ) ) // item layout + click listeners @@ -249,22 +253,15 @@ class OCFileListDelegate( // shares val shouldHideShare = ( - ( + gridView || // NMC: don't show share icon in grid mode hideItemOptions || - ( - !file.isFolder && - file.isEncrypted - ) || - ( - file.isEncrypted && - !EncryptionUtils.supportsSecureFiledrop(file, user) - ) || - (searchType == SearchType.FAVORITE_SEARCH) || - ( - file.isFolder && - (currentDirectory?.isEncrypted ?: false) - ) - ) + !file.isFolder && + file.isEncrypted || + file.isEncrypted && + !EncryptionUtils.supportsSecureFiledrop(file, user) || + searchType == SearchType.FAVORITE_SEARCH || + file.isFolder && + currentDirectory?.isEncrypted ?: false ) // sharing an encrypted subfolder is not possible if (shouldHideShare) { viewHolder.shared.visibility = View.GONE @@ -317,15 +314,8 @@ class OCFileListDelegate( private fun setItemLayoutBackgroundColor(file: OCFile, gridViewHolder: ListViewHolder) { val cornerRadius = context.resources.getDimension(R.dimen.selected_grid_container_radius) - val isDarkModeActive = (syncFolderProvider?.preferences?.isDarkModeEnabled == true) - val selectedItemBackgroundColorId: Int = if (isDarkModeActive) { - R.color.action_mode_background - } else { - R.color.selected_item_background - } - val itemLayoutBackgroundColorId: Int = if (file.fileId == highlightedItem?.fileId || isCheckedFile(file)) { - selectedItemBackgroundColorId + R.color.selected_item_background } else { R.color.bg_default } @@ -338,9 +328,8 @@ class OCFileListDelegate( private fun setCheckBoxImage(file: OCFile, gridViewHolder: ListViewHolder) { if (isCheckedFile(file)) { - gridViewHolder.checkbox.setImageDrawable( - viewThemeUtils.platform.tintDrawable(context, R.drawable.ic_checkbox_marked, ColorRole.PRIMARY) - ) + // NMC Customization + gridViewHolder.checkbox.setImageResource(R.drawable.ic_checkbox_marked) } else { gridViewHolder.checkbox.setImageResource(R.drawable.ic_checkbox_blank_outline) } @@ -451,6 +440,10 @@ class OCFileListDelegate( Log_OC.d(TAG, "background jobs cancelled") } + fun setGridView(bool: Boolean){ + gridView = bool + } + companion object { private val TAG = OCFileListDelegate::class.java.simpleName } diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListGridItemViewHolder.kt b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListGridItemViewHolder.kt index 0dfbd55f9651..7b9a93a9ee54 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListGridItemViewHolder.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListGridItemViewHolder.kt @@ -71,8 +71,8 @@ class OCFileListGridItemViewHolder(var binding: GridItemBinding) : override val hasVisibleFeatureIndicators: Boolean get() = localFileIndicator.isVisible || gridLivePhotoIndicator?.isVisible == true || unreadComments.isVisible || shared.isVisible || binding.videoOverlay.isVisible || favorite.isVisible - override val fileFeaturesLayout: LinearLayout - get() = binding.fileFeaturesLayout + override val fileFeaturesLayout: LinearLayout? + get() = null override val more: ImageButton get() = if (binding.bidiFilenameContainer.isVisible) { binding.bidiMore diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListViewHolder.kt b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListViewHolder.kt index d96845cfd6c8..32b3e2f29503 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListViewHolder.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListViewHolder.kt @@ -58,8 +58,8 @@ internal class OCFileListViewHolder(var binding: GridItemBinding) : } else { binding.more } - override val fileFeaturesLayout: LinearLayout - get() = binding.fileFeaturesLayout + override val fileFeaturesLayout: LinearLayout? + get() = null override val gridLivePhotoIndicator: ImageView get() = binding.gridLivePhotoIndicator override val livePhotoIndicator: TextView? diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/localFileList/LocalFileListItemBinder.kt b/app/src/main/java/com/owncloud/android/ui/adapter/localFileList/LocalFileListItemBinder.kt index 170bc64e059e..f296fa0a4d45 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/localFileList/LocalFileListItemBinder.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/localFileList/LocalFileListItemBinder.kt @@ -49,9 +49,8 @@ internal class LocalFileListItemBinder( if (isCheckedFile(file)) { holder.itemLayout.setBackgroundColor(ContextCompat.getColor(activity, R.color.selected_item_background)) - holder.checkbox.setImageDrawable( - viewThemeUtils.platform.tintDrawable(activity, R.drawable.ic_checkbox_marked, ColorRole.PRIMARY) - ) + // NMC Customization + holder.checkbox.setImageResource(R.drawable.ic_checkbox_marked) } else { holder.itemLayout.setBackgroundColor(ContextCompat.getColor(activity, R.color.bg_default)) holder.checkbox.setImageResource(R.drawable.ic_checkbox_blank_outline) diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/uploadList/UploadListAdapter.kt b/app/src/main/java/com/owncloud/android/ui/adapter/uploadList/UploadListAdapter.kt index 6729649ebc70..5da153b28734 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/uploadList/UploadListAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/uploadList/UploadListAdapter.kt @@ -110,7 +110,8 @@ class UploadListAdapter( val title = activity.getString(group.titleRes) val headerText = activity.getString(R.string.uploads_view_group_header) holder.binding.uploadListTitle.text = String.format(headerText, title, group.items.size) - viewThemeUtils.platform.colorTextView(holder.binding.uploadListTitle) + // NMC Customization + holder.binding.uploadListTitle.setTextColor(activity.getResources().getColor(R.color.primary, null)) val toggleExpand = { toggleSectionExpanded(section) diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.kt b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.kt index 01f945d5f4bb..33be57ec7ecc 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.kt @@ -1486,6 +1486,16 @@ open class OCFileListFragment : } } + // NMC Customization + // for NMC we are using defaultToolbar instead searchToolbar for which we needed customization + private fun isRoot(): Boolean { + val activity = activity + if (activity is FileDisplayActivity) { + return activity.isRoot(activity.file) + } + return false + } + @Subscribe(threadMode = ThreadMode.BACKGROUND) fun onSearchEvent(event: SearchEvent) { startSearch(event) diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt b/app/src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt index e7f6eb021cb1..a50d6eaf020e 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt @@ -174,9 +174,10 @@ class UnifiedSearchFragment : super.onViewCreated(view, savedInstanceState) setupAdapter() - if (supportsOpeningCalendarContactsLocally()) { + // NMC-4633 disable permission check + /*if (supportsOpeningCalendarContactsLocally()) { checkPermissions() - } + }*/ } override fun onResume() { diff --git a/app/src/main/res/drawable/cursor_drawable.xml b/app/src/main/res/drawable/cursor_drawable.xml new file mode 100644 index 000000000000..dd35b659e8ae --- /dev/null +++ b/app/src/main/res/drawable/cursor_drawable.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/activity_edit_image.xml b/app/src/main/res/layout/activity_edit_image.xml index 097431adc99d..0d486f6e6178 100644 --- a/app/src/main/res/layout/activity_edit_image.xml +++ b/app/src/main/res/layout/activity_edit_image.xml @@ -14,15 +14,10 @@ android:background="@color/black" tools:ignore="Overdraw"> - + + + app:layout_constraintTop_toBottomOf="@+id/appbar" /> @@ -82,7 +81,7 @@ android:layout_height="wrap_content" android:text="@string/daily_backup" android:textColor="@color/text_color" - android:textSize="@dimen/two_line_primary_text_size" /> + android:textSize="14sp" /> diff --git a/app/src/main/res/layout/file_thumbnail.xml b/app/src/main/res/layout/file_thumbnail.xml index 6f318d47e9b3..b7a842e4d78d 100644 --- a/app/src/main/res/layout/file_thumbnail.xml +++ b/app/src/main/res/layout/file_thumbnail.xml @@ -24,7 +24,7 @@ android:layout_width="@dimen/file_icon_size" android:layout_height="@dimen/file_icon_size" android:contentDescription="@null" - android:src="@drawable/folder" /> + tools:src="@drawable/folder" /> + android:layout_height="0.5dp" + android:background="@color/divider_color" /> diff --git a/app/src/main/res/layout/gallery_cell.xml b/app/src/main/res/layout/gallery_cell.xml index 200f64c06ed1..3c388b8957a1 100644 --- a/app/src/main/res/layout/gallery_cell.xml +++ b/app/src/main/res/layout/gallery_cell.xml @@ -37,9 +37,9 @@ android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="top|start" + android:layout_gravity="top|end" android:background="@drawable/gallery_selection_checkbox_background" - android:layout_marginStart="@dimen/standard_half_margin" + android:layout_marginEnd="@dimen/standard_half_margin" android:layout_marginTop="@dimen/standard_half_margin" android:contentDescription="@null" android:visibility="gone" /> diff --git a/app/src/main/res/layout/grid_item.xml b/app/src/main/res/layout/grid_item.xml index fe05edce1f7e..f2b58d6e0cac 100644 --- a/app/src/main/res/layout/grid_item.xml +++ b/app/src/main/res/layout/grid_item.xml @@ -16,23 +16,32 @@ android:layout_height="wrap_content" android:layout_margin="@dimen/grid_container_margin"> - + + + + + - - - - + app:layout_constraintVertical_bias="0.85" + tools:visibility="visible"> @@ -118,22 +123,34 @@ tools:ignore="TouchTargetSizeCheck" tools:visibility="visible" /> - - + + + + + app:layout_constraintTop_toBottomOf="@+id/thumbnail" + tools:visibility="visible"> + android:layout_marginStart="@dimen/iconized_single_line_item_icon_size" + android:layout_weight="1" + android:gravity="center"> @@ -195,6 +214,7 @@ android:contentDescription="@string/overflow_menu" android:translationZ="2dp" app:srcCompat="@drawable/ic_dots_vertical" + app:tint="@color/list_icon_color" tools:ignore="TouchTargetSizeCheck" /> @@ -209,6 +229,7 @@ android:gravity="center" android:singleLine="true" android:text="@string/placeholder_filename" + android:textColor="@color/text_color" android:textSize="@dimen/grid_item_text_size" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" @@ -232,6 +253,7 @@ app:layout_constraintStart_toEndOf="@id/Filename" app:layout_constraintTop_toBottomOf="@id/thumbnail" app:srcCompat="@drawable/ic_dots_vertical" + app:tint="@color/list_icon_color" tools:ignore="TouchTargetSizeCheck" tools:visibility="visible" /> diff --git a/app/src/main/res/layout/list_item.xml b/app/src/main/res/layout/list_item.xml index 46847db9f216..d7856630d6ba 100644 --- a/app/src/main/res/layout/list_item.xml +++ b/app/src/main/res/layout/list_item.xml @@ -15,17 +15,17 @@ xmlns:tools="http://schemas.android.com/tools" android:id="@+id/ListItemLayout" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="@dimen/standard_list_item_size" android:baselineAligned="false" android:descendantFocusability="blocksDescendants" - android:minHeight="@dimen/min_list_item_size" android:orientation="horizontal"> + android:layout_marginEnd="@dimen/standard_quarter_padding" + android:layout_marginBottom="@dimen/standard_padding"> + android:paddingTop="@dimen/standard_padding"> + tools:visibility="visible" + app:tint="@color/list_icon_color" /> @@ -308,15 +305,15 @@ + android:src="@drawable/ic_dots_vertical" + app:tint="@color/list_icon_color" /> diff --git a/app/src/main/res/layout/receive_external_files.xml b/app/src/main/res/layout/receive_external_files.xml index 589cae7888da..9acf6cc73ed8 100644 --- a/app/src/main/res/layout/receive_external_files.xml +++ b/app/src/main/res/layout/receive_external_files.xml @@ -12,6 +12,7 @@ android:id="@+id/upload_files_layout" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/bg_default" android:orientation="vertical"> @@ -219,6 +220,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="marquee" + android:maxLines="2" android:text="@string/instant_upload_existing" android:textAppearance="?attr/textAppearanceListItem" /> diff --git a/app/src/main/res/layout/trashbin_item.xml b/app/src/main/res/layout/trashbin_item.xml index 4d248ffd8fb5..e3c2ede36211 100644 --- a/app/src/main/res/layout/trashbin_item.xml +++ b/app/src/main/res/layout/trashbin_item.xml @@ -6,6 +6,7 @@ ~ SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only --> + android:src="@drawable/ic_history" + app:tint="@color/list_icon_color"/> + android:src="@drawable/ic_dots_vertical" + app:tint="@color/list_icon_color"/> diff --git a/app/src/main/res/layout/upload_files_layout.xml b/app/src/main/res/layout/upload_files_layout.xml index 38d17a7566a8..e9c950469995 100644 --- a/app/src/main/res/layout/upload_files_layout.xml +++ b/app/src/main/res/layout/upload_files_layout.xml @@ -26,17 +26,10 @@ android:layout_height="0dp" android:layout_weight="1" /> - - - - - + android:layout_height="0.5dp" + android:background="@color/divider_color" /> + android:src="@drawable/ic_expand_less" + app:tint="@color/list_icon_color"/> + android:src="@drawable/nav_trashbin" + app:tint="@color/list_icon_color" /> diff --git a/app/src/main/res/layout/upload_list_item.xml b/app/src/main/res/layout/upload_list_item.xml index db6acf802b0d..e75cb156ad1a 100755 --- a/app/src/main/res/layout/upload_list_item.xml +++ b/app/src/main/res/layout/upload_list_item.xml @@ -9,6 +9,7 @@ --> + android:paddingEnd="@dimen/zero" + app:tint="@color/list_icon_color"/> diff --git a/app/src/main/res/menu/activity_upload_list.xml b/app/src/main/res/menu/activity_upload_list.xml index e118af71c115..8cd7e12efc2a 100644 --- a/app/src/main/res/menu/activity_upload_list.xml +++ b/app/src/main/res/menu/activity_upload_list.xml @@ -12,10 +12,12 @@ android:id="@+id/upload_list_actions" android:checkableBehavior="none"> + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1374fb3d4f05..108a320a8b11 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1284,6 +1284,7 @@ Herunterladen Video Überlagerungsicon Bitte warten … + Bitte geben Sie unter Apps & Benachrichtigungen in den Einstellungen manuell die Erlaubnis. Überprüfe gespeicherte Anmeldeinformationen Kopiere Datei von privatem Speicher Das Ändern der Erweiterung kann dazu führen, dass diese Datei in einer anderen Anwendung geöffnet wird diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 6979627fc58a..33fd91ef1e28 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -7,6 +7,7 @@ --> + @color/grey_30 #E3E3E3 #000000 #ff6F6F6F @@ -26,7 +27,7 @@ @color/appbar - #373535 + @color/grey_70 #222222 #DADADA @@ -36,7 +37,7 @@ @color/white - #1E1E1E + #121212 @android:color/white #2A2A2A diff --git a/app/src/main/res/values-night/nmc_colors.xml b/app/src/main/res/values-night/nmc_colors.xml new file mode 100644 index 000000000000..229d9361177d --- /dev/null +++ b/app/src/main/res/values-night/nmc_colors.xml @@ -0,0 +1,73 @@ + + + + + #FFFFFF + @color/grey_30 + @color/grey_30 + #CCCCCC + @color/grey_70 + @color/grey_80 + #2D2D2D + @color/grey_70 + @color/grey_70 + + + @color/grey_80 + @color/grey_0 + + + @color/grey_80 + @color/grey_0 + + + @color/grey_60 + @color/grey_0 + @color/grey_0 + @color/grey_30 + #FFFFFF + @color/grey_30 + @color/grey_80 + #FFFFFF + + + @color/grey_80 + @color/grey_30 + @color/grey_0 + + + @color/grey_80 + @color/grey_0 + @color/grey_80 + + + @color/grey_70 + @color/grey_60 + + + @color/grey_70 + @color/grey_70 + + + #FFFFFF + @color/grey_30 + @color/grey_0 + @color/grey_0 + @color/grey_0 + @color/grey_0 + @color/grey_60 + @color/grey_0 + #FFFFFF + #7d94f9 + + + #121212 + @color/grey_0 + @color/grey_80 + @color/grey_80 + \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 19b3ce692520..167139478049 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -23,5 +23,8 @@ @style/Nextcloud.Widget.PopupMenu @style/ThemeOverlay.App.BottomSheetDialog @style/App.ActionMode + + @style/AutoCompleteCursorColorStyle + @style/AutoCompleteCursorColorStyle diff --git a/app/src/main/res/values-sw600dp/dims.xml b/app/src/main/res/values-sw600dp/dims.xml index 7436d593a3c5..a32fc3e858d1 100644 --- a/app/src/main/res/values-sw600dp/dims.xml +++ b/app/src/main/res/values-sw600dp/dims.xml @@ -8,5 +8,7 @@ --> 6 + 32dp + 16dp 512dp diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 0bd3f44d07dc..3c092593d62c 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -10,11 +10,12 @@ ~ SPDX-License-Identifier: GPL-2.0-only AND (AGPL-3.0-or-later OR GPL-2.0-only) --> - @color/secondary_text_color + @color/grey_600 #000000 #ffffff #B3FFFFFF - #333333 + #191919 + #F5F5F5 #303034 #E9E8EB @color/secondary_text_color @@ -26,7 +27,7 @@ #DDDDDD #00000000 #33000000 - #666666 + @color/grey_30 #e53935 @@ -77,16 +78,16 @@ #40162233 - @color/fontAppbar - #ECECEC + @color/white + @color/grey_0 #757575 #616161 - #80000000 + #919191 @android:color/white - #666666 + #191919 #A5A5A5 #EFEFEF diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 000000000000..cc023ec9c6e1 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,32 @@ + + + 4dp + 16dp + 24dp + 24dp + 6dp + 18sp + 15sp + 15dp + 56dp + 86dp + 80dp + 11sp + 30dp + 55dp + 258dp + 17sp + 20dp + 160dp + 50dp + 150dp + 55dp + 48dp + 48dp + 24dp + 26dp + 20sp + 145dp + 1dp + 13sp + \ No newline at end of file diff --git a/app/src/main/res/values/dims.xml b/app/src/main/res/values/dims.xml index ac2ed15dcfef..ab0c2ad18e26 100644 --- a/app/src/main/res/values/dims.xml +++ b/app/src/main/res/values/dims.xml @@ -25,7 +25,7 @@ 100dp 128dp 4dp - 3dp + 4dp 512 28dp 24dp @@ -56,7 +56,7 @@ 10dp 2dp 22sp - 16dp + 2dp 4dp 18dp 6dp @@ -101,7 +101,7 @@ 12sp 12dp 240dp - 16sp + 14sp 12sp 20dp 60dp @@ -129,11 +129,13 @@ 40dp 72dp 72dp + 24dp + 24dp 22sp 14dp 14dp - 12dp - 12dp + 24dp + 24dp 72dp 72dp 26sp diff --git a/app/src/main/res/values/nmc_colors.xml b/app/src/main/res/values/nmc_colors.xml new file mode 100644 index 000000000000..3aa33ccdf362 --- /dev/null +++ b/app/src/main/res/values/nmc_colors.xml @@ -0,0 +1,98 @@ + + + + + #191919 + @color/primary + #191919 + #191919 + @color/grey_30 + @android:color/white + #FFFFFF + @color/grey_0 + #CCCCCC + #77c4ff + #B3FFFFFF + @color/grey_10 + + + #101010 + #F2F2F2 + #E5E5E5 + #B2B2B2 + #666666 + #4C4C4C + #333333 + + + @color/design_snackbar_background_color + @color/white + + + #FFFFFF + #191919 + + + @color/grey_0 + #191919 + @color/primary + #191919 + @color/primary + @color/grey_30 + @color/white + #191919 + + + #FFFFFF + #191919 + #191919 + + + #FFFFFF + #191919 + #FFFFFF + + + @color/primary + #F399C7 + #FFFFFF + @color/grey_30 + @color/grey_10 + @color/grey_0 + + + @color/primary + @color/grey_30 + @color/grey_30 + #CCCCCC + + + #191919 + @color/grey_30 + #191919 + #191919 + #191919 + #191919 + @color/grey_30 + #191919 + #000000 + #191919 + #F6E5EB + #C16F81 + #0D39DF + #0099ff + #2238df + + + @color/grey_0 + #191919 + @color/grey_0 + @color/grey_30 + #77b6bb + #5077b6bb + \ No newline at end of file diff --git a/app/src/main/res/values/setup.xml b/app/src/main/res/values/setup.xml index a758c6884e77..104403dc64ea 100644 --- a/app/src/main/res/values/setup.xml +++ b/app/src/main/res/values/setup.xml @@ -58,7 +58,7 @@ -1 /.Calendar-Backup - true + false true diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 02ad7b2f9b0c..e842413a3b9d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1361,6 +1361,7 @@ Link Name Delete Link Settings + Please navigate to App info in settings and give permission manually. Confirm Destination filename Suggest diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index b01edd987c4e..ade9110b0b11 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -32,6 +32,9 @@ @color/bg_default @style/Widget.App.TextInputLayout @dimen/dialogBorderRadius + + @style/AutoCompleteCursorColorStyle + @style/AutoCompleteCursorColorStyle + +