Quellcode durchsuchen

Merge pull request #10717 from nextcloud/feature/material3

🎨 Material 3️⃣
Álvaro Brey vor 2 Jahren
Ursprung
Commit
ac20b55d90
100 geänderte Dateien mit 250 neuen und 303 gelöschten Zeilen
  1. 10 8
      app/build.gradle
  2. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_empty.png
  3. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_error.png
  4. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_loading.png
  5. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_openDrawer.png
  6. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_showActivities.png
  7. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.AuthenticatorActivityIT_login.png
  8. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.CommunityActivityIT_open.png
  9. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_drawer.png
  10. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_open.png
  11. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_showMediaThenAllFiles.png
  12. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.FirstRunActivityIT_open.png
  13. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.SettingsActivityIT_open.png
  14. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.SettingsActivityIT_showMnemonic_Error.png
  15. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.SyncedFoldersActivityIT_open.png
  16. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.SyncedFoldersActivityIT_testSyncedFolderDialog.png
  17. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.UploadListActivityActivityIT_openDrawer.png
  18. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.etm.EtmActivityTest_accounts.png
  19. BIN
      app/screenshots/gplay/debug/com.nextcloud.client.etm.EtmActivityTest_overview.png
  20. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepBoth.png
  21. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepExisting.png
  22. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepNew.png
  23. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_screenshotTextFiles.png
  24. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ContactsPreferenceActivityIT_openContactsPreference.png
  25. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ContactsPreferenceActivityIT_openVCF.png
  26. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.FolderPickerActivityIT_open.png
  27. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_open.png
  28. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_userInfoDetail.png
  29. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.NotificationsActivityIT_empty.png
  30. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.NotificationsActivityIT_error.png
  31. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.NotificationsActivityIT_showNotifications.png
  32. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.PassCodeActivityIT_check.png
  33. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.PassCodeActivityIT_delete.png
  34. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.PassCodeActivityIT_request.png
  35. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ReceiveExternalFilesActivityIT_open.png
  36. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.UploadFilesActivityIT_localFolderPickerMode.png
  37. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.UploadFilesActivityIT_noneSelected.png
  38. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.activity.UserInfoActivityIT_fullUserInfoDetail.png
  39. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog.png
  40. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialogWithStatusDisabled.png
  41. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_away.png
  42. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_dnd.png
  43. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_fun.png
  44. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_offline.png
  45. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_online.png
  46. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testBottomSheet.png
  47. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testEnforcedPasswordDialog.png
  48. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testLoadingDialog.png
  49. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testNewFolderDialog.png
  50. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testOptionalPasswordDialog.png
  51. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testProfileBottomSheet.png
  52. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFileDialog.png
  53. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFilesDialog.png
  54. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFolderDialog.png
  55. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFoldersDialog.png
  56. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRenameFileDialog.png
  57. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialogDifferentTypes_Screenshot.png
  58. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialog_Screenshot.png
  59. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendShareDialogTest_showDialog.png
  60. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SetupEncryptionDialogFragmentIT_error.png
  61. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SetupEncryptionDialogFragmentIT_showMnemonic.png
  62. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.BackupListFragmentIT_showCalendarAndContactsList.png
  63. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.BackupListFragmentIT_showCalendarList.png
  64. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.BackupListFragmentIT_showContactList.png
  65. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.BackupListFragmentIT_showLoading.png
  66. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showDetailsActivities.png
  67. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showDetailsActivitiesError.png
  68. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showDetailsSharing.png
  69. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showFileDetailActivitiesFragment.png
  70. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showFileDetailSharingFragment.png
  71. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileAllShareTypes.png
  72. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileNone.png
  73. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileResharingNotAllowed.png
  74. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.OCFileListFragmentStaticServerIT_showFolderTypes.png
  75. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.OCFileListFragmentStaticServerIT_showSharedFiles.png
  76. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.preview.PreviewBitmapScreenshotIT_showBitmap.png
  77. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_empty.png
  78. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_error.png
  79. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_files.png
  80. BIN
      app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_loading.png
  81. 5 0
      app/src/androidTest/java/com/owncloud/android/ui/activity/FolderPickerActivityIT.java
  82. 19 3
      app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.java
  83. 1 1
      app/src/main/AndroidManifest.xml
  84. 4 3
      app/src/main/java/com/nextcloud/client/di/AppModule.java
  85. 12 0
      app/src/main/java/com/nextcloud/client/di/ComponentsModule.java
  86. 22 95
      app/src/main/java/com/nextcloud/client/di/ThemeModule.kt
  87. 5 11
      app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt
  88. 4 3
      app/src/main/java/com/nextcloud/client/jobs/FilesExportWork.kt
  89. 7 9
      app/src/main/java/com/nextcloud/client/jobs/MediaFoldersDetectionWork.kt
  90. 10 5
      app/src/main/java/com/nextcloud/client/jobs/NotificationWork.kt
  91. 9 7
      app/src/main/java/com/nextcloud/client/logger/ui/LogsActivity.kt
  92. 3 3
      app/src/main/java/com/nextcloud/client/media/PlayerService.kt
  93. 7 6
      app/src/main/java/com/nextcloud/client/notifications/AppNotificationManagerImpl.kt
  94. 27 35
      app/src/main/java/com/nextcloud/client/onboarding/FirstRunActivity.java
  95. 3 3
      app/src/main/java/com/nextcloud/client/onboarding/WhatsNewActivity.java
  96. 7 7
      app/src/main/java/com/nextcloud/client/widget/DashboardWidgetConfigurationActivity.kt
  97. 23 15
      app/src/main/java/com/nextcloud/ui/ChooseAccountDialogFragment.kt
  98. 49 45
      app/src/main/java/com/nextcloud/ui/SetStatusDialogFragment.kt
  99. 9 36
      app/src/main/java/com/nextcloud/utils/view/FastScrollUtils.kt
  100. 14 8
      app/src/main/java/com/owncloud/android/MainApp.java

+ 10 - 8
app/build.gradle

@@ -112,7 +112,7 @@ android {
 
         buildTypes {
             debug {
-                testCoverageEnabled (project.hasProperty('coverage'))
+                testCoverageEnabled(project.hasProperty('coverage'))
             }
         }
 
@@ -218,7 +218,7 @@ dependencies {
     // dependencies for app building
     implementation 'androidx.multidex:multidex:2.0.1'
 //    implementation project('nextcloud-android-library')
-    implementation ("com.github.nextcloud:android-library:$androidLibraryVersion") {
+    implementation("com.github.nextcloud:android-library:$androidLibraryVersion") {
         exclude group: 'org.ogce', module: 'xpp3' // unused in Android and brings wrong Junit version
     }
 
@@ -281,7 +281,7 @@ dependencies {
     implementation "com.google.android.exoplayer:extension-okhttp:$exoplayerVersion"
 
     implementation 'me.zhanghai.android.fastscroll:library:1.1.8'
-    
+
     // Shimmer animation
     implementation 'io.github.elye:loaderviewlibrary:3.0.0'
 
@@ -296,8 +296,8 @@ dependencies {
     implementation "io.noties:prism4j:$prismVersion"
     kapt "io.noties:prism4j-bundler:$prismVersion"
 
-    implementation ('org.mnode.ical4j:ical4j:3.0.0') {
-        ['org.apache.commons','commons-logging'].each {
+    implementation('org.mnode.ical4j:ical4j:3.0.0') {
+        ['org.apache.commons', 'commons-logging'].each {
             exclude group: "$it"
         }
     }
@@ -352,10 +352,12 @@ dependencies {
 
     // upon each update first test: new registration, receive push
     gplayImplementation "com.google.firebase:firebase-messaging:23.0.7"
+
+    implementation 'com.github.nextcloud.android-common:ui:0.2.0'
 }
 
 configurations.all {
-    resolutionStrategy{
+    resolutionStrategy {
         cacheChangingModulesFor 0, 'seconds'
         force 'org.objenesis:objenesis:2.6'
         eachDependency { details ->
@@ -400,7 +402,7 @@ shot {
     showOnlyFailingTestsInReports = ciBuild
     // CI environment renders some shadows slightly different from local VMs
     // Add a 0.5% tolerance to account for that
-    tolerance = ciBuild ? 0.5: 0
+    tolerance = ciBuild ? 0.5 : 0
 }
 
 jacoco {
@@ -413,7 +415,7 @@ spotbugs {
     reportLevel = "medium"
 }
 
-tasks.withType(SpotBugsTask){task ->
+tasks.withType(SpotBugsTask) { task ->
     String variantNameCap = task.name.replace("spotbugs", "")
     String variantName = variantNameCap.substring(0, 1).toLowerCase() + variantNameCap.substring(1)
 

BIN
app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_empty.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_error.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_loading.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_openDrawer.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_showActivities.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.AuthenticatorActivityIT_login.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.CommunityActivityIT_open.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_drawer.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_open.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_showMediaThenAllFiles.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.FirstRunActivityIT_open.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.SettingsActivityIT_open.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.SettingsActivityIT_showMnemonic_Error.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.SyncedFoldersActivityIT_open.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.SyncedFoldersActivityIT_testSyncedFolderDialog.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.UploadListActivityActivityIT_openDrawer.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.etm.EtmActivityTest_accounts.png


BIN
app/screenshots/gplay/debug/com.nextcloud.client.etm.EtmActivityTest_overview.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepBoth.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepExisting.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepNew.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_screenshotTextFiles.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ContactsPreferenceActivityIT_openContactsPreference.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ContactsPreferenceActivityIT_openVCF.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.FolderPickerActivityIT_open.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_open.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_userInfoDetail.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.NotificationsActivityIT_empty.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.NotificationsActivityIT_error.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.NotificationsActivityIT_showNotifications.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.PassCodeActivityIT_check.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.PassCodeActivityIT_delete.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.PassCodeActivityIT_request.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.ReceiveExternalFilesActivityIT_open.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.UploadFilesActivityIT_localFolderPickerMode.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.UploadFilesActivityIT_noneSelected.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.UserInfoActivityIT_fullUserInfoDetail.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialogWithStatusDisabled.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_away.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_dnd.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_fun.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_offline.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog_online.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testBottomSheet.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testEnforcedPasswordDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testLoadingDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testNewFolderDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testOptionalPasswordDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testProfileBottomSheet.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFileDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFilesDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFolderDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFoldersDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRenameFileDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialogDifferentTypes_Screenshot.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialog_Screenshot.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendShareDialogTest_showDialog.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SetupEncryptionDialogFragmentIT_error.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SetupEncryptionDialogFragmentIT_showMnemonic.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.BackupListFragmentIT_showCalendarAndContactsList.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.BackupListFragmentIT_showCalendarList.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.BackupListFragmentIT_showContactList.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.BackupListFragmentIT_showLoading.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showDetailsActivities.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showDetailsActivitiesError.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showDetailsSharing.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showFileDetailActivitiesFragment.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showFileDetailSharingFragment.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileAllShareTypes.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileNone.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileResharingNotAllowed.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.OCFileListFragmentStaticServerIT_showFolderTypes.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.OCFileListFragmentStaticServerIT_showSharedFiles.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.preview.PreviewBitmapScreenshotIT_showBitmap.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_empty.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_error.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_files.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_loading.png


+ 5 - 0
app/src/androidTest/java/com/owncloud/android/ui/activity/FolderPickerActivityIT.java

@@ -22,6 +22,7 @@ package com.owncloud.android.ui.activity;
  */
 
 import com.owncloud.android.AbstractIT;
+import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.utils.ScreenshotTest;
 
@@ -128,6 +129,10 @@ public class FolderPickerActivityIT extends AbstractIT {
         OCFile origin = new OCFile("/test/file.txt");
         sut.setFile(origin);
 
+        sut.runOnUiThread(() -> {
+            sut.findViewById(R.id.folder_picker_btn_choose).requestFocus();
+        });
+        waitForIdleSync();
         screenshot(sut);
     }
 }

+ 19 - 3
app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.java

@@ -30,6 +30,8 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.bottomsheet.BottomSheetDialog;
 import com.google.gson.Gson;
 import com.nextcloud.android.lib.resources.profile.Action;
 import com.nextcloud.android.lib.resources.profile.HoverCard;
@@ -57,6 +59,7 @@ import com.owncloud.android.lib.resources.users.Status;
 import com.owncloud.android.lib.resources.users.StatusType;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
 import com.owncloud.android.ui.fragment.OCFileListBottomSheetActions;
+import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialog;
 import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialogFragment;
 import com.owncloud.android.ui.fragment.ProfileBottomSheetDialog;
 import com.owncloud.android.utils.MimeTypeUtil;
@@ -402,7 +405,21 @@ public class DialogFragmentIT extends AbstractIT {
                                                                                   user,
                                                                                   ocFile);
 
-        showDialog(fda, sut);
+        sut.show(fda.getSupportFragmentManager(), "");
+
+        getInstrumentation().waitForIdleSync();
+        shortSleep();
+
+        ((BottomSheetDialog) sut.requireDialog()).getBehavior().setState(BottomSheetBehavior.STATE_EXPANDED);
+
+        getInstrumentation().waitForIdleSync();
+        shortSleep();
+
+        ViewGroup viewGroup = sut.requireDialog().getWindow().findViewById(android.R.id.content);
+        hideCursors(viewGroup);
+
+        screenshot(Objects.requireNonNull(sut.requireDialog().getWindow()).getDecorView());
+
     }
 
     @Test
@@ -438,8 +455,7 @@ public class DialogFragmentIT extends AbstractIT {
         ProfileBottomSheetDialog sut = new ProfileBottomSheetDialog(fda,
                                                                     user,
                                                                     hoverCard,
-                                                                    fda.themeColorUtils,
-                                                                    fda.themeDrawableUtils);
+                                                                    fda.viewThemeUtils);
 
         fda.runOnUiThread(sut::show);
 

+ 1 - 1
app/src/main/AndroidManifest.xml

@@ -215,7 +215,7 @@
         <activity
             android:name=".ui.activity.SettingsActivity"
             android:exported="false"
-            android:theme="@style/Theme.ownCloud" />
+            android:theme="@style/PreferenceTheme" />
         <activity
             android:name=".ui.preview.PreviewImageActivity"
             android:exported="false"

+ 4 - 3
app/src/main/java/com/nextcloud/client/di/AppModule.java

@@ -64,13 +64,14 @@ import com.owncloud.android.ui.activities.data.activities.RemoteActivitiesReposi
 import com.owncloud.android.ui.activities.data.files.FilesRepository;
 import com.owncloud.android.ui.activities.data.files.FilesServiceApiImpl;
 import com.owncloud.android.ui.activities.data.files.RemoteFilesRepository;
-import com.owncloud.android.utils.theme.ThemeColorUtils;
+import com.owncloud.android.utils.theme.ViewThemeUtils;
 
 import org.greenrobot.eventbus.EventBus;
 
 import java.io.File;
 
 import javax.inject.Named;
+import javax.inject.Provider;
 import javax.inject.Singleton;
 
 import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -229,11 +230,11 @@ class AppModule {
     @Singleton
     AppNotificationManager notificationsManager(Context context,
                                                 NotificationManager platformNotificationsManager,
-                                                ThemeColorUtils themeColorUtils) {
+                                                Provider<ViewThemeUtils> viewThemeUtilsProvider) {
         return new AppNotificationManagerImpl(context,
                                               context.getResources(),
                                               platformNotificationsManager,
-                                              themeColorUtils);
+                                              viewThemeUtilsProvider.get());
     }
 
     @Provides

+ 12 - 0
app/src/main/java/com/nextcloud/client/di/ComponentsModule.java

@@ -103,7 +103,9 @@ import com.owncloud.android.ui.fragment.FeatureFragment;
 import com.owncloud.android.ui.fragment.FileDetailActivitiesFragment;
 import com.owncloud.android.ui.fragment.FileDetailFragment;
 import com.owncloud.android.ui.fragment.FileDetailSharingFragment;
+import com.owncloud.android.ui.fragment.FileDetailsSharingProcessFragment;
 import com.owncloud.android.ui.fragment.GalleryFragment;
+import com.owncloud.android.ui.fragment.GalleryFragmentBottomSheetDialog;
 import com.owncloud.android.ui.fragment.LocalFileListFragment;
 import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialog;
 import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialogFragment;
@@ -113,6 +115,7 @@ import com.owncloud.android.ui.fragment.UnifiedSearchFragment;
 import com.owncloud.android.ui.fragment.contactsbackup.BackupFragment;
 import com.owncloud.android.ui.fragment.contactsbackup.BackupListFragment;
 import com.owncloud.android.ui.preview.FileDownloadFragment;
+import com.owncloud.android.ui.preview.PreviewBitmapActivity;
 import com.owncloud.android.ui.preview.PreviewImageActivity;
 import com.owncloud.android.ui.preview.PreviewImageFragment;
 import com.owncloud.android.ui.preview.PreviewMediaFragment;
@@ -254,6 +257,9 @@ abstract class ComponentsModule {
     @ContributesAndroidInjector
     abstract FileDetailActivitiesFragment fileDetailActivitiesFragment();
 
+    @ContributesAndroidInjector
+    abstract FileDetailsSharingProcessFragment fileDetailsSharingProcessFragment();
+
     @ContributesAndroidInjector
     abstract FileDetailSharingFragment fileDetailSharingFragment();
 
@@ -442,4 +448,10 @@ abstract class ComponentsModule {
 
     @ContributesAndroidInjector
     abstract DashboardWidgetProvider dashboardWidgetProvider();
+
+    @ContributesAndroidInjector
+    abstract GalleryFragmentBottomSheetDialog galleryFragmentBottomSheetDialog();
+
+    @ContributesAndroidInjector
+    abstract PreviewBitmapActivity previewBitmapActivity();
 }

+ 22 - 95
app/src/main/java/com/nextcloud/client/di/ThemeModule.kt

@@ -20,112 +20,39 @@
  */
 package com.nextcloud.client.di
 
-import android.content.Context
-import com.owncloud.android.utils.theme.ThemeAvatarUtils
-import com.owncloud.android.utils.theme.ThemeBarUtils
-import com.owncloud.android.utils.theme.ThemeButtonUtils
-import com.owncloud.android.utils.theme.ThemeCheckableUtils
+import com.nextcloud.android.common.ui.theme.MaterialSchemes
+import com.owncloud.android.utils.theme.MaterialSchemesProvider
+import com.owncloud.android.utils.theme.MaterialSchemesProviderImpl
 import com.owncloud.android.utils.theme.ThemeColorUtils
-import com.owncloud.android.utils.theme.ThemeDrawableUtils
-import com.owncloud.android.utils.theme.ThemeFabUtils
-import com.owncloud.android.utils.theme.ThemeLayoutUtils
-import com.owncloud.android.utils.theme.ThemeMenuUtils
-import com.owncloud.android.utils.theme.ThemeSnackbarUtils
-import com.owncloud.android.utils.theme.ThemeTextInputUtils
-import com.owncloud.android.utils.theme.ThemeTextUtils
-import com.owncloud.android.utils.theme.ThemeToolbarUtils
 import com.owncloud.android.utils.theme.ThemeUtils
+import dagger.Binds
 import dagger.Module
 import dagger.Provides
 import javax.inject.Singleton
 
 @Module
-internal class ThemeModule {
-    @Provides
-    @Singleton
-    fun themeColorUtils(): ThemeColorUtils {
-        return ThemeColorUtils()
-    }
-
-    @Provides
-    @Singleton
-    fun themeFabUtils(themeColorUtils: ThemeColorUtils?, themeDrawableUtils: ThemeDrawableUtils?): ThemeFabUtils {
-        return ThemeFabUtils(themeColorUtils, themeDrawableUtils)
-    }
+internal abstract class ThemeModule {
 
-    @Provides
-    @Singleton
-    fun themeLayoutUtils(themeColorUtils: ThemeColorUtils?): ThemeLayoutUtils {
-        return ThemeLayoutUtils(themeColorUtils)
-    }
+    @Binds
+    abstract fun bindMaterialSchemesProvider(provider: MaterialSchemesProviderImpl): MaterialSchemesProvider
 
-    @Provides
-    @Singleton
-    fun themeToolbarUtils(
-        themeColorUtils: ThemeColorUtils?,
-        themeDrawableUtils: ThemeDrawableUtils?,
-        themeTextInputUtils: ThemeTextInputUtils?
-    ): ThemeToolbarUtils {
-        return ThemeToolbarUtils(themeColorUtils, themeDrawableUtils, themeTextInputUtils)
-    }
+    companion object {
 
-    @Provides
-    @Singleton
-    fun themeDrawableUtils(context: Context?): ThemeDrawableUtils {
-        return ThemeDrawableUtils(context)
-    }
+        @Provides
+        @Singleton
+        fun themeColorUtils(): ThemeColorUtils {
+            return ThemeColorUtils()
+        }
 
-    @Provides
-    @Singleton
-    fun themeUtils(): ThemeUtils {
-        return ThemeUtils()
-    }
-
-    @Provides
-    @Singleton
-    fun themeMenuUtils(): ThemeMenuUtils {
-        return ThemeMenuUtils()
-    }
-
-    @Provides
-    @Singleton
-    fun themeSnackbarUtils(): ThemeSnackbarUtils {
-        return ThemeSnackbarUtils()
-    }
-
-    @Provides
-    @Singleton
-    fun themeTextUtils(): ThemeTextUtils {
-        return ThemeTextUtils()
-    }
-
-    @Provides
-    @Singleton
-    fun themeButtonUtils(): ThemeButtonUtils {
-        return ThemeButtonUtils()
-    }
-
-    @Provides
-    @Singleton
-    fun themeBarUtils(): ThemeBarUtils {
-        return ThemeBarUtils()
-    }
-
-    @Provides
-    @Singleton
-    fun themeTextInputUtils(): ThemeTextInputUtils {
-        return ThemeTextInputUtils()
-    }
-
-    @Provides
-    @Singleton
-    fun themeCheckableUtils(): ThemeCheckableUtils {
-        return ThemeCheckableUtils()
-    }
+        @Provides
+        @Singleton
+        fun themeUtils(): ThemeUtils {
+            return ThemeUtils()
+        }
 
-    @Provides
-    @Singleton
-    fun themeAvatarUtils(): ThemeAvatarUtils {
-        return ThemeAvatarUtils()
+        @Provides
+        fun provideMaterialSchemes(materialSchemesProvider: MaterialSchemesProvider): MaterialSchemes {
+            return materialSchemesProvider.getMaterialSchemesForCurrentUser()
+        }
     }
 }

+ 5 - 11
app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt

@@ -40,9 +40,7 @@ import com.nextcloud.client.preferences.AppPreferences
 import com.owncloud.android.datamodel.ArbitraryDataProvider
 import com.owncloud.android.datamodel.SyncedFolderProvider
 import com.owncloud.android.datamodel.UploadsStorageManager
-import com.owncloud.android.utils.theme.ThemeButtonUtils
-import com.owncloud.android.utils.theme.ThemeColorUtils
-import com.owncloud.android.utils.theme.ThemeSnackbarUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import org.greenrobot.eventbus.EventBus
 import javax.inject.Inject
 import javax.inject.Provider
@@ -67,9 +65,7 @@ class BackgroundJobFactory @Inject constructor(
     private val notificationManager: NotificationManager,
     private val eventBus: EventBus,
     private val deckApi: DeckApi,
-    private val themeColorUtils: ThemeColorUtils,
-    private val themeSnackbarUtils: ThemeSnackbarUtils,
-    private val themeButtonUtils: ThemeButtonUtils
+    private val viewThemeUtils: Provider<ViewThemeUtils>
 ) : WorkerFactory() {
 
     @SuppressLint("NewApi")
@@ -113,7 +109,7 @@ class BackgroundJobFactory @Inject constructor(
             context,
             accountManager.user,
             contentResolver,
-            themeColorUtils,
+            viewThemeUtils.get(),
             params
         )
     }
@@ -212,9 +208,7 @@ class BackgroundJobFactory @Inject constructor(
             accountManager,
             preferences,
             clock,
-            themeColorUtils,
-            themeSnackbarUtils,
-            themeButtonUtils
+            viewThemeUtils.get()
         )
     }
 
@@ -225,7 +219,7 @@ class BackgroundJobFactory @Inject constructor(
             notificationManager,
             accountManager,
             deckApi,
-            themeColorUtils
+            viewThemeUtils.get()
         )
     }
 

+ 4 - 3
app/src/main/java/com/nextcloud/client/jobs/FilesExportWork.kt

@@ -44,14 +44,14 @@ import com.owncloud.android.ui.dialog.SendShareDialog
 import com.owncloud.android.ui.notifications.NotificationUtils
 import com.owncloud.android.utils.FileExportUtils
 import com.owncloud.android.utils.FileStorageUtils
-import com.owncloud.android.utils.theme.ThemeColorUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import java.security.SecureRandom
 
 class FilesExportWork(
     private val appContext: Context,
     private val user: User,
     private val contentResolver: ContentResolver,
-    private val themeColorUtils: ThemeColorUtils,
+    private val viewThemeUtils: ViewThemeUtils,
     params: WorkerParameters
 ) : Worker(appContext, params) {
 
@@ -153,11 +153,12 @@ class FilesExportWork(
         )
             .setSmallIcon(R.drawable.notification_icon)
             .setLargeIcon(BitmapFactory.decodeResource(appContext.resources, R.drawable.notification_icon))
-            .setColor(themeColorUtils.primaryColor(appContext))
             .setSubText(user.accountName)
             .setContentText(message)
             .setAutoCancel(true)
 
+        viewThemeUtils.androidx.themeNotificationCompatBuilder(appContext, notificationBuilder)
+
         val actionIntent = Intent(DownloadManager.ACTION_VIEW_DOWNLOADS).apply {
             flags = FLAG_ACTIVITY_NEW_TASK
         }

+ 7 - 9
app/src/main/java/com/nextcloud/client/jobs/MediaFoldersDetectionWork.kt

@@ -55,9 +55,7 @@ import com.owncloud.android.ui.activity.ManageAccountsActivity.PENDING_FOR_REMOV
 import com.owncloud.android.ui.activity.SyncedFoldersActivity
 import com.owncloud.android.ui.notifications.NotificationUtils
 import com.owncloud.android.utils.SyncedFolderUtils
-import com.owncloud.android.utils.theme.ThemeButtonUtils
-import com.owncloud.android.utils.theme.ThemeColorUtils
-import com.owncloud.android.utils.theme.ThemeSnackbarUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import java.util.Random
 
 @Suppress("LongParameterList") // dependencies injection
@@ -69,9 +67,7 @@ class MediaFoldersDetectionWork constructor(
     private val userAccountManager: UserAccountManager,
     private val preferences: AppPreferences,
     private val clock: Clock,
-    private val themeColorUtils: ThemeColorUtils,
-    private val themeSnackbarUtils: ThemeSnackbarUtils,
-    private val themeButtonUtils: ThemeButtonUtils
+    private val viewThemeUtils: ViewThemeUtils
 ) : Worker(context, params) {
 
     companion object {
@@ -97,14 +93,14 @@ class MediaFoldersDetectionWork constructor(
             1,
             null,
             true,
-            themeSnackbarUtils
+            viewThemeUtils
         )
         val videoMediaFolders = MediaProvider.getVideoFolders(
             contentResolver,
             1,
             null,
             true,
-            themeSnackbarUtils
+            viewThemeUtils
         )
         val imageMediaFolderPaths: MutableList<String> = ArrayList()
         val videoMediaFolderPaths: MutableList<String> = ArrayList()
@@ -222,13 +218,15 @@ class MediaFoldersDetectionWork constructor(
         )
             .setSmallIcon(R.drawable.notification_icon)
             .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon))
-            .setColor(themeColorUtils.primaryColor(context))
             .setSubText(user.accountName)
             .setContentTitle(contentTitle)
             .setContentText(subtitle)
             .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
             .setAutoCancel(true)
             .setContentIntent(pendingIntent)
+
+        viewThemeUtils.androidx.themeNotificationCompatBuilder(context, notificationBuilder)
+
         val disableDetection = Intent(context, NotificationReceiver::class.java)
         disableDetection.putExtra(NOTIFICATION_ID, notificationId)
         disableDetection.action = DISABLE_DETECTION_CLICK

+ 10 - 5
app/src/main/java/com/nextcloud/client/jobs/NotificationWork.kt

@@ -54,7 +54,7 @@ import com.owncloud.android.ui.activity.FileDisplayActivity
 import com.owncloud.android.ui.activity.NotificationsActivity
 import com.owncloud.android.ui.notifications.NotificationUtils
 import com.owncloud.android.utils.PushUtils
-import com.owncloud.android.utils.theme.ThemeColorUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import dagger.android.AndroidInjection
 import org.apache.commons.httpclient.HttpMethod
 import org.apache.commons.httpclient.HttpStatus
@@ -76,7 +76,7 @@ class NotificationWork constructor(
     private val notificationManager: NotificationManager,
     private val accountManager: UserAccountManager,
     private val deckApi: DeckApi,
-    private val themeColorUtils: ThemeColorUtils
+    private val viewThemeUtils: ViewThemeUtils
 ) : Worker(context, params) {
 
     companion object {
@@ -168,7 +168,6 @@ class NotificationWork constructor(
         val notificationBuilder = NotificationCompat.Builder(context, NotificationUtils.NOTIFICATION_CHANNEL_PUSH)
             .setSmallIcon(R.drawable.notification_icon)
             .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon))
-            .setColor(themeColorUtils.primaryColor(user.toPlatformAccount(), false, context))
             .setShowWhen(true)
             .setSubText(user.accountName)
             .setContentTitle(notification.getSubject())
@@ -177,6 +176,9 @@ class NotificationWork constructor(
             .setAutoCancel(true)
             .setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
             .setContentIntent(pendingIntent)
+
+        viewThemeUtils.androidx.themeNotificationCompatBuilder(context, notificationBuilder)
+
         // Remove
         if (notification.getActions().isEmpty()) {
             val disableDetection = Intent(context, NotificationReceiver::class.java)
@@ -223,14 +225,17 @@ class NotificationWork constructor(
             NotificationCompat.Builder(context, NotificationUtils.NOTIFICATION_CHANNEL_PUSH)
                 .setSmallIcon(R.drawable.notification_icon)
                 .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.notification_icon))
-                .setColor(themeColorUtils.primaryColor(user.toPlatformAccount(), false, context))
                 .setShowWhen(true)
                 .setSubText(user.accountName)
                 .setContentTitle(context.getString(R.string.new_notification))
                 .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                 .setAutoCancel(true)
                 .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
-                .setContentIntent(pendingIntent).build()
+                .setContentIntent(pendingIntent)
+                .also {
+                    viewThemeUtils.androidx.themeNotificationCompatBuilder(context, it)
+                }
+                .build()
         )
         val notificationManager = NotificationManagerCompat.from(context)
         notificationManager.notify(notification.getNotificationId(), notificationBuilder.build())

+ 9 - 7
app/src/main/java/com/nextcloud/client/logger/ui/LogsActivity.kt

@@ -33,7 +33,7 @@ import com.nextcloud.client.di.ViewModelFactory
 import com.owncloud.android.R
 import com.owncloud.android.databinding.LogsActivityBinding
 import com.owncloud.android.ui.activity.ToolbarActivity
-import com.owncloud.android.utils.theme.ThemeBarUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import javax.inject.Inject
 
 class LogsActivity : ToolbarActivity() {
@@ -42,7 +42,8 @@ class LogsActivity : ToolbarActivity() {
     protected lateinit var viewModelFactory: ViewModelFactory
 
     @Inject
-    protected lateinit var themeBarUtils: ThemeBarUtils
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     private lateinit var vm: LogsViewModel
     private lateinit var binding: LogsActivityBinding
     private lateinit var logsAdapter: LogsAdapter
@@ -67,7 +68,7 @@ class LogsActivity : ToolbarActivity() {
         }
 
         findViewById<ProgressBar>(R.id.logs_loading_progress).apply {
-            themeBarUtils.themeProgressBar(context, this, themeColorUtils)
+            viewThemeUtils.platform.themeHorizontalProgressBar(this)
         }
 
         logsAdapter = LogsAdapter(this)
@@ -81,17 +82,18 @@ class LogsActivity : ToolbarActivity() {
 
         setupToolbar()
         supportActionBar?.setDisplayHomeAsUpEnabled(true)
-        supportActionBar?.apply { themeToolbarUtils.setColoredTitle(this, getString(R.string.logs_title), baseContext) }
 
-        themeToolbarUtils.tintBackButton(supportActionBar, baseContext)
+        supportActionBar?.let {
+            viewThemeUtils.files.themeActionBar(this, it, R.string.logs_title)
+        }
     }
 
     override fun onCreateOptionsMenu(menu: Menu): Boolean {
         menuInflater.inflate(R.menu.activity_logs, menu)
+
         (menu.findItem(R.id.action_search).actionView as SearchView).apply {
             setOnQueryTextListener(searchBoxListener)
-
-            themeToolbarUtils.themeSearchView(this, context)
+            viewThemeUtils.androidx.themeToolbarSearchView(this)
         }
         return super.onCreateOptionsMenu(menu)
     }

+ 3 - 3
app/src/main/java/com/nextcloud/client/media/PlayerService.kt

@@ -33,7 +33,7 @@ import com.nextcloud.client.network.ClientFactory
 import com.owncloud.android.R
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.ui.notifications.NotificationUtils
-import com.owncloud.android.utils.theme.ThemeColorUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import dagger.android.AndroidInjection
 import java.util.Locale
 import javax.inject.Inject
@@ -90,7 +90,7 @@ class PlayerService : Service() {
     protected lateinit var clientFactory: ClientFactory
 
     @Inject
-    protected lateinit var themeColorUtils: ThemeColorUtils
+    lateinit var viewThemeUtils: ViewThemeUtils
 
     private lateinit var player: Player
     private lateinit var notificationBuilder: NotificationCompat.Builder
@@ -101,7 +101,7 @@ class PlayerService : Service() {
         AndroidInjection.inject(this)
         player = Player(applicationContext, clientFactory, playerListener, audioManager)
         notificationBuilder = NotificationCompat.Builder(this)
-        notificationBuilder.color = themeColorUtils.primaryColor(this)
+        viewThemeUtils.androidx.themeNotificationCompatBuilder(this, notificationBuilder)
 
         val stop = Intent(this, PlayerService::class.java)
         stop.action = ACTION_STOP

+ 7 - 6
app/src/main/java/com/nextcloud/client/notifications/AppNotificationManagerImpl.kt

@@ -16,14 +16,14 @@ import com.owncloud.android.ui.activity.FileDisplayActivity
 import com.owncloud.android.ui.notifications.NotificationUtils
 import com.owncloud.android.ui.preview.PreviewImageActivity
 import com.owncloud.android.ui.preview.PreviewImageFragment
-import com.owncloud.android.utils.theme.ThemeColorUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import javax.inject.Inject
 
 class AppNotificationManagerImpl @Inject constructor(
     private val context: Context,
     private val resources: Resources,
     private val platformNotificationsManager: NotificationManager,
-    private val themeColorUtils: ThemeColorUtils
+    private val viewThemeUtils: ViewThemeUtils
 ) : AppNotificationManager {
 
     companion object {
@@ -32,12 +32,13 @@ class AppNotificationManagerImpl @Inject constructor(
     }
 
     private fun builder(channelId: String): NotificationCompat.Builder {
-        val color = themeColorUtils.primaryColor(context, true)
-        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            NotificationCompat.Builder(context, channelId).setColor(color)
+        val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            NotificationCompat.Builder(context, channelId)
         } else {
-            NotificationCompat.Builder(context).setColor(color)
+            NotificationCompat.Builder(context)
         }
+        viewThemeUtils.androidx.themeNotificationCompatBuilder(context, builder)
+        return builder
     }
 
     override fun buildDownloadServiceForegroundNotification(): Notification {

+ 27 - 35
app/src/main/java/com/nextcloud/client/onboarding/FirstRunActivity.java

@@ -32,9 +32,7 @@ import android.net.Uri;
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.Button;
 import android.widget.LinearLayout;
-import android.widget.TextView;
 
 import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.appinfo.AppInfo;
@@ -43,11 +41,11 @@ import com.nextcloud.client.preferences.AppPreferences;
 import com.owncloud.android.BuildConfig;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AuthenticatorActivity;
+import com.owncloud.android.databinding.FirstRunActivityBinding;
 import com.owncloud.android.features.FeatureItem;
 import com.owncloud.android.ui.activity.BaseActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
 import com.owncloud.android.ui.adapter.FeaturesViewAdapter;
-import com.owncloud.android.ui.whatsnew.ProgressIndicator;
 import com.owncloud.android.utils.DisplayUtils;
 
 import javax.inject.Inject;
@@ -63,29 +61,30 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
     public static final String EXTRA_EXIT = "EXIT";
     public static final int FIRST_RUN_RESULT_CODE = 199;
 
-    private ProgressIndicator progressIndicator;
-
     @Inject UserAccountManager userAccountManager;
     @Inject AppPreferences preferences;
     @Inject AppInfo appInfo;
     @Inject OnboardingService onboarding;
 
+    private FirstRunActivityBinding binding;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         enableAccountHandling = false;
 
         super.onCreate(savedInstanceState);
-        setContentView(R.layout.first_run_activity);
+        this.binding = FirstRunActivityBinding.inflate(getLayoutInflater());
+        setContentView(binding.getRoot());
 
         boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation);
 
         setSlideshowSize(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
 
-        Button loginButton = findViewById(R.id.login);
-        loginButton.setBackgroundColor(getResources().getColor(R.color.login_btn_tint));
-        loginButton.setTextColor(getResources().getColor(R.color.primary));
 
-        loginButton.setOnClickListener(v -> {
+        binding.login.setBackgroundColor(getResources().getColor(R.color.login_btn_tint));
+        binding.login.setTextColor(getResources().getColor(R.color.primary));
+
+        binding.login.setOnClickListener(v -> {
             if (getIntent().getBooleanExtra(EXTRA_ALLOW_CLOSE, false)) {
                 Intent authenticatorActivityIntent = new Intent(this, AuthenticatorActivity.class);
                 authenticatorActivityIntent.putExtra(AuthenticatorActivity.EXTRA_USE_PROVIDER_AS_WEBLOGIN, false);
@@ -95,11 +94,11 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
             }
         });
 
-        Button providerButton = findViewById(R.id.signup);
-        providerButton.setBackgroundColor(getResources().getColor(R.color.primary));
-        providerButton.setTextColor(getResources().getColor(R.color.login_text_color));
-        providerButton.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
-        providerButton.setOnClickListener(v -> {
+
+        binding.signup.setBackgroundColor(getResources().getColor(R.color.primary));
+        binding.signup.setTextColor(getResources().getColor(R.color.login_text_color));
+        binding.signup.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
+        binding.signup.setOnClickListener(v -> {
             Intent authenticatorActivityIntent = new Intent(this, AuthenticatorActivity.class);
             authenticatorActivityIntent.putExtra(AuthenticatorActivity.EXTRA_USE_PROVIDER_AS_WEBLOGIN, true);
 
@@ -111,16 +110,13 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
             }
         });
 
-        TextView hostOwnServerTextView = findViewById(R.id.host_own_server);
-        hostOwnServerTextView.setTextColor(getResources().getColor(R.color.login_text_color));
-        hostOwnServerTextView.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
+        binding.hostOwnServer.setTextColor(getResources().getColor(R.color.login_text_color));
+        binding.hostOwnServer.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
 
-        if(!isProviderOrOwnInstallationVisible) {
-            hostOwnServerTextView.setOnClickListener(v -> onHostYourOwnServerClick());
+        if (!isProviderOrOwnInstallationVisible) {
+            binding.hostOwnServer.setOnClickListener(v -> onHostYourOwnServerClick());
         }
 
-        progressIndicator = findViewById(R.id.progressIndicator);
-        ViewPager viewPager = findViewById(R.id.contentPanel);
 
         // Sometimes, accounts are not deleted when you uninstall the application so we'll do it now
         if (onboarding.isFirstRun()) {
@@ -128,29 +124,26 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
         }
 
         FeaturesViewAdapter featuresViewAdapter = new FeaturesViewAdapter(getSupportFragmentManager(), getFirstRun());
-        progressIndicator.setNumberOfSteps(featuresViewAdapter.getCount());
-        viewPager.setAdapter(featuresViewAdapter);
+        binding.progressIndicator.setNumberOfSteps(featuresViewAdapter.getCount());
+        binding.contentPanel.setAdapter(featuresViewAdapter);
 
-        viewPager.addOnPageChangeListener(this);
+        binding.contentPanel.addOnPageChangeListener(this);
     }
 
     private void setSlideshowSize(boolean isLandscape) {
         boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation);
-        LinearLayout buttonLayout = findViewById(R.id.buttonLayout);
+
         LinearLayout.LayoutParams layoutParams;
 
-        buttonLayout.setOrientation(isLandscape ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
+        binding.buttonLayout.setOrientation(isLandscape ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
 
-        LinearLayout bottomLayout = findViewById(R.id.bottomLayout);
         if (isProviderOrOwnInstallationVisible) {
-            layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
-                    ViewGroup.LayoutParams.WRAP_CONTENT);
+            layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
         } else {
-            layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
-                    DisplayUtils.convertDpToPixel(isLandscape ? 100f : 150f, this));
+            layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DisplayUtils.convertDpToPixel(isLandscape ? 100f : 150f, this));
         }
 
-        bottomLayout.setLayoutParams(layoutParams);
+        binding.bottomLayout.setLayoutParams(layoutParams);
     }
 
     @Override
@@ -196,7 +189,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
 
     @Override
     public void onPageSelected(int position) {
-        progressIndicator.animateToStep(position + 1);
+        binding.progressIndicator.animateToStep(position + 1);
     }
 
     @Override
@@ -235,7 +228,6 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
     }
 
 
-
     public static FeatureItem[] getFirstRun() {
         return new FeatureItem[]{
                 new FeatureItem(R.drawable.logo, R.string.first_run_1_text, R.string.empty, true, false),

+ 3 - 3
app/src/main/java/com/nextcloud/client/onboarding/WhatsNewActivity.java

@@ -37,7 +37,7 @@ import com.owncloud.android.R;
 import com.owncloud.android.ui.adapter.FeaturesViewAdapter;
 import com.owncloud.android.ui.adapter.FeaturesWebViewAdapter;
 import com.owncloud.android.ui.whatsnew.ProgressIndicator;
-import com.owncloud.android.utils.theme.ThemeButtonUtils;
+import com.owncloud.android.utils.theme.ViewThemeUtils;
 
 import javax.inject.Inject;
 
@@ -56,7 +56,7 @@ public class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPa
     @Inject AppPreferences preferences;
     @Inject AppInfo appInfo;
     @Inject OnboardingService onboarding;
-    @Inject ThemeButtonUtils themeButtonUtils;
+    @Inject ViewThemeUtils viewThemeUtils;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -86,7 +86,7 @@ public class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPa
         mPager.addOnPageChangeListener(this);
 
         mForwardFinishButton = findViewById(R.id.forward);
-        themeButtonUtils.colorImageButton(mForwardFinishButton, fontColor);
+        viewThemeUtils.platform.colorImageButton(mForwardFinishButton, fontColor);
 
         mForwardFinishButton.setOnClickListener(view -> {
             if (mProgress.hasNextStep()) {

+ 7 - 7
app/src/main/java/com/nextcloud/client/widget/DashboardWidgetConfigurationActivity.kt

@@ -44,7 +44,7 @@ import com.owncloud.android.lib.common.utils.Log_OC
 import com.owncloud.android.ui.adapter.DashboardWidgetListAdapter
 import com.owncloud.android.ui.dialog.AccountChooserInterface
 import com.owncloud.android.ui.dialog.MultipleAccountsDialog
-import com.owncloud.android.utils.theme.ThemeDrawableUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -61,7 +61,7 @@ class DashboardWidgetConfigurationActivity :
     private lateinit var currentUser: User
 
     @Inject
-    lateinit var themeDrawableUtils: ThemeDrawableUtils
+    lateinit var viewThemeUtils: ViewThemeUtils
 
     @Inject
     lateinit var accountManager: UserAccountManager
@@ -87,11 +87,11 @@ class DashboardWidgetConfigurationActivity :
         binding = DashboardWidgetConfigurationLayoutBinding.inflate(layoutInflater)
         setContentView(binding.root)
 
-        themeDrawableUtils.tintDrawable(binding.icon.drawable, getColor(R.color.dark))
+        viewThemeUtils.platform.colorDrawable(binding.icon.drawable, getColor(R.color.dark))
 
         val layoutManager = LinearLayoutManager(this)
         // TODO follow our new architecture
-        mAdapter = DashboardWidgetListAdapter(themeDrawableUtils, accountManager, clientFactory, this, this)
+        mAdapter = DashboardWidgetListAdapter(accountManager, clientFactory, this, this)
         binding.list.apply {
             setHasFooter(false)
             setAdapter(mAdapter)
@@ -107,12 +107,12 @@ class DashboardWidgetConfigurationActivity :
                 setCompoundDrawablesWithIntrinsicBounds(
                     null,
                     null,
-                    themeDrawableUtils.tintDrawable(
+                    viewThemeUtils.platform.colorDrawable(
                         AppCompatResources.getDrawable(
                             context,
                             R.drawable.ic_baseline_arrow_drop_down_24
-                        ),
-                        R.color.black
+                        )!!,
+                        getColor(R.color.black)
                     ),
                     null
                 )

+ 23 - 15
app/src/main/java/com/nextcloud/ui/ChooseAccountDialogFragment.kt

@@ -29,7 +29,6 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.ImageView
-import androidx.core.content.ContextCompat
 import androidx.fragment.app.DialogFragment
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.nextcloud.client.account.User
@@ -48,8 +47,7 @@ import com.owncloud.android.ui.adapter.UserListItem
 import com.owncloud.android.ui.asynctasks.RetrieveStatusAsyncTask
 import com.owncloud.android.utils.DisplayUtils
 import com.owncloud.android.utils.DisplayUtils.AvatarGenerationListener
-import com.owncloud.android.utils.theme.ThemeColorUtils
-import com.owncloud.android.utils.theme.ThemeDrawableUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import javax.inject.Inject
 
 private const val ARG_CURRENT_USER_PARAM = "currentUser"
@@ -73,10 +71,7 @@ class ChooseAccountDialogFragment :
     lateinit var clientFactory: ClientFactory
 
     @Inject
-    lateinit var themeColorUtils: ThemeColorUtils
-
-    @Inject
-    lateinit var themeDrawableUtils: ThemeDrawableUtils
+    lateinit var viewThemeUtils: ViewThemeUtils
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -90,9 +85,12 @@ class ChooseAccountDialogFragment :
         _binding = DialogChooseAccountBinding.inflate(layoutInflater)
         dialogView = binding.root
 
-        return MaterialAlertDialogBuilder(requireContext())
+        val builder = MaterialAlertDialogBuilder(requireContext())
             .setView(binding.root)
-            .create()
+
+        viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.statusView.context, builder)
+
+        return builder.create()
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -117,10 +115,7 @@ class ChooseAccountDialogFragment :
             binding.currentAccount.account.text = user.accountName
 
             // Defining user right indicator
-            val icon = themeDrawableUtils.tintDrawable(
-                ContextCompat.getDrawable(requireContext(), R.drawable.ic_check_circle),
-                themeColorUtils.primaryColor(requireContext(), true)
-            )
+            val icon = viewThemeUtils.platform.tintPrimaryDrawable(requireContext(), R.drawable.ic_check_circle)
             binding.currentAccount.accountMenu.setImageDrawable(icon)
 
             // Creating adapter for accounts list
@@ -132,8 +127,7 @@ class ChooseAccountDialogFragment :
                 false,
                 false,
                 true,
-                themeColorUtils,
-                themeDrawableUtils
+                viewThemeUtils
             )
 
             binding.accountsList.adapter = adapter
@@ -165,6 +159,20 @@ class ChooseAccountDialogFragment :
 
             RetrieveStatusAsyncTask(user, this, clientFactory).execute()
         }
+
+        themeViews()
+    }
+
+    private fun themeViews() {
+        viewThemeUtils.platform.themeDialogDivider(binding.separatorLine)
+        viewThemeUtils.platform.themeDialog(binding.root)
+
+        viewThemeUtils.material.colorMaterialTextButton(binding.setStatus)
+        viewThemeUtils.dialog.colorDialogMenuText(binding.setStatus)
+        viewThemeUtils.material.colorMaterialTextButton(binding.addAccount)
+        viewThemeUtils.dialog.colorDialogMenuText(binding.addAccount)
+        viewThemeUtils.material.colorMaterialTextButton(binding.manageAccounts)
+        viewThemeUtils.dialog.colorDialogMenuText(binding.manageAccounts)
     }
 
     private fun getAccountListItems(): List<UserListItem> {

+ 49 - 45
app/src/main/java/com/nextcloud/ui/SetStatusDialogFragment.kt

@@ -24,6 +24,7 @@ import android.annotation.SuppressLint
 import android.app.Dialog
 import android.content.Context
 import android.os.Bundle
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -31,10 +32,13 @@ import android.view.inputmethod.InputMethodManager
 import android.widget.AdapterView
 import android.widget.AdapterView.OnItemSelectedListener
 import android.widget.ArrayAdapter
+import android.widget.ImageView
+import android.widget.TextView
 import androidx.annotation.VisibleForTesting
-import androidx.appcompat.app.AlertDialog
 import androidx.fragment.app.DialogFragment
 import androidx.recyclerview.widget.LinearLayoutManager
+import com.google.android.material.card.MaterialCardView
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
 import com.nextcloud.client.account.User
@@ -53,9 +57,7 @@ import com.owncloud.android.ui.activity.BaseActivity
 import com.owncloud.android.ui.adapter.PredefinedStatusClickListener
 import com.owncloud.android.ui.adapter.PredefinedStatusListAdapter
 import com.owncloud.android.utils.DisplayUtils
-import com.owncloud.android.utils.theme.ThemeButtonUtils
-import com.owncloud.android.utils.theme.ThemeColorUtils
-import com.owncloud.android.utils.theme.ThemeTextInputUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import com.vanniktech.emoji.EmojiManager
 import com.vanniktech.emoji.EmojiPopup
 import com.vanniktech.emoji.google.GoogleEmojiProvider
@@ -110,13 +112,7 @@ class SetStatusDialogFragment :
     lateinit var clientFactory: ClientFactory
 
     @Inject
-    lateinit var themeColorUtils: ThemeColorUtils
-
-    @Inject
-    lateinit var themeButtonUtils: ThemeButtonUtils
-
-    @Inject
-    lateinit var themeTextInputUtils: ThemeTextInputUtils
+    lateinit var viewThemeUtils: ViewThemeUtils
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -139,9 +135,11 @@ class SetStatusDialogFragment :
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
         binding = DialogSetStatusBinding.inflate(layoutInflater)
 
-        return AlertDialog.Builder(requireContext())
-            .setView(binding.root)
-            .create()
+        val builder = MaterialAlertDialogBuilder(requireContext()).setView(binding.root)
+
+        viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.statusView.context, builder)
+
+        return builder.create()
     }
 
     @SuppressLint("DefaultLocale")
@@ -165,6 +163,11 @@ class SetStatusDialogFragment :
         binding.awayStatus.setOnClickListener { setStatus(StatusType.AWAY) }
         binding.invisibleStatus.setOnClickListener { setStatus(StatusType.INVISIBLE) }
 
+        viewThemeUtils.files.themeStatusCardView(binding.onlineStatus)
+        viewThemeUtils.files.themeStatusCardView(binding.dndStatus)
+        viewThemeUtils.files.themeStatusCardView(binding.awayStatus)
+        viewThemeUtils.files.themeStatusCardView(binding.invisibleStatus)
+
         binding.clearStatus.setOnClickListener { clearStatus() }
         binding.setStatus.setOnClickListener { setStatusMessage() }
         binding.emoji.setOnClickListener { popup.show() }
@@ -204,14 +207,11 @@ class SetStatusDialogFragment :
             }
         }
 
-        binding.clearStatus.setTextColor(themeColorUtils.primaryColor(context, true))
-        themeButtonUtils.colorPrimaryButton(binding.setStatus, context, themeColorUtils)
-        themeTextInputUtils.colorTextInput(
-            binding.customStatusInputContainer,
-            binding.customStatusInput,
-            themeColorUtils.primaryColor(activity),
-            themeColorUtils.primaryAccentColor(activity)
-        )
+        viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(binding.clearStatus)
+        viewThemeUtils.material.colorMaterialButtonPrimaryTonal(binding.setStatus)
+        viewThemeUtils.material.colorTextInputLayout(binding.customStatusInputContainer)
+
+        viewThemeUtils.platform.themeDialog(binding.root)
     }
 
     private fun updateCurrentStatusViews(it: Status) {
@@ -318,34 +318,37 @@ class SetStatusDialogFragment :
     }
 
     private fun visualizeStatus(statusType: StatusType) {
-        when (statusType) {
-            StatusType.ONLINE -> {
-                clearTopStatus()
-                binding.onlineStatus.setBackgroundColor(themeColorUtils.primaryColor(context))
-            }
-            StatusType.AWAY -> {
-                clearTopStatus()
-                binding.awayStatus.setBackgroundColor(themeColorUtils.primaryColor(context))
+        clearTopStatus()
+        val views: Triple<MaterialCardView, TextView, ImageView> = when (statusType) {
+            StatusType.ONLINE -> Triple(binding.onlineStatus, binding.onlineHeadline, binding.onlineIcon)
+            StatusType.AWAY -> Triple(binding.awayStatus, binding.awayHeadline, binding.awayIcon)
+            StatusType.DND -> Triple(binding.dndStatus, binding.dndHeadline, binding.dndIcon)
+            StatusType.INVISIBLE -> Triple(binding.invisibleStatus, binding.invisibleHeadline, binding.invisibleIcon)
+            else -> {
+                Log.d(TAG, "unknown status")
+                return
             }
-            StatusType.DND -> {
-                clearTopStatus()
-                binding.dndStatus.setBackgroundColor(themeColorUtils.primaryColor(context))
-            }
-            StatusType.INVISIBLE -> {
-                clearTopStatus()
-                binding.invisibleStatus.setBackgroundColor(themeColorUtils.primaryColor(context))
-            }
-            else -> clearTopStatus()
         }
+        views.first.isChecked = true
+        viewThemeUtils.platform.colorOnSecondaryContainerTextViewElement(views.second)
     }
 
     private fun clearTopStatus() {
         context?.let {
-            val grey = it.resources.getColor(R.color.grey_200)
-            binding.onlineStatus.setBackgroundColor(grey)
-            binding.awayStatus.setBackgroundColor(grey)
-            binding.dndStatus.setBackgroundColor(grey)
-            binding.invisibleStatus.setBackgroundColor(grey)
+            binding.onlineHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text))
+            binding.awayHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text))
+            binding.dndHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text))
+            binding.invisibleHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text))
+
+            binding.onlineIcon.imageTintList = null
+            binding.awayIcon.imageTintList = null
+            binding.dndIcon.imageTintList = null
+            binding.invisibleIcon.imageTintList = null
+
+            binding.onlineStatus.isChecked = false
+            binding.awayStatus.isChecked = false
+            binding.dndStatus.isChecked = false
+            binding.invisibleStatus.isChecked = false
         }
     }
 
@@ -384,6 +387,8 @@ class SetStatusDialogFragment :
      * Fragment creator
      */
     companion object {
+        private val TAG = SetStatusDialogFragment::class.simpleName
+
         @JvmStatic
         fun newInstance(user: User, status: Status?): SetStatusDialogFragment {
             val args = Bundle()
@@ -391,7 +396,6 @@ class SetStatusDialogFragment :
             args.putParcelable(ARG_CURRENT_STATUS_PARAM, status)
             val dialogFragment = SetStatusDialogFragment()
             dialogFragment.arguments = args
-            dialogFragment.setStyle(STYLE_NORMAL, R.style.Theme_ownCloud_Dialog)
             return dialogFragment
         }
     }

+ 9 - 36
app/src/main/java/com/nextcloud/utils/view/FastScroll.kt → app/src/main/java/com/nextcloud/utils/view/FastScrollUtils.kt

@@ -27,37 +27,26 @@
 
 package com.nextcloud.utils.view
 
-import android.content.Context
-import android.graphics.drawable.Drawable
 import android.view.ViewGroup
-import androidx.annotation.ColorInt
-import androidx.core.content.res.ResourcesCompat
 import androidx.recyclerview.widget.RecyclerView
 import com.google.android.material.appbar.AppBarLayout
-import com.owncloud.android.utils.theme.ThemeColorUtils
-import com.owncloud.android.utils.theme.ThemeDrawableUtils
+import com.owncloud.android.utils.theme.ViewThemeUtils
 import me.zhanghai.android.fastscroll.FastScroller
 import me.zhanghai.android.fastscroll.FastScrollerBuilder
-import me.zhanghai.android.fastscroll.PopupStyles
+import javax.inject.Inject
 
-object FastScroll {
-
-    @JvmStatic
+class FastScrollUtils @Inject constructor(private val viewThemeUtils: ViewThemeUtils) {
     @JvmOverloads
     fun applyFastScroll(
-        context: Context,
-        themeColorUtils: ThemeColorUtils,
-        themeDrawableUtils: ThemeDrawableUtils,
         recyclerView: RecyclerView,
         viewHelper: FastScroller.ViewHelper? = null
     ) {
-        val primaryColor = themeColorUtils.primaryColor(context)
-        val builder = FastScrollerBuilder(recyclerView)
-            .useMd2Style()
-            .setThumbDrawable(getThumbDrawable(context, themeDrawableUtils, primaryColor))
-            .setPopupStyle {
-                PopupStyles.MD2.accept(it)
-                it.background = FastScrollPopupBackground(context, primaryColor)
+        val builder =
+            FastScrollerBuilder(recyclerView).let {
+                viewThemeUtils.files.themeFastScrollerBuilder(
+                    recyclerView.context,
+                    it
+                )
             }
         if (viewHelper != null) {
             builder.setViewHelper(viewHelper)
@@ -65,22 +54,6 @@ object FastScroll {
         builder.build()
     }
 
-    private fun getThumbDrawable(
-        context: Context,
-        themeDrawableUtils: ThemeDrawableUtils,
-        @ColorInt color: Int
-    ): Drawable {
-        val thumbDrawable =
-            ResourcesCompat.getDrawable(
-                context.resources,
-                me.zhanghai.android.fastscroll.R.drawable.afs_md2_thumb,
-                null
-            )
-        themeDrawableUtils.tintDrawable(thumbDrawable, color)
-        return thumbDrawable!!
-    }
-
-    @JvmStatic
     fun fixAppBarForFastScroll(appBarLayout: AppBarLayout, content: ViewGroup) {
         val contentLayoutInitialPaddingBottom = content.paddingBottom
         appBarLayout.addOnOffsetChangedListener(

+ 14 - 8
app/src/main/java/com/owncloud/android/MainApp.java

@@ -81,7 +81,7 @@ import com.owncloud.android.utils.FilesSyncHelper;
 import com.owncloud.android.utils.PermissionUtil;
 import com.owncloud.android.utils.ReceiversHelper;
 import com.owncloud.android.utils.SecurityUtils;
-import com.owncloud.android.utils.theme.ThemeSnackbarUtils;
+import com.owncloud.android.utils.theme.ViewThemeUtils;
 
 import org.conscrypt.Conscrypt;
 import org.greenrobot.eventbus.EventBus;
@@ -97,6 +97,7 @@ import java.util.Locale;
 import java.util.Map;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 
@@ -177,7 +178,10 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
     @Inject
     PassCodeManager passCodeManager;
 
-    @Inject ThemeSnackbarUtils themeSnackbarUtils;
+    // workaround because injection is initialized on onAttachBaseContext
+    // and getApplicationContext is null at that point, which crashes when getting current user
+    @Inject Provider<ViewThemeUtils> viewThemeUtilsProvider;
+    private ViewThemeUtils viewThemeUtils;
 
     @SuppressWarnings("unused")
     private boolean mBound;
@@ -274,6 +278,8 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
     public void onCreate() {
         enableStrictMode();
 
+        viewThemeUtils = viewThemeUtilsProvider.get();
+
         setAppTheme(preferences.getDarkThemeMode());
         super.onCreate();
 
@@ -320,7 +326,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
                            powerManagementService,
                            backgroundJobManager,
                            clock,
-                           themeSnackbarUtils);
+                           viewThemeUtils);
         initContactsBackup(accountManager, backgroundJobManager);
         notificationChannels();
 
@@ -500,7 +506,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
         final PowerManagementService powerManagementService,
         final BackgroundJobManager backgroundJobManager,
         final Clock clock,
-        final ThemeSnackbarUtils themeSnackbarUtils
+        final ViewThemeUtils viewThemeUtils
                                          ) {
         updateToAutoUpload();
         cleanOldEntries(clock);
@@ -508,7 +514,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
 
         if (getAppContext() != null) {
             if (PermissionUtil.checkExternalStoragePermission(getAppContext())) {
-                splitOutAutoUploadEntries(clock, themeSnackbarUtils);
+                splitOutAutoUploadEntries(clock, viewThemeUtils);
             } else {
                 preferences.setAutoUploadSplitEntriesEnabled(true);
             }
@@ -731,7 +737,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
     }
 
     private static void splitOutAutoUploadEntries(Clock clock,
-                                                  ThemeSnackbarUtils themeSnackbarUtils) {
+                                                  final ViewThemeUtils viewThemeUtils) {
         Context context = getAppContext();
         AppPreferences preferences = AppPreferencesImpl.fromContext(context);
         if (!preferences.isAutoUploadSplitEntriesEnabled()) {
@@ -746,12 +752,12 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
                                                                                       1,
                                                                                       null,
                                                                                       true,
-                                                                                      themeSnackbarUtils);
+                                                                                      viewThemeUtils);
             final List<MediaFolder> videoMediaFolders = MediaProvider.getVideoFolders(contentResolver,
                                                                                       1,
                                                                                       null,
                                                                                       true,
-                                                                                      themeSnackbarUtils);
+                                                                                      viewThemeUtils);
 
             ArrayList<Long> idsToDelete = new ArrayList<>();
             List<SyncedFolder> syncedFolders = syncedFolderProvider.getSyncedFolders();

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.