Browse Source

Merge pull request #2084 from nextcloud/feature/2076/Material3

🎨 Material 3️⃣
Andy Scherzinger 2 years ago
parent
commit
2bd7688f9c
100 changed files with 1894 additions and 1082 deletions
  1. 1 0
      app/build.gradle
  2. 19 9
      app/src/main/java/com/nextcloud/talk/activities/BaseActivity.kt
  3. 3 2
      app/src/main/java/com/nextcloud/talk/activities/CallActivity.java
  4. 8 5
      app/src/main/java/com/nextcloud/talk/activities/FullScreenTextViewerActivity.kt
  5. 1 1
      app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java
  6. 8 5
      app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java
  7. 39 30
      app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java
  8. 31 13
      app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java
  9. 1 1
      app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java
  10. 49 52
      app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.java
  11. 5 3
      app/src/main/java/com/nextcloud/talk/adapters/items/MessageResultItem.kt
  12. 24 8
      app/src/main/java/com/nextcloud/talk/adapters/items/ParticipantItem.java
  13. 15 27
      app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt
  14. 13 24
      app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt
  15. 15 1
      app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPreviewMessageViewHolder.java
  16. 10 23
      app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt
  17. 22 42
      app/src/main/java/com/nextcloud/talk/adapters/messages/MagicIncomingTextMessageViewHolder.kt
  18. 15 53
      app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt
  19. 15 5
      app/src/main/java/com/nextcloud/talk/adapters/messages/MagicPreviewMessageViewHolder.java
  20. 18 46
      app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt
  21. 17 54
      app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt
  22. 16 1
      app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPreviewMessageViewHolder.java
  23. 18 57
      app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt
  24. 32 18
      app/src/main/java/com/nextcloud/talk/adapters/messages/Reaction.kt
  25. 11 3
      app/src/main/java/com/nextcloud/talk/callbacks/MentionAutocompleteCallback.java
  26. 36 24
      app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
  27. 10 4
      app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt
  28. 30 11
      app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt
  29. 7 21
      app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java
  30. 12 21
      app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt
  31. 40 35
      app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt
  32. 2 2
      app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.kt
  33. 16 10
      app/src/main/java/com/nextcloud/talk/controllers/base/BaseController.java
  34. 20 17
      app/src/main/java/com/nextcloud/talk/controllers/base/NewBaseController.kt
  35. 0 8
      app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt
  36. 2 0
      app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.kt
  37. 1 0
      app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java
  38. 0 4
      app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt
  39. 1 1
      app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionViewHolder.kt
  40. 3 0
      app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultHeaderViewHolder.kt
  41. 4 1
      app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVoterViewHolder.kt
  42. 1 1
      app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt
  43. 10 9
      app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt
  44. 6 0
      app/src/main/java/com/nextcloud/talk/polls/ui/PollLoadingFragment.kt
  45. 14 4
      app/src/main/java/com/nextcloud/talk/polls/ui/PollMainDialogFragment.kt
  46. 16 4
      app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt
  47. 16 4
      app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt
  48. 6 1
      app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java
  49. 11 6
      app/src/main/java/com/nextcloud/talk/remotefilebrowser/activities/RemoteFileBrowserActivity.kt
  50. 5 9
      app/src/main/java/com/nextcloud/talk/shareditems/activities/SharedItemsActivity.kt
  51. 11 0
      app/src/main/java/com/nextcloud/talk/ui/dialog/AttachmentDialog.kt
  52. 7 12
      app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt
  53. 51 32
      app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java
  54. 8 4
      app/src/main/java/com/nextcloud/talk/ui/dialog/ContactsBottomDialog.kt
  55. 7 4
      app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt
  56. 12 2
      app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt
  57. 12 0
      app/src/main/java/com/nextcloud/talk/ui/dialog/ScopeDialog.kt
  58. 10 7
      app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt
  59. 11 4
      app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt
  60. 3 2
      app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java
  61. 35 0
      app/src/main/java/com/nextcloud/talk/ui/theme/MaterialSchemes.kt
  62. 33 0
      app/src/main/java/com/nextcloud/talk/ui/theme/MaterialSchemesImpl.kt
  63. 4 4
      app/src/main/java/com/nextcloud/talk/ui/theme/MaterialSchemesProvider.kt
  64. 9 9
      app/src/main/java/com/nextcloud/talk/ui/theme/MaterialSchemesProviderImpl.kt
  65. 1 4
      app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt
  66. 3 3
      app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt
  67. 567 87
      app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt
  68. 18 17
      app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java
  69. 27 8
      app/src/main/java/com/nextcloud/talk/utils/preferences/MagicUserInputModule.java
  70. 11 0
      app/src/main/java/com/nextcloud/talk/utils/ui/ColorUtil.kt
  71. 43 0
      app/src/main/res/drawable-v24/ic_avatar_background.xml
  72. 31 0
      app/src/main/res/drawable/ic_avatar_document.xml
  73. 31 0
      app/src/main/res/drawable/ic_avatar_group.xml
  74. 31 0
      app/src/main/res/drawable/ic_avatar_link.xml
  75. 31 0
      app/src/main/res/drawable/ic_avatar_mail.xml
  76. 2 2
      app/src/main/res/drawable/reaction_self_background.xml
  77. 3 2
      app/src/main/res/layout/account_item.xml
  78. 0 21
      app/src/main/res/layout/activity_main.xml
  79. 3 2
      app/src/main/res/layout/controller_chat.xml
  80. 43 36
      app/src/main/res/layout/controller_profile.xml
  81. 3 2
      app/src/main/res/layout/current_account_item.xml
  82. 8 14
      app/src/main/res/layout/dialog_choose_account.xml
  83. 1 0
      app/src/main/res/layout/dialog_poll_loading.xml
  84. 2 0
      app/src/main/res/layout/item_custom_incoming_location_message.xml
  85. 2 0
      app/src/main/res/layout/item_custom_incoming_poll_message.xml
  86. 6 4
      app/src/main/res/layout/item_custom_incoming_preview_message.xml
  87. 4 1
      app/src/main/res/layout/item_custom_incoming_text_message.xml
  88. 65 63
      app/src/main/res/layout/item_custom_incoming_voice_message.xml
  89. 5 1
      app/src/main/res/layout/item_custom_outcoming_location_message.xml
  90. 6 6
      app/src/main/res/layout/item_custom_outcoming_poll_message.xml
  91. 6 4
      app/src/main/res/layout/item_custom_outcoming_preview_message.xml
  92. 4 1
      app/src/main/res/layout/item_custom_outcoming_text_message.xml
  93. 10 7
      app/src/main/res/layout/item_custom_outcoming_voice_message.xml
  94. 9 6
      app/src/main/res/layout/item_message_quote.xml
  95. 0 11
      app/src/main/res/layout/search_layout.xml
  96. 5 2
      app/src/main/res/layout/sorting_order_fragment.xml
  97. 2 1
      app/src/main/res/values-night/colors.xml
  98. 2 1
      app/src/main/res/values/colors.xml
  99. 4 2
      app/src/main/res/values/dimens.xml
  100. 17 14
      app/src/main/res/values/styles.xml

+ 1 - 0
app/build.gradle

@@ -335,6 +335,7 @@ dependencies {
     gplayImplementation "com.google.firebase:firebase-messaging:23.0.7"
 
     // implementation 'androidx.activity:activity-ktx:1.4.0'
+    implementation project(':material-color-utilities')
 }
 
 task installGitHooks(type: Copy, group: "development") {

+ 19 - 9
app/src/main/java/com/nextcloud/talk/activities/BaseActivity.kt

@@ -27,15 +27,17 @@ import android.os.Bundle
 import android.util.Log
 import android.view.WindowManager
 import android.webkit.SslErrorHandler
+import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.app.AppCompatActivity
 import autodagger.AutoInjector
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.events.CertificateEvent
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.SecurityUtils
 import com.nextcloud.talk.utils.preferences.AppPreferences
 import com.nextcloud.talk.utils.ssl.MagicTrustManager
-import com.yarolegovich.lovelydialog.LovelyStandardDialog
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
@@ -53,6 +55,9 @@ open class BaseActivity : AppCompatActivity() {
     @Inject
     lateinit var appPreferences: AppPreferences
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     @Inject
     lateinit var context: Context
 
@@ -110,21 +115,26 @@ open class BaseActivity : AppCompatActivity() {
                 issuedBy, issuedFor, validFrom, validUntil
             )
 
-            LovelyStandardDialog(this)
-                .setTopColorRes(R.color.nc_darkRed)
-                .setNegativeButtonColorRes(R.color.nc_darkRed)
-                .setPositiveButtonColorRes(R.color.colorPrimary)
-                .setIcon(R.drawable.ic_security_white_24dp)
+            val dialogBuilder = MaterialAlertDialogBuilder(this)
+                .setIcon(viewThemeUtils.colorMaterialAlertDialogIcon(context, R.drawable.ic_security_white_24dp))
                 .setTitle(R.string.nc_certificate_dialog_title)
                 .setMessage(dialogText)
-                .setPositiveButton(R.string.nc_yes) { v ->
+                .setPositiveButton(R.string.nc_yes) { _, _ ->
                     magicTrustManager.addCertInTrustStore(cert)
                     sslErrorHandler?.proceed()
                 }
-                .setNegativeButton(R.string.nc_no) { view1 ->
+                .setNegativeButton(R.string.nc_no) { _, _ ->
                     sslErrorHandler?.cancel()
                 }
-                .show()
+
+            viewThemeUtils.colorMaterialAlertDialogBackground(context, dialogBuilder)
+
+            val dialog = dialogBuilder.show()
+
+            viewThemeUtils.colorTextButtons(
+                dialog.getButton(AlertDialog.BUTTON_POSITIVE),
+                dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
+            )
         } catch (e: CertificateParsingException) {
             Log.d(TAG, "Failed to parse the certificate")
         }

+ 3 - 2
app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

@@ -880,12 +880,13 @@ public class CallActivity extends CallBaseActivity {
         if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_MICROPHONE)) {
 
             if (!appPreferences.getPushToTalkIntroShown()) {
+                int primary = viewThemeUtils.getScheme(binding.audioOutputButton.getContext()).getPrimary();
                 spotlightView = new SpotlightView.Builder(this)
                     .introAnimationDuration(300)
                     .enableRevealAnimation(true)
                     .performClick(false)
                     .fadeinTextDuration(400)
-                    .headingTvColor(getResources().getColor(R.color.colorPrimary))
+                    .headingTvColor(primary)
                     .headingTvSize(20)
                     .headingTvText(getResources().getString(R.string.nc_push_to_talk))
                     .subHeadingTvColor(getResources().getColor(R.color.bg_default))
@@ -894,7 +895,7 @@ public class CallActivity extends CallBaseActivity {
                     .maskColor(Color.parseColor("#dc000000"))
                     .target(binding.microphoneButton)
                     .lineAnimDuration(400)
-                    .lineAndArcColor(getResources().getColor(R.color.colorPrimary))
+                    .lineAndArcColor(primary)
                     .enableDismissAfterShown(true)
                     .dismissOnBackPress(true)
                     .usageId("pushToTalk")

+ 8 - 5
app/src/main/java/com/nextcloud/talk/activities/FullScreenTextViewerActivity.kt

@@ -34,15 +34,20 @@ import com.nextcloud.talk.BuildConfig
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.databinding.ActivityFullScreenTextBinding
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.Mimetype.TEXT_PREFIX_GENERIC
 import io.noties.markwon.Markwon
 import java.io.File
+import javax.inject.Inject
 
 @AutoInjector(NextcloudTalkApplication::class)
 class FullScreenTextViewerActivity : AppCompatActivity() {
     lateinit var binding: ActivityFullScreenTextBinding
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     private lateinit var path: String
 
     override fun onCreateOptionsMenu(menu: Menu?): Boolean {
@@ -77,6 +82,7 @@ class FullScreenTextViewerActivity : AppCompatActivity() {
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
 
         binding = ActivityFullScreenTextBinding.inflate(layoutInflater)
         setContentView(binding.root)
@@ -98,12 +104,9 @@ class FullScreenTextViewerActivity : AppCompatActivity() {
         supportActionBar?.title = fileName
         supportActionBar?.setDisplayHomeAsUpEnabled(true)
 
-        if (resources != null) {
-            DisplayUtils.applyColorToStatusBar(
-                this,
-                ResourcesCompat.getColor(resources, R.color.appbar, null)
-            )
+        viewThemeUtils.themeStatusBar(this, binding.textviewToolbar)
 
+        if (resources != null) {
             DisplayUtils.applyColorToNavigationBar(
                 this.window,
                 ResourcesCompat.getColor(resources, R.color.bg_default, null)

+ 1 - 1
app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java

@@ -106,7 +106,7 @@ public class TakePhotoActivity extends AppCompatActivity {
         setContentView(binding.getRoot());
 
         viewThemeUtils.themeFAB(binding.takePhoto);
-        viewThemeUtils.colorMaterialButtonBackground(binding.send);
+        viewThemeUtils.colorMaterialButtonPrimaryFilled(binding.send);
 
         cameraProviderFuture = ProcessCameraProvider.getInstance(this);
         cameraProviderFuture.addListener(() -> {

+ 8 - 5
app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java

@@ -30,10 +30,10 @@ import android.view.View;
 import com.facebook.drawee.backends.pipeline.Fresco;
 import com.facebook.drawee.interfaces.DraweeController;
 import com.nextcloud.talk.R;
-import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.data.user.model.User;
 import com.nextcloud.talk.databinding.AccountItemBinding;
 import com.nextcloud.talk.models.json.participants.Participant;
+import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 
@@ -54,11 +54,16 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
     private final User user;
     @Nullable
     private final Account account;
+    private final ViewThemeUtils viewThemeUtils;
 
-    public AdvancedUserItem(Participant participant, User user, @Nullable Account account) {
+    public AdvancedUserItem(Participant participant,
+                            User user,
+                            @Nullable Account account,
+                            ViewThemeUtils viewThemeUtils) {
         this.participant = participant;
         this.user = user;
         this.account = account;
+        this.viewThemeUtils = viewThemeUtils;
     }
 
     @Override
@@ -110,9 +115,7 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
                     holder.binding.userName,
                     participant.getDisplayName(),
                     String.valueOf(adapter.getFilter(String.class)),
-                    NextcloudTalkApplication.Companion.getSharedApplication()
-                            .getResources()
-                            .getColor(R.color.colorPrimary));
+                    viewThemeUtils.getScheme(holder.binding.userName.getContext()).getPrimary());
         } else {
             holder.binding.userName.setText(participant.getDisplayName());
         }

+ 39 - 30
app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java

@@ -25,6 +25,7 @@
 package com.nextcloud.talk.adapters.items;
 
 import android.annotation.SuppressLint;
+import android.os.Build;
 import android.text.TextUtils;
 import android.view.View;
 
@@ -134,19 +135,15 @@ public class ContactItem extends AbstractFlexibleItem<ContactItem.ContactItemVie
             holder.binding.avatarDraweeView.setAlpha(1.0f);
         }
 
+        holder.binding.nameText.setText(participant.getDisplayName());
+
         if (adapter.hasFilter()) {
             FlexibleUtils.highlightText(holder.binding.nameText,
                                         participant.getDisplayName(),
                                         String.valueOf(adapter.getFilter(String.class)),
-                                        NextcloudTalkApplication
-                                            .Companion
-                                            .getSharedApplication()
-                                            .getResources()
-                                            .getColor(R.color.colorPrimary));
+                                        viewThemeUtils.getScheme(holder.binding.nameText.getContext()).getPrimary());
         }
 
-        holder.binding.nameText.setText(participant.getDisplayName());
-
         if (TextUtils.isEmpty(participant.getDisplayName()) &&
             (participant.getType().equals(Participant.ParticipantType.GUEST) ||
                 participant.getType().equals(Participant.ParticipantType.USER_FOLLOWING_LINK))) {
@@ -162,45 +159,57 @@ public class ContactItem extends AbstractFlexibleItem<ContactItem.ContactItemVie
                 participant.getCalculatedActorType() == Participant.ActorType.CIRCLES ||
                 PARTICIPANT_SOURCE_CIRCLES.equals(participant.getSource())) {
 
-            holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_group);
+            setGenericAvatar(holder, R.drawable.ic_avatar_group, R.drawable.ic_circular_group);
 
         } else if (participant.getCalculatedActorType() == Participant.ActorType.EMAILS) {
 
-            holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_mail);
+            setGenericAvatar(holder, R.drawable.ic_avatar_mail, R.drawable.ic_circular_mail);
 
         } else if (
             participant.getCalculatedActorType() == Participant.ActorType.GUESTS ||
                 Participant.ParticipantType.GUEST.equals(participant.getType()) ||
                 Participant.ParticipantType.GUEST_MODERATOR.equals(participant.getType())) {
 
-            String displayName = NextcloudTalkApplication.Companion.getSharedApplication()
-                .getResources().getString(R.string.nc_guest);
+            String displayName;
 
             if (!TextUtils.isEmpty(participant.getDisplayName())) {
                 displayName = participant.getDisplayName();
+            } else {
+                displayName = NextcloudTalkApplication.Companion.getSharedApplication()
+                    .getResources().getString(R.string.nc_guest);
             }
 
-            DraweeController draweeController = Fresco.newDraweeControllerBuilder()
-                .setOldController(holder.binding.avatarDraweeView.getController())
-                .setAutoPlayAnimations(true)
-                .setImageRequest(DisplayUtils.getImageRequestForUrl(
-                    ApiUtils.getUrlForGuestAvatar(user.getBaseUrl(),
-                                                  displayName,
-                                                  false)))
-                .build();
-            holder.binding.avatarDraweeView.setController(draweeController);
-
+            setUserStyleAvatar(holder,
+                               ApiUtils.getUrlForGuestAvatar(user.getBaseUrl(), displayName, false));
         } else if (participant.getCalculatedActorType() == Participant.ActorType.USERS ||
             PARTICIPANT_SOURCE_USERS.equals(participant.getSource())) {
-            DraweeController draweeController = Fresco.newDraweeControllerBuilder()
-                .setOldController(holder.binding.avatarDraweeView.getController())
-                .setAutoPlayAnimations(true)
-                .setImageRequest(DisplayUtils.getImageRequestForUrl(
-                    ApiUtils.getUrlForAvatar(user.getBaseUrl(),
-                                             participant.getCalculatedActorId(),
-                                             false)))
-                .build();
-            holder.binding.avatarDraweeView.setController(draweeController);
+            setUserStyleAvatar(holder,
+                               ApiUtils.getUrlForAvatar(user.getBaseUrl(),
+                                                        participant.getCalculatedActorId(),
+                                                        false));
+        }
+    }
+
+    private void setUserStyleAvatar(ContactItemViewHolder holder, String avatarUrl) {
+        DraweeController draweeController = Fresco.newDraweeControllerBuilder()
+            .setOldController(holder.binding.avatarDraweeView.getController())
+            .setAutoPlayAnimations(true)
+            .setImageRequest(DisplayUtils.getImageRequestForUrl(avatarUrl))
+            .build();
+        holder.binding.avatarDraweeView.setController(draweeController);
+    }
+
+    private void setGenericAvatar(
+        ContactItemViewHolder holder,
+        int roundPlaceholderDrawable,
+        int fallbackImageResource) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            holder.binding.avatarDraweeView.getHierarchy().setPlaceholderImage(
+                DisplayUtils.getRoundedDrawable(
+                    viewThemeUtils.themePlaceholderAvatar(holder.binding.avatarDraweeView,
+                                                          roundPlaceholderDrawable)));
+        } else {
+            holder.binding.avatarDraweeView.setImageResource(fallbackImageResource);
         }
     }
 

+ 31 - 13
app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java

@@ -61,7 +61,6 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
 import eu.davidea.flexibleadapter.items.IFilterable;
 import eu.davidea.flexibleadapter.items.IFlexible;
 import eu.davidea.flexibleadapter.items.ISectionable;
-import eu.davidea.flexibleadapter.utils.FlexibleUtils;
 import eu.davidea.viewholders.FlexibleViewHolder;
 
 public class ConversationItem extends AbstractFlexibleItem<ConversationItem.ConversationItemViewHolder> implements
@@ -144,9 +143,9 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
                                                                         null));
 
         if (adapter.hasFilter()) {
-            FlexibleUtils.highlightText(holder.binding.dialogName, conversation.getDisplayName(),
-                                        String.valueOf(adapter.getFilter(String.class)),
-                                        viewThemeUtils.getElementColor(holder.binding.dialogName.getContext()));
+            viewThemeUtils.highlightText(holder.binding.dialogName,
+                                         conversation.getDisplayName(),
+                                         String.valueOf(adapter.getFilter(String.class)));
         } else {
             holder.binding.dialogName.setText(conversation.getDisplayName());
         }
@@ -264,9 +263,15 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
                     break;
                 case "file":
                     shouldLoadAvatar = false;
-                    holder.binding.dialogAvatar.setImageDrawable(
-                        ContextCompat.getDrawable(context,
-                                                  R.drawable.ic_circular_document));
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                        holder.binding.dialogAvatar.setImageDrawable(
+                            DisplayUtils.getRoundedDrawable(
+                                viewThemeUtils.themePlaceholderAvatar(holder.binding.dialogAvatar,
+                                                                      R.drawable.ic_avatar_document)));
+                    } else {
+                        holder.binding.dialogAvatar.setImageDrawable(
+                            ContextCompat.getDrawable(context, R.drawable.ic_circular_document));
+                    }
                     break;
                 default:
                     break;
@@ -275,6 +280,7 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
 
         if (Conversation.ConversationType.ROOM_SYSTEM.equals(conversation.getType())) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+
                 Drawable[] layers = new Drawable[2];
                 layers[0] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_background);
                 layers[1] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_foreground);
@@ -307,14 +313,26 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
                     }
                     break;
                 case ROOM_GROUP_CALL:
-                    holder.binding.dialogAvatar.setImageDrawable(
-                        ContextCompat.getDrawable(context,
-                                                  R.drawable.ic_circular_group));
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                        holder.binding.dialogAvatar.setImageDrawable(
+                            DisplayUtils.getRoundedDrawable(
+                                viewThemeUtils.themePlaceholderAvatar(holder.binding.dialogAvatar,
+                                                                      R.drawable.ic_avatar_group)));
+                    } else {
+                        holder.binding.dialogAvatar.setImageDrawable(
+                            ContextCompat.getDrawable(context, R.drawable.ic_circular_group));
+                    }
                     break;
                 case ROOM_PUBLIC_CALL:
-                    holder.binding.dialogAvatar.setImageDrawable(
-                        ContextCompat.getDrawable(context,
-                                                  R.drawable.ic_circular_link));
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                        holder.binding.dialogAvatar.setImageDrawable(
+                            DisplayUtils.getRoundedDrawable(
+                                viewThemeUtils.themePlaceholderAvatar(holder.binding.dialogAvatar,
+                                                                      R.drawable.ic_avatar_link)));
+                    } else {
+                        holder.binding.dialogAvatar.setImageDrawable(
+                            ContextCompat.getDrawable(context, R.drawable.ic_circular_link));
+                    }
                     break;
                 default:
                     holder.binding.dialogAvatar.setVisibility(View.GONE);

+ 1 - 1
app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java

@@ -74,7 +74,7 @@ public class GenericTextHeaderItem extends AbstractHeaderItem<GenericTextHeaderI
             Log.d(TAG, "We have payloads, so ignoring!");
         } else {
             holder.binding.titleTextView.setText(title);
-            viewThemeUtils.colorTextViewElement(holder.binding.titleTextView);
+            viewThemeUtils.colorPrimaryTextViewElement(holder.binding.titleTextView);
         }
     }
 

+ 49 - 52
app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.java

@@ -26,21 +26,21 @@ package com.nextcloud.talk.adapters.items;
 
 import android.annotation.SuppressLint;
 import android.content.Context;
+import android.os.Build;
 import android.view.View;
 
 import com.facebook.drawee.backends.pipeline.Fresco;
 import com.facebook.drawee.interfaces.DraweeController;
 import com.nextcloud.talk.R;
-import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.data.user.model.User;
 import com.nextcloud.talk.models.json.mention.Mention;
 import com.nextcloud.talk.models.json.status.StatusType;
 import com.nextcloud.talk.ui.StatusDrawable;
+import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 
 import java.util.List;
-import java.util.Objects;
 import java.util.regex.Pattern;
 
 import androidx.constraintlayout.widget.ConstraintLayout;
@@ -67,11 +67,12 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
     private final String statusMessage;
     private final User currentUser;
     private final Context context;
+    private final ViewThemeUtils viewThemeUtils;
 
     public MentionAutocompleteItem(
         Mention mention,
         User currentUser,
-        Context activityContext) {
+        Context activityContext, ViewThemeUtils viewThemeUtils) {
         this.objectId = mention.getId();
         this.displayName = mention.getLabel();
         this.source = mention.getSource();
@@ -80,6 +81,7 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
         this.statusMessage = mention.getStatusMessage();
         this.currentUser = currentUser;
         this.context = activityContext;
+        this.viewThemeUtils = viewThemeUtils;
     }
 
     public String getSource() {
@@ -133,26 +135,27 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
             FlexibleUtils.highlightText(holder.binding.nameText,
                                         displayName,
                                         String.valueOf(adapter.getFilter(String.class)),
-                                        Objects.requireNonNull(NextcloudTalkApplication
-                                                                   .Companion
-                                                                   .getSharedApplication())
-                                            .getResources().getColor(R.color.colorPrimary));
-            if (holder.binding.secondaryText != null) {
-                FlexibleUtils.highlightText(holder.binding.secondaryText,
-                                            "@" + objectId,
-                                            String.valueOf(adapter.getFilter(String.class)),
-                                            NextcloudTalkApplication.Companion.getSharedApplication()
-                                                .getResources().getColor(R.color.colorPrimary));
-            }
+                                        viewThemeUtils
+                                            .getScheme(holder.binding.secondaryText.getContext())
+                                            .getPrimary());
+            FlexibleUtils.highlightText(holder.binding.secondaryText,
+                                        "@" + objectId,
+                                        String.valueOf(adapter.getFilter(String.class)),
+                                        viewThemeUtils
+                                            .getScheme(holder.binding.secondaryText.getContext())
+                                            .getPrimary());
         } else {
             holder.binding.nameText.setText(displayName);
-            if (holder.binding.secondaryText != null) {
-                holder.binding.secondaryText.setText("@" + objectId);
-            }
+            holder.binding.secondaryText.setText("@" + objectId);
         }
 
         if (SOURCE_CALLS.equals(source)) {
-            if (holder.binding.avatarDraweeView != null) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                holder.binding.avatarDraweeView.getHierarchy().setPlaceholderImage(
+                    DisplayUtils.getRoundedDrawable(
+                        viewThemeUtils.themePlaceholderAvatar(holder.binding.avatarDraweeView,
+                                                              R.drawable.ic_avatar_group)));
+            } else {
                 holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_group);
             }
         } else {
@@ -168,9 +171,7 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
                     false);
             }
 
-            if (holder.binding.avatarDraweeView != null) {
-                holder.binding.avatarDraweeView.setController(null);
-            }
+            holder.binding.avatarDraweeView.setController(null);
 
             DraweeController draweeController = Fresco.newDraweeControllerBuilder()
                 .setOldController(holder.binding.avatarDraweeView.getController())
@@ -184,39 +185,35 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
     }
 
     private void drawStatus(ParticipantItem.ParticipantItemViewHolder holder) {
-        if (holder.binding.conversationInfoStatusMessage != null &&
-            holder.binding.participantStatusEmoji != null &&
-            holder.binding.userStatusImage != null) {
-            float size = DisplayUtils.convertDpToPixel(STATUS_SIZE_IN_DP, context);
-            holder.binding.userStatusImage.setImageDrawable(new StatusDrawable(
-                status,
-                NO_ICON,
-                size,
-                context.getResources().getColor(R.color.bg_default),
-                context));
-
-            if (statusMessage != null) {
-                holder.binding.conversationInfoStatusMessage.setText(statusMessage);
-                alignUsernameVertical(holder, 0);
-            } else {
-                holder.binding.conversationInfoStatusMessage.setText("");
-                alignUsernameVertical(holder, 10);
-            }
+        float size = DisplayUtils.convertDpToPixel(STATUS_SIZE_IN_DP, context);
+        holder.binding.userStatusImage.setImageDrawable(new StatusDrawable(
+            status,
+            NO_ICON,
+            size,
+            context.getResources().getColor(R.color.bg_default),
+            context));
+
+        if (statusMessage != null) {
+            holder.binding.conversationInfoStatusMessage.setText(statusMessage);
+            alignUsernameVertical(holder, 0);
+        } else {
+            holder.binding.conversationInfoStatusMessage.setText("");
+            alignUsernameVertical(holder, 10);
+        }
 
-            if (statusIcon != null && !statusIcon.isEmpty()) {
-                holder.binding.participantStatusEmoji.setText(statusIcon);
-            } else {
-                holder.binding.participantStatusEmoji.setVisibility(View.GONE);
-            }
+        if (statusIcon != null && !statusIcon.isEmpty()) {
+            holder.binding.participantStatusEmoji.setText(statusIcon);
+        } else {
+            holder.binding.participantStatusEmoji.setVisibility(View.GONE);
+        }
 
-            if (status != null && status.equals(StatusType.DND.getString())) {
-                if (statusMessage == null || statusMessage.isEmpty()) {
-                    holder.binding.conversationInfoStatusMessage.setText(R.string.dnd);
-                }
-            } else if (status != null && status.equals(StatusType.AWAY.getString())) {
-                if (statusMessage == null || statusMessage.isEmpty()) {
-                    holder.binding.conversationInfoStatusMessage.setText(R.string.away);
-                }
+        if (status != null && status.equals(StatusType.DND.getString())) {
+            if (statusMessage == null || statusMessage.isEmpty()) {
+                holder.binding.conversationInfoStatusMessage.setText(R.string.dnd);
+            }
+        } else if (status != null && status.equals(StatusType.AWAY.getString())) {
+            if (statusMessage == null || statusMessage.isEmpty()) {
+                holder.binding.conversationInfoStatusMessage.setText(R.string.away);
             }
         }
     }

+ 5 - 3
app/src/main/java/com/nextcloud/talk/adapters/items/MessageResultItem.kt

@@ -77,9 +77,11 @@ data class MessageResultItem constructor(
     }
 
     private fun bindMessageExcerpt(holder: ViewHolder) {
-        val messageSpannable = SpannableString(messageEntry.messageExcerpt)
-        val highlightColor = viewThemeUtils.getElementColor(holder.binding.messageExcerpt.context)
-        val highlightedSpan = DisplayUtils.searchAndColor(messageSpannable, messageEntry.searchTerm, highlightColor)
+        val highlightedSpan = viewThemeUtils.createHighlightedSpan(
+            holder.binding.messageExcerpt.context,
+            SpannableString(messageEntry.messageExcerpt),
+            messageEntry.searchTerm
+        )
         holder.binding.messageExcerpt.text = highlightedSpan
     }
 

+ 24 - 8
app/src/main/java/com/nextcloud/talk/adapters/items/ParticipantItem.java

@@ -27,6 +27,7 @@ package com.nextcloud.talk.adapters.items;
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.Resources;
+import android.os.Build;
 import android.text.TextUtils;
 import android.view.View;
 
@@ -41,6 +42,7 @@ import com.nextcloud.talk.models.json.participants.Participant;
 import com.nextcloud.talk.models.json.participants.Participant.InCallFlags;
 import com.nextcloud.talk.models.json.status.StatusType;
 import com.nextcloud.talk.ui.StatusDrawable;
+import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 
@@ -64,14 +66,16 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
     private final Context context;
     private final Participant participant;
     private final User user;
+    private final ViewThemeUtils viewThemeUtils;
     public boolean isOnline = true;
 
     public ParticipantItem(Context activityContext,
                            Participant participant,
-                           User user) {
+                           User user, ViewThemeUtils viewThemeUtils) {
         this.context = activityContext;
         this.participant = participant;
         this.user = user;
+        this.viewThemeUtils = viewThemeUtils;
     }
 
     public Participant getModel() {
@@ -127,16 +131,14 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
             holder.binding.avatarDraweeView.setAlpha(1.0f);
         }
 
+        holder.binding.nameText.setText(participant.getDisplayName());
+
         if (adapter.hasFilter()) {
             FlexibleUtils.highlightText(holder.binding.nameText, participant.getDisplayName(),
                                         String.valueOf(adapter.getFilter(String.class)),
-                                        NextcloudTalkApplication.Companion.getSharedApplication()
-                                            .getResources()
-                                            .getColor(R.color.colorPrimary));
+                                        viewThemeUtils.getScheme(holder.binding.nameText.getContext()).getPrimary());
         }
 
-        holder.binding.nameText.setText(participant.getDisplayName());
-
         if (TextUtils.isEmpty(participant.getDisplayName()) &&
             (participant.getType().equals(Participant.ParticipantType.GUEST) ||
                 participant.getType().equals(Participant.ParticipantType.USER_FOLLOWING_LINK))) {
@@ -150,9 +152,23 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
             "groups".equals(participant.getSource()) ||
             participant.getCalculatedActorType() == Participant.ActorType.CIRCLES ||
             "circles".equals(participant.getSource())) {
-            holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_group);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                holder.binding.avatarDraweeView.getHierarchy().setPlaceholderImage(
+                    DisplayUtils.getRoundedDrawable(
+                        viewThemeUtils.themePlaceholderAvatar(holder.binding.avatarDraweeView,
+                                                              R.drawable.ic_avatar_group)));
+            } else {
+                holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_group);
+            }
         } else if (participant.getCalculatedActorType() == Participant.ActorType.EMAILS) {
-            holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_mail);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                holder.binding.avatarDraweeView.getHierarchy().setPlaceholderImage(
+                    DisplayUtils.getRoundedDrawable(
+                        viewThemeUtils.themePlaceholderAvatar(holder.binding.avatarDraweeView,
+                                                              R.drawable.ic_avatar_mail)));
+            } else {
+                holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_mail);
+            }
         } else if (participant.getCalculatedActorType() == Participant.ActorType.GUESTS ||
             Participant.ParticipantType.GUEST.equals(participant.getType()) ||
             Participant.ParticipantType.GUEST_MODERATOR.equals(participant.getType())) {

+ 15 - 27
app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt

@@ -41,7 +41,6 @@ import android.webkit.WebView
 import android.webkit.WebViewClient
 import android.widget.Toast
 import androidx.appcompat.content.res.AppCompatResources
-import androidx.core.view.ViewCompat
 import autodagger.AutoInjector
 import coil.load
 import com.amulyakhare.textdrawable.TextDrawable
@@ -50,6 +49,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.databinding.ItemCustomIncomingLocationMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.UriUtils
@@ -69,13 +69,14 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
     var locationName: String? = ""
     var locationGeoLink: String? = ""
 
-    @JvmField
     @Inject
-    var context: Context? = null
+    lateinit var context: Context
 
-    @JvmField
     @Inject
-    var appPreferences: AppPreferences? = null
+    lateinit var appPreferences: AppPreferences
+
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
 
     lateinit var reactionsInterface: ReactionsInterface
 
@@ -89,7 +90,6 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
         colorizeMessageBubble(message)
 
         itemView.isSelected = false
-        binding.messageTime.setTextColor(context?.resources!!.getColor(R.color.warm_grey_four))
 
         val textSize = context?.resources!!.getDimension(R.dimen.chat_text_size)
         binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
@@ -101,7 +101,13 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
         // geo-location
         setLocationDataOnMessageItem(message)
 
-        Reaction().showReactions(message, binding.reactions, binding.messageText.context, false)
+        Reaction().showReactions(
+            message,
+            binding.reactions,
+            binding.messageText.context,
+            false,
+            viewThemeUtils
+        )
         binding.reactions.reactionsEmojiWrapper.setOnClickListener {
             reactionsInterface.onClickReactions(message)
         }
@@ -155,25 +161,7 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
     }
 
     private fun colorizeMessageBubble(message: ChatMessage) {
-        val resources = itemView.resources
-
-        var bubbleResource = R.drawable.shape_incoming_message
-
-        if (message.isGrouped) {
-            bubbleResource = R.drawable.shape_grouped_incoming_message
-        }
-
-        val bgBubbleColor = if (message.isDeleted) {
-            resources.getColor(R.color.bg_message_list_incoming_bubble_deleted)
-        } else {
-            resources.getColor(R.color.bg_message_list_incoming_bubble)
-        }
-        val bubbleDrawable = DisplayUtils.getMessageSelector(
-            bgBubbleColor,
-            resources.getColor(R.color.transparent),
-            bgBubbleColor, bubbleResource
-        )
-        ViewCompat.setBackground(bubble, bubbleDrawable)
+        viewThemeUtils.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
     }
 
     private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
@@ -199,7 +187,7 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
                 .setTextColor(context!!.resources.getColor(R.color.textColorMaxContrast))
 
             if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
-                binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.colorPrimary)
+                viewThemeUtils.colorPrimaryView(binding.messageQuote.quoteColoredView)
             } else {
                 binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
             }

+ 13 - 24
app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt

@@ -29,7 +29,6 @@ import android.text.TextUtils
 import android.view.View
 import androidx.core.content.ContextCompat
 import androidx.core.content.res.ResourcesCompat
-import androidx.core.view.ViewCompat
 import autodagger.AutoInjector
 import coil.load
 import com.amulyakhare.textdrawable.TextDrawable
@@ -41,6 +40,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA
 import com.nextcloud.talk.databinding.ItemCustomIncomingPollMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.polls.ui.PollMainDialogFragment
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.preferences.AppPreferences
@@ -60,6 +60,9 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
     @Inject
     lateinit var appPreferences: AppPreferences
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     @Inject
     lateinit var ncApi: NcApi
 
@@ -78,14 +81,19 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
         colorizeMessageBubble(message)
 
         itemView.isSelected = false
-        binding.messageTime.setTextColor(ResourcesCompat.getColor(context?.resources!!, R.color.warm_grey_four, null))
 
         // parent message handling
         setParentMessageDataOnMessageItem(message)
 
         setPollPreview(message)
 
-        Reaction().showReactions(message, binding.reactions, binding.messageTime.context, false)
+        Reaction().showReactions(
+            message,
+            binding.reactions,
+            binding.messageTime.context,
+            false,
+            viewThemeUtils
+        )
         binding.reactions.reactionsEmojiWrapper.setOnClickListener {
             reactionsInterface.onClickReactions(message)
         }
@@ -183,26 +191,7 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
     }
 
     private fun colorizeMessageBubble(message: ChatMessage) {
-        val resources = itemView.resources
-
-        var bubbleResource = R.drawable.shape_incoming_message
-
-        if (message.isGrouped) {
-            bubbleResource = R.drawable.shape_grouped_incoming_message
-        }
-
-        val bgBubbleColor = if (message.isDeleted) {
-            ResourcesCompat.getColor(resources, R.color.bg_message_list_incoming_bubble_deleted, null)
-        } else {
-            ResourcesCompat.getColor(resources, R.color.bg_message_list_incoming_bubble, null)
-        }
-        val bubbleDrawable = DisplayUtils.getMessageSelector(
-            bgBubbleColor,
-            ResourcesCompat.getColor(resources, R.color.transparent, null),
-            bgBubbleColor,
-            bubbleResource
-        )
-        ViewCompat.setBackground(bubble, bubbleDrawable)
+        viewThemeUtils.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
     }
 
     private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
@@ -228,7 +217,7 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
                 .setTextColor(ContextCompat.getColor(context, R.color.textColorMaxContrast))
 
             if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
-                binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.colorPrimary)
+                viewThemeUtils.colorPrimaryView(binding.messageQuote.quoteColoredView)
             } else {
                 binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
             }

+ 15 - 1
app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPreviewMessageViewHolder.java

@@ -26,9 +26,13 @@ import android.view.View;
 import android.widget.ProgressBar;
 
 import com.facebook.drawee.view.SimpleDraweeView;
+import com.google.android.material.card.MaterialCardView;
+import com.nextcloud.talk.R;
 import com.nextcloud.talk.databinding.ItemCustomIncomingPreviewMessageBinding;
 import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding;
+import com.nextcloud.talk.models.json.chat.ChatMessage;
 
+import androidx.core.content.ContextCompat;
 import androidx.emoji.widget.EmojiTextView;
 
 public class IncomingPreviewMessageViewHolder extends MagicPreviewMessageViewHolder {
@@ -39,6 +43,16 @@ public class IncomingPreviewMessageViewHolder extends MagicPreviewMessageViewHol
         binding = ItemCustomIncomingPreviewMessageBinding.bind(itemView);
     }
 
+    @Override
+    public void onBind(ChatMessage message) {
+        super.onBind(message);
+
+        binding.messageText.setTextColor(ContextCompat.getColor(binding.messageText.getContext(),
+                                                                R.color.no_emphasis_text));
+        binding.messageTime.setTextColor(ContextCompat.getColor(binding.messageText.getContext(),
+                                                                R.color.no_emphasis_text));
+    }
+
     @Override
     public EmojiTextView getMessageText() {
         return binding.messageText;
@@ -60,7 +74,7 @@ public class IncomingPreviewMessageViewHolder extends MagicPreviewMessageViewHol
     }
 
     @Override
-    public View getPreviewContactContainer() {
+    public MaterialCardView getPreviewContactContainer() {
         return binding.contactContainer;
     }
 

+ 10 - 23
app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt

@@ -37,7 +37,6 @@ import android.view.View
 import android.widget.SeekBar
 import androidx.core.content.ContextCompat
 import androidx.core.content.res.ResourcesCompat
-import androidx.core.view.ViewCompat
 import androidx.work.WorkInfo
 import androidx.work.WorkManager
 import autodagger.AutoInjector
@@ -90,7 +89,6 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
         colorizeMessageBubble(message)
 
         itemView.isSelected = false
-        binding.messageTime.setTextColor(ResourcesCompat.getColor(context?.resources!!, R.color.warm_grey_four, null))
 
         // parent message handling
         setParentMessageDataOnMessageItem(message)
@@ -98,6 +96,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
         updateDownloadState(message)
         binding.seekbar.max = message.voiceMessageDuration
         viewThemeUtils.themeHorizontalSeekBar(binding.seekbar)
+        viewThemeUtils.colorCircularProgressBarOnSurfaceVariant(binding.progressBar)
 
         if (message.isPlayingVoiceMessage) {
             showPlayButton()
@@ -146,7 +145,13 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
             }
         })
 
-        Reaction().showReactions(message, binding.reactions, binding.messageTime.context, false)
+        Reaction().showReactions(
+            message,
+            binding.reactions,
+            binding.messageTime.context,
+            false,
+            viewThemeUtils
+        )
         binding.reactions.reactionsEmojiWrapper.setOnClickListener {
             reactionsInterface.onClickReactions(message)
         }
@@ -261,25 +266,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
     }
 
     private fun colorizeMessageBubble(message: ChatMessage) {
-        val resources = itemView.resources
-
-        var bubbleResource = R.drawable.shape_incoming_message
-
-        if (message.isGrouped) {
-            bubbleResource = R.drawable.shape_grouped_incoming_message
-        }
-
-        val bgBubbleColor = if (message.isDeleted) {
-            ResourcesCompat.getColor(resources, R.color.bg_message_list_incoming_bubble_deleted, null)
-        } else {
-            ResourcesCompat.getColor(resources, R.color.bg_message_list_incoming_bubble, null)
-        }
-        val bubbleDrawable = DisplayUtils.getMessageSelector(
-            bgBubbleColor,
-            ResourcesCompat.getColor(resources, R.color.transparent, null),
-            bgBubbleColor, bubbleResource
-        )
-        ViewCompat.setBackground(bubble, bubbleDrawable)
+        viewThemeUtils.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
     }
 
     private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
@@ -305,7 +292,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
                 .setTextColor(ContextCompat.getColor(context!!, R.color.textColorMaxContrast))
 
             if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
-                binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.colorPrimary)
+                viewThemeUtils.colorPrimaryView(binding.messageQuote.quoteColoredView)
             } else {
                 binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
             }

+ 22 - 42
app/src/main/java/com/nextcloud/talk/adapters/messages/MagicIncomingTextMessageViewHolder.kt

@@ -26,7 +26,6 @@ package com.nextcloud.talk.adapters.messages
 
 import android.content.Context
 import android.content.Intent
-import android.content.res.Resources
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.LayerDrawable
 import android.net.Uri
@@ -38,7 +37,6 @@ import android.util.TypedValue
 import android.view.View
 import androidx.core.content.ContextCompat
 import androidx.core.content.res.ResourcesCompat
-import androidx.core.view.ViewCompat
 import autodagger.AutoInjector
 import coil.load
 import com.amulyakhare.textdrawable.TextDrawable
@@ -48,6 +46,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA
 import com.nextcloud.talk.databinding.ItemCustomIncomingTextMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.TextMatchers
@@ -61,13 +60,14 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
 
     private val binding: ItemCustomIncomingTextMessageBinding = ItemCustomIncomingTextMessageBinding.bind(itemView)
 
-    @JvmField
     @Inject
-    var context: Context? = null
+    lateinit var context: Context
 
-    @JvmField
     @Inject
-    var appPreferences: AppPreferences? = null
+    lateinit var viewThemeUtils: ViewThemeUtils
+
+    @Inject
+    lateinit var appPreferences: AppPreferences
 
     lateinit var reactionsInterface: ReactionsInterface
 
@@ -87,12 +87,9 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
             binding.messageAuthor.visibility = View.GONE
         }
 
-        val resources = itemView.resources
-
-        setBubbleOnChatMessage(message, resources)
+        viewThemeUtils.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
 
         itemView.isSelected = false
-        binding.messageTime.setTextColor(ResourcesCompat.getColor(resources, R.color.warm_grey_four, null))
 
         var messageString: Spannable = SpannableString(message.text)
 
@@ -120,7 +117,13 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
 
         itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.replyable)
 
-        Reaction().showReactions(message, binding.reactions, binding.messageText.context, false)
+        Reaction().showReactions(
+            message,
+            binding.reactions,
+            binding.messageText.context,
+            false,
+            viewThemeUtils
+        )
         binding.reactions.reactionsEmojiWrapper.setOnClickListener {
             reactionsInterface.onClickReactions(message)
         }
@@ -141,30 +144,6 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
         }
     }
 
-    private fun setBubbleOnChatMessage(
-        message: ChatMessage,
-        resources: Resources
-    ) {
-        val bgBubbleColor = if (message.isDeleted) {
-            ResourcesCompat.getColor(resources, R.color.bg_message_list_incoming_bubble_deleted, null)
-        } else {
-            ResourcesCompat.getColor(resources, R.color.bg_message_list_incoming_bubble, null)
-        }
-
-        var bubbleResource = R.drawable.shape_incoming_message
-
-        if (message.isGrouped) {
-            bubbleResource = R.drawable.shape_grouped_incoming_message
-        }
-
-        val bubbleDrawable = DisplayUtils.getMessageSelector(
-            bgBubbleColor,
-            ResourcesCompat.getColor(resources, R.color.transparent, null),
-            bgBubbleColor, bubbleResource
-        )
-        ViewCompat.setBackground(bubble, bubbleDrawable)
-    }
-
     private fun processParentMessage(message: ChatMessage) {
         val parentChatMessage = message.parentMessage
         parentChatMessage!!.activeUser = message.activeUser
@@ -183,13 +162,12 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
             context!!.getText(R.string.nc_nick_guest) else parentChatMessage.actorDisplayName
         binding.messageQuote.quotedMessage.text = parentChatMessage.text
 
-        binding.messageQuote.quotedMessageAuthor
-            .setTextColor(ContextCompat.getColor(context!!, R.color.textColorMaxContrast))
-
         if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
-            binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.colorPrimary)
+            viewThemeUtils.colorPrimaryView(binding.messageQuote.quoteColoredView)
         } else {
-            binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
+            binding.messageQuote.quoteColoredView.setBackgroundColor(
+                ContextCompat.getColor(binding.messageQuote.quoteColoredView.context, R.color.high_emphasis_text)
+            )
         }
     }
 
@@ -245,7 +223,8 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
                             individualHashMap["name"]!!,
                             individualHashMap["type"]!!,
                             message.activeUser!!,
-                            R.xml.chip_you
+                            R.xml.chip_you,
+                            viewThemeUtils
                         )
                     } else {
                         messageStringInternal = DisplayUtils.searchAndReplaceWithMentionSpan(
@@ -255,7 +234,8 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
                             individualHashMap["name"]!!,
                             individualHashMap["type"]!!,
                             message.activeUser!!,
-                            R.xml.chip_others
+                            R.xml.chip_others,
+                            viewThemeUtils
                         )
                     }
                 } else if (individualHashMap["type"] == "file") {

+ 15 - 53
app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt

@@ -25,14 +25,13 @@ package com.nextcloud.talk.adapters.messages
 
 import android.content.Context
 import android.content.Intent
+import android.graphics.PorterDuff
 import android.net.Uri
 import android.text.Spannable
 import android.text.SpannableString
 import android.util.TypedValue
 import android.view.View
 import androidx.core.content.res.ResourcesCompat
-import androidx.core.graphics.ColorUtils
-import androidx.core.view.ViewCompat
 import autodagger.AutoInjector
 import coil.load
 import com.google.android.flexbox.FlexboxLayout
@@ -43,15 +42,12 @@ import com.nextcloud.talk.databinding.ItemCustomOutcomingTextMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ReadStatus
 import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
-import com.nextcloud.talk.ui.theme.ServerTheme
 import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
-import com.nextcloud.talk.utils.DisplayUtils.getMessageSelector
 import com.nextcloud.talk.utils.DisplayUtils.searchAndReplaceWithMentionSpan
 import com.nextcloud.talk.utils.TextMatchers
 import com.stfalcon.chatkit.messages.MessageHolders.OutcomingTextMessageViewHolder
 import javax.inject.Inject
-import kotlin.math.roundToInt
 
 @AutoInjector(NextcloudTalkApplication::class)
 class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewHolder<ChatMessage>(itemView) {
@@ -64,9 +60,6 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
     @Inject
     lateinit var viewThemeUtils: ViewThemeUtils
 
-    @Inject
-    lateinit var serverTheme: ServerTheme
-
     lateinit var reactionsInterface: ReactionsInterface
 
     override fun onBind(message: ChatMessage) {
@@ -75,18 +68,16 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
         val messageParameters: HashMap<String?, HashMap<String?, String?>>? = message.messageParameters
         var messageString: Spannable = SpannableString(message.text)
         realView.isSelected = false
-        binding.messageTime.setTextColor(ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_60_INT))
         val layoutParams = binding.messageTime.layoutParams as FlexboxLayout.LayoutParams
         layoutParams.isWrapBefore = false
         var textSize = context!!.resources.getDimension(R.dimen.chat_text_size)
+        val textColor = viewThemeUtils.getScheme(binding.messageText.context).onSurfaceVariant
+        binding.messageTime.setTextColor(textColor)
         if (messageParameters != null && messageParameters.size > 0) {
             messageString = processMessageParameters(messageParameters, message, messageString)
         } else if (TextMatchers.isMessageWithSingleEmoticonOnly(message.text)) {
             textSize = (textSize * TEXT_SIZE_MULTIPLIER).toFloat()
             layoutParams.isWrapBefore = true
-            binding.messageTime.setTextColor(
-                ResourcesCompat.getColor(context!!.resources, R.color.warm_grey_four, null)
-            )
             realView.isSelected = true
         }
 
@@ -94,9 +85,8 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
 
         binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
         binding.messageTime.layoutParams = layoutParams
+        binding.messageText.setTextColor(textColor)
         binding.messageText.text = messageString
-        binding.messageText.setTextColor(serverTheme.colorText)
-        binding.messageText.setLinkTextColor(serverTheme.colorText)
 
         // parent message handling
         if (!message.isDeleted && message.parentMessage != null) {
@@ -121,7 +111,9 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
         readStatusDrawableInt?.let { drawableInt ->
             ResourcesCompat.getDrawable(context!!.resources, drawableInt, null)?.let {
                 binding.checkMark.setImageDrawable(it)
-                viewThemeUtils.colorImageViewText(binding.checkMark)
+                binding.checkMark.setColorFilter(
+                    viewThemeUtils.getScheme(binding.messageText.context).onSurfaceVariant, PorterDuff.Mode.SRC_ATOP
+                )
             }
         }
 
@@ -129,7 +121,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
 
         itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.replyable)
 
-        Reaction().showReactions(message, binding.reactions, context!!, true)
+        Reaction().showReactions(message, binding.reactions, context, true, viewThemeUtils)
         binding.reactions.reactionsEmojiWrapper.setOnClickListener {
             reactionsInterface.onClickReactions(message)
         }
@@ -141,6 +133,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
 
     private fun processParentMessage(message: ChatMessage) {
         val parentChatMessage = message.parentMessage
+        val textColor = viewThemeUtils.getScheme(binding.messageQuote.quotedMessage.context).onSurfaceVariant
         parentChatMessage!!.activeUser = message.activeUser
         parentChatMessage.imageUrl?.let {
             binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
@@ -156,43 +149,14 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
         binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
             ?: context!!.getText(R.string.nc_nick_guest)
         binding.messageQuote.quotedMessage.text = parentChatMessage.text
-        binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText)
-
-        binding.messageQuote.quotedMessageAuthor.setTextColor(
-            ColorUtils.setAlphaComponent(
-                serverTheme.colorText,
-                ALPHA_80_INT
-            )
-        )
 
-        binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText)
+        binding.messageQuote.quotedMessageAuthor.setTextColor(textColor)
+        binding.messageQuote.quotedMessage.setTextColor(textColor)
+        binding.messageQuote.quoteColoredView.setBackgroundColor(textColor)
     }
 
     private fun setBubbleOnChatMessage(message: ChatMessage) {
-        val resources = sharedApplication!!.resources
-        val elementColor = viewThemeUtils.getElementColor(binding.root.context)
-        val bgBubbleColor = if (message.isDeleted) {
-            ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT)
-        } else {
-            elementColor
-        }
-        if (message.isGrouped) {
-            val bubbleDrawable = getMessageSelector(
-                bgBubbleColor,
-                ResourcesCompat.getColor(resources, R.color.transparent, null),
-                bgBubbleColor,
-                R.drawable.shape_grouped_outcoming_message
-            )
-            ViewCompat.setBackground(bubble, bubbleDrawable)
-        } else {
-            val bubbleDrawable = getMessageSelector(
-                bgBubbleColor,
-                ResourcesCompat.getColor(resources, R.color.transparent, null),
-                bgBubbleColor,
-                R.drawable.shape_outcoming_message
-            )
-            ViewCompat.setBackground(bubble, bubbleDrawable)
-        }
+        viewThemeUtils.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
     }
 
     private fun processMessageParameters(
@@ -215,7 +179,8 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
                         individualHashMap["name"]!!,
                         individualHashMap["type"]!!,
                         message.activeUser,
-                        R.xml.chip_others
+                        R.xml.chip_others,
+                        viewThemeUtils
                     )
                 } else if (individualHashMap["type"] == "file") {
                     realView.setOnClickListener { v: View? ->
@@ -234,8 +199,5 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
 
     companion object {
         const val TEXT_SIZE_MULTIPLIER = 2.5
-        private const val HALF_ALPHA_INT: Int = 255 / 2
-        private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt()
-        private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt()
     }
 }

+ 15 - 5
app/src/main/java/com/nextcloud/talk/adapters/messages/MagicPreviewMessageViewHolder.java

@@ -42,6 +42,7 @@ import android.widget.PopupMenu;
 import android.widget.ProgressBar;
 
 import com.facebook.drawee.view.SimpleDraweeView;
+import com.google.android.material.card.MaterialCardView;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.components.filebrowser.models.BrowserFile;
@@ -50,7 +51,7 @@ import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation;
 import com.nextcloud.talk.data.user.model.User;
 import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding;
 import com.nextcloud.talk.models.json.chat.ChatMessage;
-import com.nextcloud.talk.ui.theme.ServerTheme;
+import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.DrawableUtils;
 import com.nextcloud.talk.utils.FileViewerUtils;
@@ -94,7 +95,7 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
     Context context;
 
     @Inject
-    ServerTheme serverTheme;
+    ViewThemeUtils viewThemeUtils;
 
     @Inject
     OkHttpClient okHttpClient;
@@ -149,6 +150,7 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
         }
 
         progressBar = getProgressBar();
+        viewThemeUtils.colorCircularProgressBar(getProgressBar());
         image = getImage();
         clickView = getImage();
         getMessageText().setVisibility(View.VISIBLE);
@@ -165,6 +167,9 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
                 progressBar = getPreviewContactProgressBar();
                 getMessageText().setVisibility(View.INVISIBLE);
                 clickView = getPreviewContactContainer();
+                viewThemeUtils.colorContactChatItemBackground(getPreviewContactContainer());
+                viewThemeUtils.colorContactChatItemName(getPreviewContactName());
+                viewThemeUtils.colorCircularProgressBarOnPrimaryContainer(getPreviewContactProgressBar());
             } else {
                 getPreviewContainer().setVisibility(View.VISIBLE);
                 getPreviewContactContainer().setVisibility(View.GONE);
@@ -184,7 +189,8 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
                 if (drawable != null &&
                     (drawableResourceId == R.drawable.ic_mimetype_folder ||
                     drawableResourceId == R.drawable.ic_mimetype_package_x_generic)) {
-                    drawable.setColorFilter(serverTheme.getPrimaryColor(), PorterDuff.Mode.SRC_ATOP);
+                    drawable.setColorFilter(viewThemeUtils.getScheme(image.getContext()).getPrimary(),
+                                            PorterDuff.Mode.SRC_ATOP);
                 }
 
                 image.getHierarchy().setPlaceholderImage(drawable);
@@ -239,7 +245,11 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
         itemView.setTag(REPLYABLE_VIEW_TAG, message.getReplyable());
 
         reactionsBinding = getReactionsBinding();
-        new Reaction().showReactions(message, reactionsBinding, getMessageText().getContext(), true);
+        new Reaction().showReactions(message,
+                                     reactionsBinding,
+                                     getMessageText().getContext(),
+                                     true,
+                                     viewThemeUtils);
         reactionsBinding.reactionsEmojiWrapper.setOnClickListener(l -> {
             reactionsInterface.onClickReactions(message);
         });
@@ -353,7 +363,7 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
 
     public abstract View getPreviewContainer();
 
-    public abstract View getPreviewContactContainer();
+    public abstract MaterialCardView getPreviewContactContainer();
 
     public abstract SimpleDraweeView getPreviewContactPhoto();
 

+ 18 - 46
app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt

@@ -25,6 +25,7 @@ package com.nextcloud.talk.adapters.messages
 import android.annotation.SuppressLint
 import android.content.Context
 import android.content.Intent
+import android.graphics.PorterDuff
 import android.net.Uri
 import android.util.Log
 import android.util.TypedValue
@@ -34,9 +35,6 @@ import android.webkit.WebView
 import android.webkit.WebViewClient
 import android.widget.Toast
 import androidx.appcompat.content.res.AppCompatResources
-import androidx.core.content.res.ResourcesCompat
-import androidx.core.graphics.ColorUtils
-import androidx.core.view.ViewCompat
 import autodagger.AutoInjector
 import coil.load
 import com.google.android.flexbox.FlexboxLayout
@@ -46,10 +44,8 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA
 import com.nextcloud.talk.databinding.ItemCustomOutcomingLocationMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ReadStatus
-import com.nextcloud.talk.ui.theme.ServerTheme
 import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
-import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.UriUtils
 import com.stfalcon.chatkit.messages.MessageHolders
 import java.net.URLEncoder
@@ -68,22 +64,20 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
     var locationName: String? = ""
     var locationGeoLink: String? = ""
 
-    @JvmField
     @Inject
-    var context: Context? = null
+    lateinit var context: Context
 
     @Inject
     lateinit var viewThemeUtils: ViewThemeUtils
 
-    @Inject
-    lateinit var serverTheme: ServerTheme
-
     lateinit var reactionsInterface: ReactionsInterface
 
     @SuppressLint("SetTextI18n")
     override fun onBind(message: ChatMessage) {
         super.onBind(message)
         sharedApplication!!.componentApplication.inject(this)
+        val textColor = viewThemeUtils.getScheme(binding.messageTime.context).onSurfaceVariant
+        binding.messageTime.setTextColor(textColor)
 
         realView.isSelected = false
         val layoutParams = binding.messageTime.layoutParams as FlexboxLayout.LayoutParams
@@ -94,11 +88,8 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
         colorizeMessageBubble(message)
         binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
         binding.messageTime.layoutParams = layoutParams
-        binding.messageTime.setTextColor(ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_60_INT))
 
         binding.messageText.text = message.text
-        binding.messageText.setTextColor(serverTheme.colorText)
-        binding.messageText.setLinkTextColor(serverTheme.colorText)
 
         // parent message handling
         setParentMessageDataOnMessageItem(message)
@@ -118,7 +109,9 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
         readStatusDrawableInt?.let { drawableInt ->
             AppCompatResources.getDrawable(context!!, drawableInt)?.let {
                 binding.checkMark.setImageDrawable(it)
-                viewThemeUtils.colorImageViewText(binding.checkMark)
+                binding.checkMark.setColorFilter(
+                    viewThemeUtils.getScheme(binding.checkMark.context).onSurfaceVariant, PorterDuff.Mode.SRC_ATOP
+                )
             }
         }
 
@@ -127,7 +120,13 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
         // geo-location
         setLocationDataOnMessageItem(message)
 
-        Reaction().showReactions(message, binding.reactions, binding.messageText.context, true)
+        Reaction().showReactions(
+            message,
+            binding.reactions,
+            binding.messageText.context,
+            true,
+            viewThemeUtils
+        )
         binding.reactions.reactionsEmojiWrapper.setOnClickListener {
             reactionsInterface.onClickReactions(message)
         }
@@ -213,12 +212,9 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
             binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
                 ?: context!!.getText(R.string.nc_nick_guest)
             binding.messageQuote.quotedMessage.text = parentChatMessage.text
-            binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText)
-            binding.messageQuote.quotedMessageAuthor.setTextColor(
-                ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_80_INT)
-            )
-
-            binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText)
+            viewThemeUtils.colorOutgoingQuoteText(binding.messageQuote.quotedMessage)
+            viewThemeUtils.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
+            viewThemeUtils.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
 
             binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
         } else {
@@ -227,30 +223,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
     }
 
     private fun colorizeMessageBubble(message: ChatMessage) {
-        val resources = sharedApplication!!.resources
-        val elementColor = viewThemeUtils.getElementColor(binding.root.context)
-        val bgBubbleColor = if (message.isDeleted) {
-            ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT)
-        } else {
-            elementColor
-        }
-        if (message.isGrouped) {
-            val bubbleDrawable = DisplayUtils.getMessageSelector(
-                bgBubbleColor,
-                ResourcesCompat.getColor(resources, R.color.transparent, null),
-                bgBubbleColor,
-                R.drawable.shape_grouped_outcoming_message
-            )
-            ViewCompat.setBackground(bubble, bubbleDrawable)
-        } else {
-            val bubbleDrawable = DisplayUtils.getMessageSelector(
-                bgBubbleColor,
-                ResourcesCompat.getColor(resources, R.color.transparent, null),
-                bgBubbleColor,
-                R.drawable.shape_outcoming_message
-            )
-            ViewCompat.setBackground(bubble, bubbleDrawable)
-        }
+        viewThemeUtils.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
     }
 
     private fun openGeoLink() {
@@ -277,6 +250,5 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
         private const val TAG = "LocOutMessageView"
         private const val HALF_ALPHA_INT: Int = 255 / 2
         private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt()
-        private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt()
     }
 }

+ 17 - 54
app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt

@@ -23,12 +23,9 @@ package com.nextcloud.talk.adapters.messages
 
 import android.annotation.SuppressLint
 import android.content.Context
-import android.content.res.ColorStateList
+import android.graphics.PorterDuff
 import android.view.View
 import androidx.appcompat.content.res.AppCompatResources
-import androidx.core.content.res.ResourcesCompat
-import androidx.core.graphics.ColorUtils
-import androidx.core.view.ViewCompat
 import autodagger.AutoInjector
 import coil.load
 import com.nextcloud.talk.R
@@ -40,14 +37,11 @@ import com.nextcloud.talk.databinding.ItemCustomOutcomingPollMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ReadStatus
 import com.nextcloud.talk.polls.ui.PollMainDialogFragment
-import com.nextcloud.talk.ui.theme.ServerTheme
 import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
-import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.preferences.AppPreferences
 import com.stfalcon.chatkit.messages.MessageHolders
 import javax.inject.Inject
-import kotlin.math.roundToInt
 
 @AutoInjector(NextcloudTalkApplication::class)
 class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : MessageHolders
@@ -62,9 +56,6 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
     @Inject
     lateinit var viewThemeUtils: ViewThemeUtils
 
-    @Inject
-    lateinit var serverTheme: ServerTheme
-
     @Inject
     lateinit var appPreferences: AppPreferences
 
@@ -80,16 +71,12 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
         super.onBind(message)
         this.message = message
         sharedApplication!!.componentApplication.inject(this)
+        val textColor = viewThemeUtils.getScheme(binding.messageTime.context).onSurfaceVariant
+        binding.messageTime.setTextColor(textColor)
 
         colorizeMessageBubble(message)
 
         itemView.isSelected = false
-        binding.messageTime.setTextColor(
-            ColorUtils.setAlphaComponent(
-                serverTheme.colorText,
-                ALPHA_60_INT
-            )
-        )
 
         // parent message handling
         setParentMessageDataOnMessageItem(message)
@@ -109,7 +96,9 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
         readStatusDrawableInt?.let { drawableInt ->
             AppCompatResources.getDrawable(context, drawableInt)?.let {
                 binding.checkMark.setImageDrawable(it)
-                viewThemeUtils.colorImageViewText(binding.checkMark)
+                binding.checkMark.setColorFilter(
+                    viewThemeUtils.getScheme(binding.checkMark.context).onSurfaceVariant, PorterDuff.Mode.SRC_ATOP
+                )
             }
         }
 
@@ -117,7 +106,13 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
 
         setPollPreview(message)
 
-        Reaction().showReactions(message, binding.reactions, binding.messageTime.context, true)
+        Reaction().showReactions(
+            message,
+            binding.reactions,
+            binding.messageTime.context,
+            true,
+            viewThemeUtils
+        )
         binding.reactions.reactionsEmojiWrapper.setOnClickListener {
             reactionsInterface.onClickReactions(message)
         }
@@ -142,9 +137,6 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
         }
 
         if (pollId != null && pollName != null) {
-            binding.messagePollTitle.setTextColor(serverTheme.colorText)
-            binding.messagePollSubtitle.setTextColor(serverTheme.colorText)
-            binding.messagePollIcon.imageTintList = ColorStateList.valueOf(serverTheme.colorText)
             binding.messagePollTitle.text = pollName
 
             val roomToken = (payload as? MessagePayload)!!.roomToken
@@ -184,12 +176,9 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
             binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
                 ?: context.getText(R.string.nc_nick_guest)
             binding.messageQuote.quotedMessage.text = parentChatMessage.text
-            binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText)
-            binding.messageQuote.quotedMessageAuthor.setTextColor(
-                ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_80_INT)
-            )
-
-            binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText)
+            viewThemeUtils.colorOutgoingQuoteText(binding.messageQuote.quotedMessage)
+            viewThemeUtils.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
+            viewThemeUtils.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
 
             binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
         } else {
@@ -198,30 +187,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
     }
 
     private fun colorizeMessageBubble(message: ChatMessage) {
-        val resources = sharedApplication!!.resources
-        val elementColor = viewThemeUtils.getElementColor(binding.root.context)
-        val bgBubbleColor = if (message.isDeleted) {
-            ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT)
-        } else {
-            elementColor
-        }
-        if (message.isGrouped) {
-            val bubbleDrawable = DisplayUtils.getMessageSelector(
-                bgBubbleColor,
-                ResourcesCompat.getColor(resources, R.color.transparent, null),
-                bgBubbleColor,
-                R.drawable.shape_grouped_outcoming_message
-            )
-            ViewCompat.setBackground(bubble, bubbleDrawable)
-        } else {
-            val bubbleDrawable = DisplayUtils.getMessageSelector(
-                bgBubbleColor,
-                ResourcesCompat.getColor(resources, R.color.transparent, null),
-                bgBubbleColor,
-                R.drawable.shape_outcoming_message
-            )
-            ViewCompat.setBackground(bubble, bubbleDrawable)
-        }
+        viewThemeUtils.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
     }
 
     fun assignReactionInterface(reactionsInterface: ReactionsInterface) {
@@ -230,8 +196,5 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
 
     companion object {
         private val TAG = NextcloudTalkApplication::class.java.simpleName
-        private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt()
-        private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt()
-        private const val HALF_ALPHA_INT: Int = 255 / 2
     }
 }

+ 16 - 1
app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPreviewMessageViewHolder.java

@@ -26,12 +26,17 @@ import android.view.View;
 import android.widget.ProgressBar;
 
 import com.facebook.drawee.view.SimpleDraweeView;
+import com.google.android.material.card.MaterialCardView;
+import com.nextcloud.talk.R;
 import com.nextcloud.talk.databinding.ItemCustomOutcomingPreviewMessageBinding;
 import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding;
+import com.nextcloud.talk.models.json.chat.ChatMessage;
 
+import androidx.core.content.ContextCompat;
 import androidx.emoji.widget.EmojiTextView;
 
 public class OutcomingPreviewMessageViewHolder extends MagicPreviewMessageViewHolder {
+
     private final ItemCustomOutcomingPreviewMessageBinding binding;
 
     public OutcomingPreviewMessageViewHolder(View itemView) {
@@ -39,6 +44,16 @@ public class OutcomingPreviewMessageViewHolder extends MagicPreviewMessageViewHo
         binding = ItemCustomOutcomingPreviewMessageBinding.bind(itemView);
     }
 
+    @Override
+    public void onBind(ChatMessage message) {
+        super.onBind(message);
+
+        binding.messageText.setTextColor(ContextCompat.getColor(binding.messageText.getContext(),
+                                                                R.color.no_emphasis_text));
+        binding.messageTime.setTextColor(ContextCompat.getColor(binding.messageText.getContext(),
+                                                                R.color.no_emphasis_text));
+    }
+
     @Override
     public EmojiTextView getMessageText() {
         return binding.messageText;
@@ -60,7 +75,7 @@ public class OutcomingPreviewMessageViewHolder extends MagicPreviewMessageViewHo
     }
 
     @Override
-    public View getPreviewContactContainer() {
+    public MaterialCardView getPreviewContactContainer() {
         return binding.contactContainer;
     }
 

+ 18 - 57
app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt

@@ -31,9 +31,6 @@ import android.view.View
 import android.widget.SeekBar
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.core.content.ContextCompat
-import androidx.core.content.res.ResourcesCompat
-import androidx.core.graphics.ColorUtils
-import androidx.core.view.ViewCompat
 import androidx.work.WorkInfo
 import androidx.work.WorkManager
 import autodagger.AutoInjector
@@ -44,15 +41,12 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA
 import com.nextcloud.talk.databinding.ItemCustomOutcomingVoiceMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ReadStatus
-import com.nextcloud.talk.ui.theme.ServerTheme
 import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
-import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.preferences.AppPreferences
 import com.stfalcon.chatkit.messages.MessageHolders
 import java.util.concurrent.ExecutionException
 import javax.inject.Inject
-import kotlin.math.roundToInt
 
 @AutoInjector(NextcloudTalkApplication::class)
 class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
@@ -68,9 +62,6 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
     @Inject
     lateinit var viewThemeUtils: ViewThemeUtils
 
-    @Inject
-    lateinit var serverTheme: ServerTheme
-
     @JvmField
     @Inject
     var appPreferences: AppPreferences? = null
@@ -87,23 +78,20 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
         super.onBind(message)
         this.message = message
         sharedApplication!!.componentApplication.inject(this)
+        val textColor = viewThemeUtils.getScheme(binding.messageTime.context).onSurfaceVariant
+        binding.messageTime.setTextColor(textColor)
 
         colorizeMessageBubble(message)
 
         itemView.isSelected = false
-        binding.messageTime.setTextColor(
-            ColorUtils.setAlphaComponent(
-                serverTheme.colorText,
-                ALPHA_60_INT
-            )
-        )
 
         // parent message handling
         setParentMessageDataOnMessageItem(message)
 
         updateDownloadState(message)
         binding.seekbar.max = message.voiceMessageDuration
-        viewThemeUtils.themeHorizontalSeekBar(binding.seekbar, serverTheme.colorText)
+        viewThemeUtils.themeHorizontalSeekBar(binding.seekbar)
+        viewThemeUtils.colorCircularProgressBarOnSurfaceVariant(binding.progressBar)
 
         handleIsPlayingVoiceMessageState(message)
 
@@ -142,13 +130,21 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
         readStatusDrawableInt?.let { drawableInt ->
             AppCompatResources.getDrawable(context!!, drawableInt)?.let {
                 binding.checkMark.setImageDrawable(it)
-                viewThemeUtils.colorImageViewText(binding.checkMark)
+                binding.checkMark.setColorFilter(
+                    viewThemeUtils.getScheme(binding.checkMark.context).onSurfaceVariant, PorterDuff.Mode.SRC_ATOP
+                )
             }
         }
 
         binding.checkMark.setContentDescription(readStatusContentDescriptionString)
 
-        Reaction().showReactions(message, binding.reactions, binding.messageTime.context, true)
+        Reaction().showReactions(
+            message,
+            binding.reactions,
+            binding.messageTime.context,
+            true,
+            viewThemeUtils
+        )
         binding.reactions.reactionsEmojiWrapper.setOnClickListener {
             reactionsInterface.onClickReactions(message)
         }
@@ -165,7 +161,6 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
                 context!!,
                 R.drawable.ic_baseline_play_arrow_voice_message_24
             )
-            binding.playPauseBtn.icon.setColorFilter(serverTheme.colorText, PorterDuff.Mode.SRC_ATOP)
             binding.seekbar.progress = SEEKBAR_START
             message.resetVoiceMessage = false
         }
@@ -186,7 +181,6 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
                 context!!,
                 R.drawable.ic_baseline_pause_voice_message_24
             )
-            binding.playPauseBtn.icon.setColorFilter(serverTheme.colorText, PorterDuff.Mode.SRC_ATOP)
             binding.seekbar.progress = message.voiceMessagePlayedSeconds
         } else {
             binding.playPauseBtn.visibility = View.VISIBLE
@@ -194,7 +188,6 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
                 context!!,
                 R.drawable.ic_baseline_play_arrow_voice_message_24
             )
-            binding.playPauseBtn.icon.setColorFilter(serverTheme.colorText, PorterDuff.Mode.SRC_ATOP)
         }
     }
 
@@ -270,15 +263,9 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
             binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
                 ?: context!!.getText(R.string.nc_nick_guest)
             binding.messageQuote.quotedMessage.text = parentChatMessage.text
-            binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText)
-            binding.messageQuote.quotedMessageAuthor.setTextColor(
-                ColorUtils.setAlphaComponent(
-                    serverTheme.colorText,
-                    ALPHA_80_INT
-                )
-            )
-
-            binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText)
+            viewThemeUtils.colorOutgoingQuoteText(binding.messageQuote.quotedMessage)
+            viewThemeUtils.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
+            viewThemeUtils.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
 
             binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
         } else {
@@ -287,30 +274,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
     }
 
     private fun colorizeMessageBubble(message: ChatMessage) {
-        val resources = sharedApplication!!.resources
-        val elementColor = viewThemeUtils.getElementColor(binding.root.context)
-        val bgBubbleColor = if (message.isDeleted) {
-            ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT)
-        } else {
-            elementColor
-        }
-        if (message.isGrouped) {
-            val bubbleDrawable = DisplayUtils.getMessageSelector(
-                bgBubbleColor,
-                ResourcesCompat.getColor(resources, R.color.transparent, null),
-                bgBubbleColor,
-                R.drawable.shape_grouped_outcoming_message
-            )
-            ViewCompat.setBackground(bubble, bubbleDrawable)
-        } else {
-            val bubbleDrawable = DisplayUtils.getMessageSelector(
-                bgBubbleColor,
-                ResourcesCompat.getColor(resources, R.color.transparent, null),
-                bgBubbleColor,
-                R.drawable.shape_outcoming_message
-            )
-            ViewCompat.setBackground(bubble, bubbleDrawable)
-        }
+        viewThemeUtils.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
     }
 
     fun assignVoiceMessageInterface(voiceMessageInterface: VoiceMessageInterface) {
@@ -324,8 +288,5 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
     companion object {
         private const val TAG = "VoiceOutMessageView"
         private const val SEEKBAR_START: Int = 0
-        private const val HALF_ALPHA_INT: Int = 255 / 2
-        private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt()
-        private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt()
     }
 }

+ 32 - 18
app/src/main/java/com/nextcloud/talk/adapters/messages/Reaction.kt

@@ -27,11 +27,11 @@ import android.content.Context
 import android.view.ViewGroup
 import android.widget.LinearLayout
 import android.widget.TextView
-import androidx.appcompat.content.res.AppCompatResources
 import androidx.core.content.ContextCompat
 import com.nextcloud.talk.R
 import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.vanniktech.emoji.EmojiTextView
 
@@ -41,7 +41,8 @@ class Reaction {
         message: ChatMessage,
         binding: ReactionsInsideMessageBinding,
         context: Context,
-        isOutgoingMessage: Boolean
+        isOutgoingMessage: Boolean,
+        viewThemeUtils: ViewThemeUtils
     ) {
         binding.reactionsEmojiWrapper.removeAllViews()
         if (message.reactions != null && message.reactions!!.isNotEmpty()) {
@@ -49,7 +50,6 @@ class Reaction {
             var remainingEmojisToDisplay = MAX_EMOJIS_TO_DISPLAY
             val showInfoAboutMoreEmojis = message.reactions!!.size > MAX_EMOJIS_TO_DISPLAY
 
-            val textColor = getTextColor(context, isOutgoingMessage, binding)
             val amountParams = getAmountLayoutParams(context)
             val wrapperParams = getWrapperLayoutParams(context)
 
@@ -58,9 +58,12 @@ class Reaction {
             val paddingBottom = DisplayUtils.convertDpToPixel(WRAPPER_PADDING_BOTTOM, context).toInt()
 
             for ((emoji, amount) in message.reactions!!) {
+                val isSelfReaction = message.reactionsSelf != null &&
+                    message.reactionsSelf!!.isNotEmpty() &&
+                    message.reactionsSelf!!.contains(emoji)
+                val textColor = getTextColor(isOutgoingMessage, isSelfReaction, binding, viewThemeUtils)
                 val emojiWithAmountWrapper = getEmojiWithAmountWrapperLayout(
-                    context,
-                    message,
+                    binding.reactionsEmojiWrapper.context,
                     emoji,
                     amount,
                     EmojiWithAmountWrapperLayoutInfo(
@@ -69,7 +72,10 @@ class Reaction {
                         wrapperParams,
                         paddingSide,
                         paddingTop,
-                        paddingBottom
+                        paddingBottom,
+                        viewThemeUtils,
+                        isOutgoingMessage,
+                        isSelfReaction
                     ),
                 )
 
@@ -86,7 +92,6 @@ class Reaction {
 
     private fun getEmojiWithAmountWrapperLayout(
         context: Context,
-        message: ChatMessage,
         emoji: String,
         amount: Int,
         layoutInfo: EmojiWithAmountWrapperLayoutInfo
@@ -98,12 +103,17 @@ class Reaction {
         emojiWithAmountWrapper.addView(getReactionCount(context, layoutInfo.textColor, amount, layoutInfo.amountParams))
         emojiWithAmountWrapper.layoutParams = layoutInfo.wrapperParams
 
-        if (message.reactionsSelf != null &&
-            message.reactionsSelf!!.isNotEmpty() &&
-            message.reactionsSelf!!.contains(emoji)
-        ) {
-            emojiWithAmountWrapper.background =
-                AppCompatResources.getDrawable(context, R.drawable.reaction_self_background)
+        if (layoutInfo.isSelfReaction) {
+            val color = if (layoutInfo.isOutgoingMessage) {
+                ContextCompat.getColor(
+                    emojiWithAmountWrapper.context,
+                    R.color.bg_message_list_incoming_bubble
+                )
+            } else {
+                layoutInfo.viewThemeUtils.getScheme(emojiWithAmountWrapper.context).primaryContainer
+            }
+            layoutInfo.viewThemeUtils.setCheckedBackground(emojiWithAmountWrapper, color)
+
             emojiWithAmountWrapper.setPaddingRelative(
                 layoutInfo.paddingSide,
                 layoutInfo.paddingTop,
@@ -166,12 +176,13 @@ class Reaction {
     }
 
     private fun getTextColor(
-        context: Context,
         isOutgoingMessage: Boolean,
-        binding: ReactionsInsideMessageBinding
+        isSelfReaction: Boolean,
+        binding: ReactionsInsideMessageBinding,
+        viewThemeUtils: ViewThemeUtils
     ): Int {
-        var textColor = ContextCompat.getColor(context, R.color.white)
-        if (!isOutgoingMessage) {
+        var textColor = viewThemeUtils.getScheme(binding.root.context).onSurfaceVariant
+        if (!isOutgoingMessage || isSelfReaction) {
             textColor = ContextCompat.getColor(binding.root.context, R.color.high_emphasis_text)
         }
         return textColor
@@ -183,7 +194,10 @@ class Reaction {
         val wrapperParams: LinearLayout.LayoutParams,
         val paddingSide: Int,
         val paddingTop: Int,
-        val paddingBottom: Int
+        val paddingBottom: Int,
+        val viewThemeUtils: ViewThemeUtils,
+        val isOutgoingMessage: Boolean,
+        val isSelfReaction: Boolean
     )
 
     companion object {

+ 11 - 3
app/src/main/java/com/nextcloud/talk/callbacks/MentionAutocompleteCallback.java

@@ -31,6 +31,7 @@ import com.facebook.widget.text.span.BetterImageSpan;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.data.user.model.User;
 import com.nextcloud.talk.models.json.mention.Mention;
+import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.MagicCharPolicy;
 import com.nextcloud.talk.utils.text.Spans;
@@ -39,15 +40,19 @@ import com.vanniktech.emoji.EmojiRange;
 import com.vanniktech.emoji.Emojis;
 
 public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
+    private final ViewThemeUtils viewThemeUtils;
     private Context context;
     private User conversationUser;
     private EditText editText;
 
-    public MentionAutocompleteCallback(Context context, User conversationUser,
-                                       EditText editText) {
+    public MentionAutocompleteCallback(Context context,
+                                       User conversationUser,
+                                       EditText editText,
+                                       ViewThemeUtils viewThemeUtils) {
         this.context = context;
         this.conversationUser = conversationUser;
         this.editText = editText;
+        this.viewThemeUtils = viewThemeUtils;
     }
 
     @Override
@@ -73,11 +78,14 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
                                                                                  conversationUser,
                                                                                  item.getSource(),
                                                                                  R.xml.chip_you,
-                                                                                 editText),
+                                                                                 editText,
+                                                                                 viewThemeUtils),
                                       BetterImageSpan.ALIGN_CENTER,
                                       item.getId(), item.getLabel());
         editable.setSpan(mentionChipSpan, start, start + replacementStringBuilder.toString().length(),
                          Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+
         return true;
     }
 

+ 36 - 24
app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt

@@ -35,11 +35,9 @@ import android.content.Context
 import android.content.Intent
 import android.content.pm.PackageManager
 import android.content.res.AssetFileDescriptor
-import android.content.res.ColorStateList
 import android.content.res.Resources
 import android.database.Cursor
 import android.graphics.Bitmap
-import android.graphics.Color
 import android.graphics.drawable.ColorDrawable
 import android.media.MediaPlayer
 import android.media.MediaRecorder
@@ -74,6 +72,7 @@ import android.widget.ImageView
 import android.widget.PopupMenu
 import android.widget.RelativeLayout
 import android.widget.Toast
+import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.view.ContextThemeWrapper
 import androidx.core.content.ContextCompat
 import androidx.core.content.FileProvider
@@ -100,6 +99,7 @@ import com.facebook.drawee.backends.pipeline.Fresco
 import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
 import com.facebook.imagepipeline.image.CloseableImage
 import com.google.android.flexbox.FlexboxLayout
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.nextcloud.talk.BuildConfig
 import com.nextcloud.talk.R
 import com.nextcloud.talk.activities.CallActivity
@@ -154,8 +154,6 @@ import com.nextcloud.talk.ui.dialog.MessageActionsDialog
 import com.nextcloud.talk.ui.dialog.ShowReactionsDialog
 import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions
 import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
-import com.nextcloud.talk.ui.theme.ServerTheme
-import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.AttendeePermissionsUtil
 import com.nextcloud.talk.utils.ConductorRemapping
@@ -190,7 +188,6 @@ import com.stfalcon.chatkit.messages.MessageHolders.ContentChecker
 import com.stfalcon.chatkit.messages.MessagesListAdapter
 import com.stfalcon.chatkit.utils.DateFormatter
 import com.vanniktech.emoji.EmojiPopup
-import com.yarolegovich.lovelydialog.LovelyStandardDialog
 import io.reactivex.Observer
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
@@ -237,12 +234,6 @@ class ChatController(args: Bundle) :
     @Inject
     lateinit var permissionUtil: PlatformPermissionUtil
 
-    @Inject
-    lateinit var viewThemeUtils: ViewThemeUtils
-
-    @Inject
-    lateinit var serverTheme: ServerTheme
-
     val disposables = DisposableSet()
 
     var roomToken: String? = null
@@ -655,8 +646,7 @@ class ChatController(args: Bundle) :
             }
         }
 
-        binding.popupBubbleView.setTextColor(Color.WHITE)
-        binding.popupBubbleView.setIconTint(ColorStateList.valueOf(Color.WHITE))
+        viewThemeUtils.colorMaterialButtonPrimaryFilled(binding.popupBubbleView)
 
         binding.messageInputView.setPadding(0, 0, 0, 0)
 
@@ -1415,28 +1405,38 @@ class ChatController(args: Bundle) :
 
                     val confirmationQuestion = when (filesToUpload.size) {
                         1 -> context?.resources?.getString(R.string.nc_upload_confirm_send_single)?.let {
-                            String.format(it, title)
+                            String.format(it, title.trim())
                         }
                         else -> context?.resources?.getString(R.string.nc_upload_confirm_send_multiple)?.let {
-                            String.format(it, title)
+                            String.format(it, title.trim())
                         }
                     }
 
-                    LovelyStandardDialog(activity)
-                        .setPositiveButtonColorRes(R.color.nc_darkGreen)
+                    val materialAlertDialogBuilder = MaterialAlertDialogBuilder(binding.messageInputView.context)
                         .setTitle(confirmationQuestion)
                         .setMessage(filenamesWithLinebreaks.toString())
-                        .setPositiveButton(R.string.nc_yes) { v ->
-                            if (UploadAndShareFilesWorker.isStoragePermissionGranted(context!!)) {
+                        .setPositiveButton(R.string.nc_yes) { _, _ ->
+                            if (UploadAndShareFilesWorker.isStoragePermissionGranted(context)) {
                                 uploadFiles(filesToUpload, false)
                             } else {
                                 UploadAndShareFilesWorker.requestStoragePermission(this)
                             }
                         }
-                        .setNegativeButton(R.string.nc_no) {
+                        .setNegativeButton(R.string.nc_no) { _, _ ->
                             // unused atm
                         }
-                        .show()
+
+                    viewThemeUtils.colorMaterialAlertDialogBackground(
+                        binding.messageInputView.context,
+                        materialAlertDialogBuilder
+                    )
+
+                    val dialog = materialAlertDialogBuilder.show()
+
+                    viewThemeUtils.colorTextButtons(
+                        dialog.getButton(AlertDialog.BUTTON_POSITIVE),
+                        dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
+                    )
                 } catch (e: IllegalStateException) {
                     Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG)
                         .show()
@@ -1683,7 +1683,8 @@ class ChatController(args: Bundle) :
                 val callback = MentionAutocompleteCallback(
                     activity,
                     conversationUser!!,
-                    binding.messageInputView.inputEditText
+                    binding.messageInputView.inputEditText,
+                    viewThemeUtils
                 )
 
                 if (mentionAutocomplete == null && binding.messageInputView.inputEditText != null) {
@@ -1764,6 +1765,8 @@ class ChatController(args: Bundle) :
             cancelReply()
         }
 
+        viewThemeUtils.themeImageButton(binding.messageInputView.findViewById<ImageButton>(R.id.cancelReplyButton))
+
         cancelNotificationsForCurrentConversation()
 
         Log.d(TAG, "onAttach inConversation: " + inConversation.toString())
@@ -2487,6 +2490,16 @@ class ChatController(args: Bundle) :
         super.onCreateOptionsMenu(menu, inflater)
         inflater.inflate(R.menu.menu_conversation, menu)
 
+        viewThemeUtils.colorToolbarMenuIcon(
+            binding.messageInputView.context,
+            menu.findItem(R.id.conversation_voice_call)
+        )
+
+        viewThemeUtils.colorToolbarMenuIcon(
+            binding.messageInputView.context,
+            menu.findItem(R.id.conversation_video_call)
+        )
+
         if (conversationUser?.userId == "?") {
             menu.removeItem(R.id.conversation_info)
         } else {
@@ -2685,8 +2698,7 @@ class ChatController(args: Bundle) :
                 chatMessage,
                 conversationUser,
                 hasChatPermission,
-                ncApi!!,
-                serverTheme
+                ncApi
             ).show()
         }
     }

+ 10 - 4
app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt

@@ -65,7 +65,6 @@ import com.nextcloud.talk.models.json.converters.EnumActorTypeConverter
 import com.nextcloud.talk.models.json.participants.Participant
 import com.nextcloud.talk.ui.dialog.ContactsBottomDialog
 import com.nextcloud.talk.users.UserManager
-import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.ConductorRemapping
 import com.nextcloud.talk.utils.bundle.BundleKeys
@@ -104,9 +103,6 @@ class ContactsController(args: Bundle) :
     @Inject
     lateinit var ncApi: NcApi
 
-    @Inject
-    lateinit var viewThemeUtils: ViewThemeUtils
-
     private var credentials: String? = null
     private var currentUser: User? = null
     private var contactsQueryDisposable: Disposable? = null
@@ -338,6 +334,7 @@ class ContactsController(args: Bundle) :
             val searchManager: SearchManager? = activity?.getSystemService(Context.SEARCH_SERVICE) as SearchManager?
             if (searchItem != null) {
                 searchView = MenuItemCompat.getActionView(searchItem) as SearchView
+                viewThemeUtils.themeSearchView(searchView!!)
                 searchView!!.maxWidth = Int.MAX_VALUE
                 searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
                 var imeOptions: Int = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
@@ -381,6 +378,14 @@ class ContactsController(args: Bundle) :
 
     override fun onPrepareOptionsMenu(menu: Menu) {
         super.onPrepareOptionsMenu(menu)
+
+        if (searchItem != null) {
+            viewThemeUtils.colorToolbarMenuIcon(
+                binding.titleTextView.context,
+                searchItem!!
+            )
+        }
+
         checkAndHandleDoneMenuItem()
         if (adapter?.hasFilter() == true) {
             searchItem!!.expandActionView()
@@ -632,6 +637,7 @@ class ContactsController(args: Bundle) :
                 ResourcesCompat.getColor(resources!!, R.color.colorBackgroundDarker, null),
                 PorterDuff.Mode.SRC_IN
             )
+
         viewThemeUtils.colorImageViewButton(binding.conversationPrivacyToggle.publicCallLink)
         disengageProgressBar()
     }

+ 30 - 11
app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt

@@ -30,6 +30,7 @@ import android.annotation.SuppressLint
 import android.content.Intent
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.LayerDrawable
+import android.os.Build
 import android.os.Bundle
 import android.os.Parcelable
 import android.text.TextUtils
@@ -73,7 +74,6 @@ import com.nextcloud.talk.models.json.participants.Participant.ActorType.GROUPS
 import com.nextcloud.talk.models.json.participants.Participant.ActorType.USERS
 import com.nextcloud.talk.models.json.participants.ParticipantsOverall
 import com.nextcloud.talk.shareditems.activities.SharedItemsActivity
-import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DateConstants
 import com.nextcloud.talk.utils.DateUtils
@@ -113,9 +113,6 @@ class ConversationInfoController(args: Bundle) :
     @Inject
     lateinit var eventBus: EventBus
 
-    @Inject
-    lateinit var viewThemeUtils: ViewThemeUtils
-
     private val conversationToken: String?
     private val conversationUser: User?
     private val hasAvatarSpacing: Boolean
@@ -234,6 +231,8 @@ class ConversationInfoController(args: Bundle) :
         }
 
         binding.addParticipantsAction.visibility = View.GONE
+
+        viewThemeUtils.colorCircularProgressBar(binding.progressBar)
     }
 
     private fun setupWebinaryView() {
@@ -437,7 +436,7 @@ class ConversationInfoController(args: Bundle) :
 
         for (i in participants.indices) {
             participant = participants[i]
-            userItem = ParticipantItem(router.activity, participant, conversationUser)
+            userItem = ParticipantItem(router.activity, participant, conversationUser, viewThemeUtils)
             if (participant.sessionId != null) {
                 userItem.isOnline = !participant.sessionId.equals("0")
             } else {
@@ -789,12 +788,32 @@ class ConversationInfoController(args: Bundle) :
                     .build()
                 binding.avatarImage.controller = draweeController
             }
-            Conversation.ConversationType.ROOM_GROUP_CALL -> binding.avatarImage.hierarchy.setPlaceholderImage(
-                R.drawable.ic_circular_group
-            )
-            Conversation.ConversationType.ROOM_PUBLIC_CALL -> binding.avatarImage.hierarchy.setPlaceholderImage(
-                R.drawable.ic_circular_link
-            )
+            Conversation.ConversationType.ROOM_GROUP_CALL -> {
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                    binding.avatarImage.hierarchy.setPlaceholderImage(
+                        DisplayUtils.getRoundedDrawable(
+                            viewThemeUtils.themePlaceholderAvatar(binding.avatarImage, R.drawable.ic_avatar_group)
+                        )
+                    )
+                } else {
+                    binding.avatarImage.hierarchy.setPlaceholderImage(
+                        R.drawable.ic_circular_group
+                    )
+                }
+            }
+            Conversation.ConversationType.ROOM_PUBLIC_CALL -> {
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                    binding.avatarImage.hierarchy.setPlaceholderImage(
+                        DisplayUtils.getRoundedDrawable(
+                            viewThemeUtils.themePlaceholderAvatar(binding.avatarImage, R.drawable.ic_avatar_link)
+                        )
+                    )
+                } else {
+                    binding.avatarImage.hierarchy.setPlaceholderImage(
+                        R.drawable.ic_circular_link
+                    )
+                }
+            }
             Conversation.ConversationType.ROOM_SYSTEM -> {
                 val layers = arrayOfNulls<Drawable>(2)
                 layers[0] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_background)

+ 7 - 21
app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java

@@ -31,9 +31,7 @@ import android.content.ClipData;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.res.ColorStateList;
 import android.graphics.Bitmap;
-import android.graphics.Color;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -341,6 +339,7 @@ public class ConversationsListController extends BaseController implements Flexi
             credentials = ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken());
             if (getActivity() != null && getActivity() instanceof MainActivity) {
                 loadUserAvatar(((MainActivity) getActivity()).binding.switchAccountButton);
+                viewThemeUtils.colorMaterialTextButton(((MainActivity) getActivity()).binding.switchAccountButton);
             }
             fetchData();
         }
@@ -359,7 +358,7 @@ public class ConversationsListController extends BaseController implements Flexi
             SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
             if (searchItem != null) {
                 searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
-                DisplayUtils.themeSearchView(searchView, context);
+                viewThemeUtils.themeSearchView(searchView);
                 searchView.setMaxWidth(Integer.MAX_VALUE);
                 searchView.setInputType(InputType.TYPE_TEXT_VARIATION_FILTER);
                 int imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_FULLSCREEN;
@@ -421,23 +420,15 @@ public class ConversationsListController extends BaseController implements Flexi
 
                 activity.binding.searchText.setOnClickListener(v -> {
                     showSearchView(activity, searchView, searchItem);
-                    if (getResources() != null) {
-                        DisplayUtils.applyColorToStatusBar(
-                            activity,
-                            ResourcesCompat.getColor(getResources(), R.color.appbar, null)
-                                                          );
-                    }
+                    viewThemeUtils.themeStatusBar(activity, searchView);
                 });
             }
 
             searchView.setOnCloseListener(() -> {
                 if (TextUtils.isEmpty(searchView.getQuery().toString())) {
                     searchView.onActionViewCollapsed();
-                    if (activity != null && getResources() != null) {
-                        DisplayUtils.applyColorToStatusBar(
-                            activity,
-                            ResourcesCompat.getColor(getResources(), R.color.bg_default, null)
-                                                          );
+                    if (activity != null) {
+                        viewThemeUtils.resetStatusBar(activity, searchView);
                     }
                 } else {
                     searchView.post(() -> searchView.setQuery(TAG, true));
@@ -481,10 +472,7 @@ public class ConversationsListController extends BaseController implements Flexi
                         activity.binding.toolbar.setVisibility(View.GONE);
                         activity.binding.searchToolbar.setVisibility(View.VISIBLE);
                         if (getResources() != null) {
-                            DisplayUtils.applyColorToStatusBar(
-                                activity,
-                                ResourcesCompat.getColor(getResources(), R.color.bg_default, null)
-                                                              );
+                            viewThemeUtils.resetStatusBar(activity, activity.binding.searchToolbar);
                         }
                     }
                     SmoothScrollLinearLayoutManager layoutManager =
@@ -816,9 +804,7 @@ public class ConversationsListController extends BaseController implements Flexi
                 recyclerView.smoothScrollToPosition(nextUnreadConversationScrollPosition);
             }
         });
-
-        newMentionPopupBubble.setTextColor(Color.WHITE);
-        newMentionPopupBubble.setIconTint(ColorStateList.valueOf(Color.WHITE));
+        viewThemeUtils.colorMaterialButtonPrimaryFilled(newMentionPopupBubble);
     }
 
     private void checkToShowUnreadBubble() {

+ 12 - 21
app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt

@@ -39,9 +39,7 @@ import android.view.MenuItem
 import android.view.View
 import android.view.ViewGroup
 import android.widget.Toast
-import androidx.annotation.ColorInt
 import androidx.annotation.DrawableRes
-import androidx.core.graphics.drawable.DrawableCompat
 import androidx.core.view.ViewCompat
 import androidx.recyclerview.widget.RecyclerView
 import autodagger.AutoInjector
@@ -108,9 +106,6 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
     @Inject
     lateinit var permissionUtil: PlatformPermissionUtil
 
-    @Inject
-    lateinit var viewThemeUtils: ViewThemeUtils
-
     private var currentUser: User? = null
     private var edit = false
     private var adapter: UserInfoAdapter? = null
@@ -197,7 +192,7 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
 
     override fun onAttach(view: View) {
         super.onAttach(view)
-        adapter = UserInfoAdapter(null, viewThemeUtils.getElementColor(activity!!), this)
+        adapter = UserInfoAdapter(null, viewThemeUtils, this)
         binding.userinfoList.adapter = adapter
         binding.userinfoList.setItemViewCacheSize(DEFAULT_CACHE_SIZE)
         currentUser = userManager.currentUser.blockingGet()
@@ -266,8 +261,10 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
     }
 
     private fun colorIcons() {
-        viewThemeUtils.colorImageView(binding.avatarChoose)
-        viewThemeUtils.colorImageView(binding.avatarCamera)
+        viewThemeUtils.themeFAB(binding.avatarChoose)
+        viewThemeUtils.themeFAB(binding.avatarCamera)
+        viewThemeUtils.themeFAB(binding.avatarUpload)
+        viewThemeUtils.themeFAB(binding.avatarDelete)
     }
 
     private fun isAllEmpty(items: Array<String?>): Boolean {
@@ -710,18 +707,18 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
 
     class UserInfoAdapter(
         displayList: List<UserInfoDetailsItem>?,
-        @ColorInt tintColor: Int,
-        controller: ProfileController
+        private val viewThemeUtils: ViewThemeUtils,
+        private val controller: ProfileController
     ) : RecyclerView.Adapter<UserInfoAdapter.ViewHolder>() {
         var displayList: List<UserInfoDetailsItem>?
         var filteredDisplayList: MutableList<UserInfoDetailsItem> = LinkedList()
 
-        @ColorInt
-        protected var mTintColor: Int
-        private val controller: ProfileController
-
         class ViewHolder(val binding: UserInfoDetailsTableItemBinding) : RecyclerView.ViewHolder(binding.root)
 
+        init {
+            this.displayList = displayList ?: LinkedList()
+        }
+
         fun setData(displayList: List<UserInfoDetailsItem>) {
             this.displayList = displayList
             updateFilteredList()
@@ -758,7 +755,7 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
             initUserInfoEditText(holder, item)
 
             holder.binding.icon.contentDescription = item.hint
-            DrawableCompat.setTint(holder.binding.icon.drawable, mTintColor)
+            viewThemeUtils.colorImageView(holder.binding.icon)
             if (!TextUtils.isEmpty(item.text) || controller.edit) {
                 holder.binding.userInfoDetailContainer.visibility = View.VISIBLE
                 controller.viewThemeUtils.colorTextInputLayout(holder.binding.userInfoInputLayout)
@@ -853,12 +850,6 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
             displayList!![position].scope = scope
             notifyDataSetChanged()
         }
-
-        init {
-            this.displayList = displayList ?: LinkedList()
-            mTintColor = tintColor
-            this.controller = controller
-        }
     }
 
     enum class Field(val fieldName: String, val scopeName: String) {

+ 40 - 35
app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt

@@ -60,6 +60,7 @@ import com.bluelinelabs.conductor.Controller
 import com.bluelinelabs.conductor.RouterTransaction
 import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
 import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.google.android.material.textfield.TextInputLayout
 import com.nextcloud.talk.BuildConfig
 import com.nextcloud.talk.R
@@ -78,7 +79,6 @@ import com.nextcloud.talk.jobs.ContactAddressBookWorker.Companion.deleteAll
 import com.nextcloud.talk.models.json.generic.GenericOverall
 import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
 import com.nextcloud.talk.users.UserManager
-import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.LoggingUtils.sendMailWithAttachment
@@ -92,7 +92,6 @@ import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
 import com.nextcloud.talk.utils.preferences.MagicUserInputModule
 import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
 import com.yarolegovich.lovelydialog.LovelySaveStateHandler
-import com.yarolegovich.lovelydialog.LovelyStandardDialog
 import io.reactivex.Observer
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
@@ -119,10 +118,6 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
     @Inject
     lateinit var currentUserProvider: CurrentUserProviderNew
 
-    @Inject
-    lateinit var viewThemeUtils: ViewThemeUtils
-
-    private var saveStateHandler: LovelySaveStateHandler? = null
     private var currentUser: User? = null
     private var credentials: String? = null
     private var proxyTypeChangeListener: OnPreferenceValueChangedListener<String>? = null
@@ -154,10 +149,6 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
 
         getCurrentUser()
 
-        if (saveStateHandler == null) {
-            saveStateHandler = LovelySaveStateHandler()
-        }
-
         registerChangeListeners()
 
         setupSettingsScreen()
@@ -385,11 +376,6 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
         }
     }
 
-    override fun onSaveViewState(view: View, outState: Bundle) {
-        saveStateHandler!!.saveInstanceState(outState)
-        super.onSaveViewState(view, outState)
-    }
-
     override fun onRestoreViewState(view: View, savedViewState: Bundle) {
         super.onRestoreViewState(view, savedViewState)
         if (LovelySaveStateHandler.wasDialogOnScreen(savedViewState)) {
@@ -401,23 +387,27 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
 
     private fun showRemoveAccountWarning(savedInstanceState: Bundle?) {
         if (activity != null) {
-            LovelyStandardDialog(activity, LovelyStandardDialog.ButtonLayout.HORIZONTAL)
-                .setTopColorRes(R.color.nc_darkRed)
-                .setIcon(
-                    DisplayUtils.getTintedDrawable(
-                        resources,
-                        R.drawable.ic_delete_black_24dp,
-                        R.color.bg_default
-                    )
-                )
-                .setPositiveButtonColor(context!!.resources.getColor(R.color.nc_darkRed))
+            val materialAlertDialogBuilder = MaterialAlertDialogBuilder(binding.messageText.context)
                 .setTitle(R.string.nc_settings_remove_account)
                 .setMessage(R.string.nc_settings_remove_confirmation)
-                .setPositiveButton(R.string.nc_settings_remove, { removeCurrentAccount() })
-                .setNegativeButton(R.string.nc_cancel, null)
-                .setInstanceStateHandler(ID_REMOVE_ACCOUNT_WARNING_DIALOG, saveStateHandler)
-                .setSavedInstanceState(savedInstanceState)
-                .show()
+                .setPositiveButton(R.string.nc_settings_remove) { _, _ ->
+                    removeCurrentAccount()
+                }
+                .setNegativeButton(R.string.nc_cancel) { _, _ ->
+                    // unused atm
+                }
+
+            viewThemeUtils.colorMaterialAlertDialogBackground(
+                binding.messageText.context,
+                materialAlertDialogBuilder
+            )
+
+            val dialog = materialAlertDialogBuilder.show()
+
+            viewThemeUtils.colorTextButtons(
+                dialog.getButton(AlertDialog.BUTTON_POSITIVE),
+                dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
+            )
         }
     }
 
@@ -566,7 +556,9 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
         if (ApplicationWideMessageHolder.getInstance().messageType != null) {
             when (ApplicationWideMessageHolder.getInstance().messageType) {
                 ApplicationWideMessageHolder.MessageType.ACCOUNT_UPDATED_NOT_ADDED -> {
-                    binding.messageText.setTextColor(resources!!.getColor(R.color.colorPrimary))
+                    binding.messageText.setTextColor(
+                        viewThemeUtils.getScheme(binding.messageText.context).primary
+                    )
                     binding.messageText.text = resources!!.getString(R.string.nc_settings_account_updated)
                     binding.messageView.visibility = View.VISIBLE
                 }
@@ -575,13 +567,17 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
                     binding.messageText.setTextColor(resources!!.getColor(R.color.nc_darkRed))
                     binding.messageText.text = resources!!.getString(R.string.nc_settings_wrong_account)
                     binding.messageView.visibility = View.VISIBLE
-                    binding.messageText.setTextColor(resources!!.getColor(R.color.colorPrimary))
+                    binding.messageText.setTextColor(
+                        viewThemeUtils.getScheme(binding.messageText.context).primary
+                    )
                     binding.messageText.text = resources!!.getString(R.string.nc_Server_account_imported)
                     binding.messageView.visibility = View.VISIBLE
                 }
 
                 ApplicationWideMessageHolder.MessageType.ACCOUNT_WAS_IMPORTED -> {
-                    binding.messageText.setTextColor(resources!!.getColor(R.color.colorPrimary))
+                    binding.messageText.setTextColor(
+                        viewThemeUtils.getScheme(binding.messageText.context).primary
+                    )
                     binding.messageText.text = resources!!.getString(R.string.nc_Server_account_imported)
                     binding.messageView.visibility = View.VISIBLE
                 }
@@ -961,13 +957,16 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
         })
         phoneNumberInputLayout.addView(phoneNumberField)
         phoneNumberLayoutWrapper.addView(phoneNumberInputLayout)
-        val dialog = AlertDialog.Builder((activity)!!)
+        val dialogBuilder = MaterialAlertDialogBuilder(phoneNumberInputLayout.context)
             .setTitle(R.string.nc_settings_phone_book_integration_phone_number_dialog_title)
             .setMessage(R.string.nc_settings_phone_book_integration_phone_number_dialog_description)
             .setView(phoneNumberLayoutWrapper)
             .setPositiveButton(context!!.resources.getString(R.string.nc_common_set), null)
             .setNegativeButton(context!!.resources.getString(R.string.nc_common_skip), null)
-            .create()
+
+        viewThemeUtils.colorMaterialAlertDialogBackground(phoneNumberInputLayout.context, dialogBuilder)
+
+        val dialog = dialogBuilder.create()
         dialog.setOnShowListener(object : OnShowListener {
             override fun onShow(dialogInterface: DialogInterface) {
                 val button = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
@@ -978,7 +977,13 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
                 })
             }
         })
+
         dialog.show()
+
+        viewThemeUtils.colorTextButtons(
+            dialog.getButton(AlertDialog.BUTTON_POSITIVE),
+            dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
+        )
     }
 
     private fun setPhoneNumber(textInputLayout: TextInputLayout, dialog: AlertDialog) {

+ 2 - 2
app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.kt

@@ -138,7 +138,7 @@ class SwitchAccountController(args: Bundle? = null) :
                         participant.actorType = Participant.ActorType.USERS
                         participant.actorId = userId
                         participant.displayName = user.displayName
-                        userItems.add(AdvancedUserItem(participant, user, null))
+                        userItems.add(AdvancedUserItem(participant, user, null, viewThemeUtils))
                     }
                 }
                 adapter!!.addListener(onSwitchItemClickListener)
@@ -156,7 +156,7 @@ class SwitchAccountController(args: Bundle? = null) :
                     participant.displayName = importAccount.getUsername()
                     user = User()
                     user.baseUrl = importAccount.getBaseUrl()
-                    userItems.add(AdvancedUserItem(participant, user, account))
+                    userItems.add(AdvancedUserItem(participant, user, account, viewThemeUtils))
                 }
                 adapter!!.addListener(onImportItemClickListener)
                 adapter!!.updateDataSet(userItems, false)

+ 16 - 10
app/src/main/java/com/nextcloud/talk/controllers/base/BaseController.java

@@ -49,6 +49,7 @@ import com.nextcloud.talk.controllers.ServerSelectionController;
 import com.nextcloud.talk.controllers.SwitchAccountController;
 import com.nextcloud.talk.controllers.WebViewLoginController;
 import com.nextcloud.talk.controllers.base.providers.ActionBarProvider;
+import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.preferences.AppPreferences;
 
@@ -70,9 +71,13 @@ public abstract class BaseController extends ButterKnifeController {
     private static final String TAG = "BaseController";
     @Inject
     AppPreferences appPreferences;
+
     @Inject
     Context context;
 
+    @Inject
+    ViewThemeUtils viewThemeUtils;
+
     protected BaseController() {
         cleanTempCertPreference();
     }
@@ -109,12 +114,19 @@ public abstract class BaseController extends ButterKnifeController {
     @Override
     protected void onViewBound(@NonNull View view) {
         super.onViewBound(view);
+        MainActivity activity = null;
+
+        if (getActivity() != null && getActivity() instanceof MainActivity) {
+            activity = (MainActivity) getActivity();
+            viewThemeUtils.themeCardView(activity.binding.searchToolbar);
+            viewThemeUtils.themeToolbar(activity.binding.toolbar);
+            viewThemeUtils.themeSearchBarText(activity.binding.searchText);
+        }
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences.getIsKeyboardIncognito()) {
             disableKeyboardPersonalisedLearning((ViewGroup) view);
 
-            if (getActivity() != null && getActivity() instanceof MainActivity) {
-                MainActivity activity = (MainActivity) getActivity();
+            if (activity != null) {
                 disableKeyboardPersonalisedLearning(activity.binding.appBar);
             }
         }
@@ -174,15 +186,9 @@ public abstract class BaseController extends ButterKnifeController {
 
                 if ((getResources() != null)) {
                     if (showSearchBar) {
-                        DisplayUtils.applyColorToStatusBar(
-                                activity, ResourcesCompat.getColor(getResources(),
-                                        R.color.bg_default, null)
-                        );
+                        viewThemeUtils.resetStatusBar(activity, activity.binding.searchToolbar);
                     } else {
-                        DisplayUtils.applyColorToStatusBar(
-                                activity, ResourcesCompat.getColor(getResources(),
-                                        R.color.appbar, null)
-                        );
+                        viewThemeUtils.themeStatusBar(activity, activity.binding.searchToolbar);
                     }
                 }
             }

+ 20 - 17
app/src/main/java/com/nextcloud/talk/controllers/base/NewBaseController.kt

@@ -56,6 +56,7 @@ import com.nextcloud.talk.controllers.WebViewLoginController
 import com.nextcloud.talk.controllers.base.providers.ActionBarProvider
 import com.nextcloud.talk.controllers.util.ControllerViewBindingDelegate
 import com.nextcloud.talk.databinding.ActivityMainBinding
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.preferences.AppPreferences
 import javax.inject.Inject
@@ -73,6 +74,9 @@ abstract class NewBaseController(@LayoutRes var layoutRes: Int, args: Bundle? =
     @Inject
     lateinit var context: Context
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     protected open val title: String?
         get() = null
 
@@ -115,11 +119,19 @@ abstract class NewBaseController(@LayoutRes var layoutRes: Int, args: Bundle? =
     }
 
     protected open fun onViewBound(view: View) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences!!.isKeyboardIncognito) {
-            disableKeyboardPersonalisedLearning(view as ViewGroup)
-            if (activity != null && activity is MainActivity) {
-                val activity = activity as MainActivity?
-                disableKeyboardPersonalisedLearning(activity!!.binding.appBar)
+        var activity: MainActivity? = null
+
+        if (getActivity() != null && getActivity() is MainActivity) {
+            activity = getActivity() as MainActivity?
+            viewThemeUtils.themeCardView(activity!!.binding.searchToolbar)
+            viewThemeUtils.themeToolbar(activity.binding.toolbar)
+            viewThemeUtils.themeSearchBarText(activity.binding.searchText)
+        }
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences.isKeyboardIncognito) {
+            disableKeyboardPersonalisedLearning((view as ViewGroup))
+            if (activity != null) {
+                disableKeyboardPersonalisedLearning(activity.binding.appBar)
             }
         }
     }
@@ -176,6 +188,7 @@ abstract class NewBaseController(@LayoutRes var layoutRes: Int, args: Bundle? =
         val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
         binding.searchToolbar.visibility = View.GONE
         binding.toolbar.visibility = View.VISIBLE
+        viewThemeUtils.colorToolbarOverflowIcon(binding.toolbar)
         layoutParams.scrollFlags = 0
         binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
             binding.appBar.context,
@@ -192,19 +205,9 @@ abstract class NewBaseController(@LayoutRes var layoutRes: Int, args: Bundle? =
     private fun colorizeStatusBar(showSearchBar: Boolean, activity: Activity?, resources: Resources?) {
         if (activity != null && resources != null) {
             if (showSearchBar) {
-                DisplayUtils.applyColorToStatusBar(
-                    activity,
-                    ResourcesCompat.getColor(
-                        resources, R.color.bg_default, null
-                    )
-                )
+                view?.let { viewThemeUtils.resetStatusBar(activity, it) }
             } else {
-                DisplayUtils.applyColorToStatusBar(
-                    activity,
-                    ResourcesCompat.getColor(
-                        resources, R.color.appbar, null
-                    )
-                )
+                view?.let { viewThemeUtils.themeStatusBar(activity, it) }
             }
         }
     }

+ 0 - 8
app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt

@@ -46,8 +46,6 @@ import com.nextcloud.talk.controllers.base.NewBaseController
 import com.nextcloud.talk.controllers.util.viewBinding
 import com.nextcloud.talk.databinding.ControllerEntryMenuBinding
 import com.nextcloud.talk.models.json.conversations.Conversation
-import com.nextcloud.talk.ui.theme.ServerTheme
-import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.users.UserManager
 import com.nextcloud.talk.utils.ShareUtils
 import com.nextcloud.talk.utils.UriUtils
@@ -74,12 +72,6 @@ class EntryMenuController(args: Bundle) :
     @Inject
     lateinit var userManager: UserManager
 
-    @Inject
-    lateinit var viewThemeUtils: ViewThemeUtils
-
-    @Inject
-    lateinit var serverTheme: ServerTheme
-
     private val operation: ConversationOperationEnum
     private var conversation: Conversation? = null
     private var shareIntent: Intent? = null

+ 2 - 0
app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.kt

@@ -117,6 +117,8 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
         sharedApplication!!.componentApplication.inject(this)
         currentUser = userManager.currentUser.blockingGet()
 
+        viewThemeUtils.colorCircularProgressBar(binding.progressBar)
+
         if (!TextUtils.isEmpty(callUrl) && callUrl.contains("/call")) {
             conversationToken = callUrl.substring(callUrl.lastIndexOf("/") + 1)
             if (callUrl.contains("/index.php")) {

+ 1 - 0
app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java

@@ -346,6 +346,7 @@ public class NotificationWorker extends Worker {
         if (Build.VERSION.SDK_INT >= 23) {
             // This method should exist since API 21, but some phones don't have it
             // So as a safeguard, we don't use it until 23
+
             notificationBuilder.setColor(context.getResources().getColor(R.color.colorPrimary));
         }
 

+ 0 - 4
app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt

@@ -41,7 +41,6 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.controllers.ConversationsListController
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.ActivityMessageSearchBinding
-import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.bundle.BundleKeys
 import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
@@ -65,9 +64,6 @@ class MessageSearchActivity : BaseActivity() {
     @Inject
     lateinit var userProvider: CurrentUserProviderNew
 
-    @Inject
-    lateinit var viewThemeUtils: ViewThemeUtils
-
     private lateinit var binding: ActivityMessageSearchBinding
     private lateinit var searchView: SearchView
 

+ 1 - 1
app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionViewHolder.kt

@@ -50,7 +50,7 @@ class PollCreateOptionViewHolder(
         }
 
         binding.pollOptionTextEdit.setText(pollCreateOptionItem.pollOption)
-        viewThemeUtils.colorEditText(binding.pollOptionTextEdit)
+        viewThemeUtils.colorTextInputLayout(binding.pollOptionTextInputLayout)
 
         if (focus) {
             itemsListener.requestFocus(binding.pollOptionTextEdit)

+ 3 - 0
app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultHeaderViewHolder.kt

@@ -41,6 +41,9 @@ class PollResultHeaderViewHolder(
         binding.pollOptionText.text = item.name
         binding.pollOptionPercentText.text = "${item.percent}%"
 
+        viewThemeUtils.colorDialogSupportingText(binding.pollOptionText)
+        viewThemeUtils.colorDialogSupportingText(binding.pollOptionPercentText)
+
         if (item.selfVoted) {
             binding.pollOptionText.setTypeface(null, Typeface.BOLD)
             binding.pollOptionPercentText.setTypeface(null, Typeface.BOLD)

+ 4 - 1
app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVoterViewHolder.kt

@@ -29,12 +29,14 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.PollResultVoterItemBinding
 import com.nextcloud.talk.polls.model.PollDetails
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DisplayUtils
 
 class PollResultVoterViewHolder(
     private val user: User,
-    override val binding: PollResultVoterItemBinding
+    override val binding: PollResultVoterItemBinding,
+    private val viewThemeUtils: ViewThemeUtils
 ) : PollResultViewHolder(binding) {
 
     @SuppressLint("SetTextI18n")
@@ -45,6 +47,7 @@ class PollResultVoterViewHolder(
 
         binding.pollVoterName.text = item.details.actorDisplayName
         binding.pollVoterAvatar.controller = getAvatarDraweeController(item.details)
+        viewThemeUtils.colorDialogSupportingText(binding.pollVoterName)
     }
 
     private fun getAvatarDraweeController(pollDetail: PollDetails): DraweeController? {

+ 1 - 1
app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt

@@ -52,7 +52,7 @@ class PollResultsAdapter(
                     LayoutInflater.from(parent.context), parent,
                     false
                 )
-                viewHolder = PollResultVoterViewHolder(user, itemBinding)
+                viewHolder = PollResultVoterViewHolder(user, itemBinding, viewThemeUtils)
             }
             PollResultVotersOverviewItem.VIEW_TYPE -> {
                 val itemBinding = PollResultVotersOverviewItemBinding.inflate(

+ 10 - 9
app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt

@@ -31,11 +31,11 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
 import android.widget.Toast
-import androidx.appcompat.app.AlertDialog
 import androidx.fragment.app.DialogFragment
 import androidx.lifecycle.ViewModelProvider
 import androidx.recyclerview.widget.LinearLayoutManager
 import autodagger.AutoInjector
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.databinding.DialogPollCreateBinding
@@ -73,9 +73,11 @@ class PollCreateDialogFragment : DialogFragment(), PollCreateOptionsItemListener
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
         binding = DialogPollCreateBinding.inflate(LayoutInflater.from(context))
 
-        return AlertDialog.Builder(requireContext())
+        val dialogBuilder = MaterialAlertDialogBuilder(binding.root.context)
             .setView(binding.root)
-            .create()
+        viewThemeUtils.colorMaterialAlertDialogBackground(binding.root.context, dialogBuilder)
+
+        return dialogBuilder.create()
     }
 
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
@@ -99,16 +101,15 @@ class PollCreateDialogFragment : DialogFragment(), PollCreateOptionsItemListener
     }
 
     private fun themeDialog() {
-        viewThemeUtils.colorTextViewText(binding.pollQuestion)
-        viewThemeUtils.colorTextViewText(binding.pollOptions)
-        viewThemeUtils.colorTextViewText(binding.pollSettings)
+        viewThemeUtils.colorPrimaryTextViewElement(binding.pollQuestion)
+        viewThemeUtils.colorPrimaryTextViewElement(binding.pollOptions)
+        viewThemeUtils.colorPrimaryTextViewElement(binding.pollSettings)
 
-        viewThemeUtils.colorEditText(binding.pollCreateQuestionTextEdit)
+        viewThemeUtils.colorTextInputLayout(binding.pollCreateQuestionTextInputLayout)
 
         viewThemeUtils.colorMaterialButtonText(binding.pollAddOptionsItem)
-        // TODO button also needs a disabled state handling for colors
         viewThemeUtils.colorMaterialButtonText(binding.pollDismiss)
-        viewThemeUtils.colorMaterialButtonBackground(binding.pollCreateButton)
+        viewThemeUtils.colorMaterialButtonPrimaryFilled(binding.pollCreateButton)
 
         viewThemeUtils.themeCheckbox(binding.pollPrivatePollCheckbox)
         viewThemeUtils.themeCheckbox(binding.pollMultipleAnswersCheckbox)

+ 6 - 0
app/src/main/java/com/nextcloud/talk/polls/ui/PollLoadingFragment.kt

@@ -29,12 +29,17 @@ import androidx.fragment.app.Fragment
 import autodagger.AutoInjector
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.databinding.DialogPollLoadingBinding
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
+import javax.inject.Inject
 
 @AutoInjector(NextcloudTalkApplication::class)
 class PollLoadingFragment : Fragment() {
 
     private lateinit var binding: DialogPollLoadingBinding
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     var fragmentHeight = 0
 
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -50,6 +55,7 @@ class PollLoadingFragment : Fragment() {
     ): View {
         binding = DialogPollLoadingBinding.inflate(inflater, container, false)
         binding.root.layoutParams.height = fragmentHeight
+        viewThemeUtils.colorCircularProgressBar(binding.pollLoadingProgressbar)
         return binding.root
     }
 

+ 14 - 4
app/src/main/java/com/nextcloud/talk/polls/ui/PollMainDialogFragment.kt

@@ -26,16 +26,17 @@ import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import androidx.appcompat.app.AlertDialog
 import androidx.core.os.bundleOf
 import androidx.fragment.app.DialogFragment
 import androidx.lifecycle.ViewModelProvider
 import autodagger.AutoInjector
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.DialogPollMainBinding
 import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import javax.inject.Inject
 
 @AutoInjector(NextcloudTalkApplication::class)
@@ -44,6 +45,9 @@ class PollMainDialogFragment : DialogFragment() {
     @Inject
     lateinit var viewModelFactory: ViewModelProvider.Factory
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     private lateinit var binding: DialogPollMainBinding
     private lateinit var viewModel: PollMainViewModel
 
@@ -66,11 +70,15 @@ class PollMainDialogFragment : DialogFragment() {
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
         binding = DialogPollMainBinding.inflate(LayoutInflater.from(context))
 
-        val dialog = AlertDialog.Builder(requireContext())
-            .setView(binding.root)
-            .create()
+        val dialogBuilder = MaterialAlertDialogBuilder(binding.root.context).setView(binding.root)
+
+        viewThemeUtils.colorMaterialAlertDialogBackground(binding.root.context, dialogBuilder)
+
+        val dialog = dialogBuilder.create()
 
         binding.messagePollTitle.text = viewModel.pollTitle
+        viewThemeUtils.colorDialogHeadline(binding.messagePollTitle)
+        viewThemeUtils.colorDialogIcon(binding.messagePollIcon)
 
         return dialog
     }
@@ -135,6 +143,7 @@ class PollMainDialogFragment : DialogFragment() {
 
     private fun initVotersAmount(showVotersAmount: Boolean, numVoters: Int, showResultSubtitle: Boolean) {
         if (showVotersAmount) {
+            viewThemeUtils.colorDialogSupportingText(binding.pollVotesAmount)
             binding.pollVotesAmount.visibility = View.VISIBLE
             binding.pollVotesAmount.text = resources.getQuantityString(
                 R.plurals.polls_amount_voters,
@@ -146,6 +155,7 @@ class PollMainDialogFragment : DialogFragment() {
         }
 
         if (showResultSubtitle) {
+            viewThemeUtils.colorDialogSupportingText(binding.pollResultsSubtitle)
             binding.pollResultsSubtitle.visibility = View.VISIBLE
             binding.pollResultsSubtitleSeperator.visibility = View.VISIBLE
         } else {

+ 16 - 4
app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt

@@ -31,6 +31,7 @@ import androidx.fragment.app.Fragment
 import androidx.lifecycle.ViewModelProvider
 import androidx.recyclerview.widget.LinearLayoutManager
 import autodagger.AutoInjector
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.databinding.DialogPollResultsBinding
@@ -98,8 +99,8 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener {
     }
 
     private fun themeDialog() {
-        viewThemeUtils.colorMaterialButtonBackground(binding.editVoteButton)
-        viewThemeUtils.colorMaterialButtonText(binding.pollResultsEndPollButton)
+        viewThemeUtils.colorMaterialButtonPrimaryFilled(binding.editVoteButton)
+        viewThemeUtils.colorMaterialButtonPrimaryBorderless(binding.pollResultsEndPollButton)
     }
 
     private fun initAdapter() {
@@ -123,14 +124,25 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener {
         if (showEndPollButton) {
             binding.pollResultsEndPollButton.visibility = View.VISIBLE
             binding.pollResultsEndPollButton.setOnClickListener {
-                AlertDialog.Builder(requireContext())
+                val dialogBuilder = MaterialAlertDialogBuilder(binding.pollResultsEndPollButton.context)
                     .setTitle(R.string.polls_end_poll)
                     .setMessage(R.string.polls_end_poll_confirm)
                     .setPositiveButton(R.string.polls_end_poll) { _, _ ->
                         parentViewModel.endPoll()
                     }
                     .setNegativeButton(R.string.nc_cancel, null)
-                    .show()
+
+                viewThemeUtils.colorMaterialAlertDialogBackground(
+                    binding.pollResultsEndPollButton.context,
+                    dialogBuilder
+                )
+
+                val dialog = dialogBuilder.show()
+
+                viewThemeUtils.colorTextButtons(
+                    dialog.getButton(AlertDialog.BUTTON_POSITIVE),
+                    dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
+                )
             }
         } else {
             binding.pollResultsEndPollButton.visibility = View.GONE

+ 16 - 4
app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt

@@ -37,6 +37,7 @@ import androidx.appcompat.app.AlertDialog
 import androidx.fragment.app.Fragment
 import androidx.lifecycle.ViewModelProvider
 import autodagger.AutoInjector
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.databinding.DialogPollVoteBinding
@@ -126,9 +127,9 @@ class PollVoteFragment : Fragment() {
     }
 
     private fun themeDialog() {
-        viewThemeUtils.colorMaterialButtonBackground(binding.pollVoteSubmitButton)
+        viewThemeUtils.colorMaterialButtonPrimaryFilled(binding.pollVoteSubmitButton)
         viewThemeUtils.colorMaterialButtonText(binding.pollVoteEndPollButton)
-        viewThemeUtils.colorMaterialButtonText(binding.pollVoteEditDismiss)
+        viewThemeUtils.colorMaterialButtonPrimaryOutlined(binding.pollVoteEditDismiss)
     }
 
     private fun updateDismissEditButton(showDismissEditButton: Boolean) {
@@ -206,14 +207,25 @@ class PollVoteFragment : Fragment() {
         if (showEndPollButton) {
             binding.pollVoteEndPollButton.visibility = View.VISIBLE
             binding.pollVoteEndPollButton.setOnClickListener {
-                AlertDialog.Builder(requireContext())
+                val dialogBuilder = MaterialAlertDialogBuilder(binding.pollVoteEndPollButton.context)
                     .setTitle(R.string.polls_end_poll)
                     .setMessage(R.string.polls_end_poll_confirm)
                     .setPositiveButton(R.string.polls_end_poll) { _, _ ->
                         parentViewModel.endPoll()
                     }
                     .setNegativeButton(R.string.nc_cancel, null)
-                    .show()
+
+                viewThemeUtils.colorMaterialAlertDialogBackground(
+                    binding.pollVoteEndPollButton.context,
+                    dialogBuilder
+                )
+
+                val dialog = dialogBuilder.show()
+
+                viewThemeUtils.colorTextButtons(
+                    dialog.getButton(AlertDialog.BUTTON_POSITIVE),
+                    dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
+                )
             }
         } else {
             binding.pollVoteEndPollButton.visibility = View.GONE

+ 6 - 1
app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java

@@ -36,6 +36,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.data.user.model.User;
 import com.nextcloud.talk.models.json.mention.Mention;
 import com.nextcloud.talk.models.json.mention.MentionOverall;
+import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.nextcloud.talk.users.UserManager;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.otaliastudios.autocomplete.RecyclerViewPresenter;
@@ -69,6 +70,9 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
     @Inject
     UserManager userManager;
 
+    @Inject
+    ViewThemeUtils viewThemeUtils;
+
     private User currentUser;
     private FlexibleAdapter<AbstractFlexibleItem> adapter;
     private Context context;
@@ -150,7 +154,8 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
                                         new MentionAutocompleteItem(
                                                 mention,
                                                 currentUser,
-                                                context));
+                                                context,
+                                                viewThemeUtils));
                             }
 
                             if (adapter.getItemCount() != 0) {

+ 11 - 6
app/src/main/java/com/nextcloud/talk/remotefilebrowser/activities/RemoteFileBrowserActivity.kt

@@ -24,6 +24,7 @@ package com.nextcloud.talk.remotefilebrowser.activities
 
 import android.app.Activity
 import android.content.Intent
+import android.content.res.ColorStateList
 import android.os.Bundle
 import android.util.Log
 import android.view.Menu
@@ -74,14 +75,18 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
 
         binding = ActivityRemoteFileBrowserBinding.inflate(layoutInflater)
         setSupportActionBar(binding.remoteFileBrowserItemsToolbar)
+        viewThemeUtils.themeToolbar(binding.remoteFileBrowserItemsToolbar)
+        val scheme = viewThemeUtils.getScheme(binding.sortListButtonGroup.context)
+        binding.sortListButtonGroup.setBackgroundColor(scheme.surface)
+        binding.sortButton.iconTint = ColorStateList.valueOf(scheme.onSurface)
+        binding.sortButton.setTextColor(scheme.onSurface)
+        viewThemeUtils.colorMaterialTextButton(binding.sortButton)
+        binding.pathNavigationBackButton.iconTint = ColorStateList.valueOf(scheme.onSurface)
+        binding.pathNavigationBackButton.setTextColor(scheme.onSurface)
+        viewThemeUtils.colorMaterialTextButton(binding.pathNavigationBackButton)
+        viewThemeUtils.themeStatusBar(this, binding.remoteFileBrowserItemsToolbar)
         setContentView(binding.root)
 
-        DisplayUtils.applyColorToStatusBar(
-            this,
-            ResourcesCompat.getColor(
-                resources, R.color.appbar, null
-            )
-        )
         DisplayUtils.applyColorToNavigationBar(
             this.window,
             ResourcesCompat.getColor(resources, R.color.bg_default, null)

+ 5 - 9
app/src/main/java/com/nextcloud/talk/shareditems/activities/SharedItemsActivity.kt

@@ -73,14 +73,10 @@ class SharedItemsActivity : AppCompatActivity() {
         setSupportActionBar(binding.sharedItemsToolbar)
         setContentView(binding.root)
 
-        DisplayUtils.applyColorToStatusBar(
-            this,
-            ResourcesCompat.getColor(
-                resources,
-                R.color.appbar,
-                null
-            )
-        )
+        viewThemeUtils.themeStatusBar(this, binding.sharedItemsToolbar)
+        viewThemeUtils.themeToolbar(binding.sharedItemsToolbar)
+        viewThemeUtils.themeTabLayoutOnSurface(binding.sharedItemsTabs)
+
         DisplayUtils.applyColorToNavigationBar(
             this.window,
             ResourcesCompat.getColor(resources, R.color.bg_default, null)
@@ -150,7 +146,7 @@ class SharedItemsActivity : AppCompatActivity() {
             else -> {}
         }
 
-        viewThemeUtils.colorTabLayout(binding.sharedItemsTabs)
+        viewThemeUtils.themeTabLayoutOnSurface(binding.sharedItemsTabs)
     }
 
     private fun clearEmptyLoading() {

+ 11 - 0
app/src/main/java/com/nextcloud/talk/ui/dialog/AttachmentDialog.kt

@@ -26,23 +26,34 @@ import android.app.Activity
 import android.os.Bundle
 import android.view.View
 import android.view.ViewGroup
+import autodagger.AutoInjector
 import com.google.android.material.bottomsheet.BottomSheetBehavior
 import com.google.android.material.bottomsheet.BottomSheetDialog
 import com.nextcloud.talk.R
+import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.controllers.ChatController
 import com.nextcloud.talk.databinding.DialogAttachmentBinding
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
+import javax.inject.Inject
 
+@AutoInjector(NextcloudTalkApplication::class)
 class AttachmentDialog(val activity: Activity, var chatController: ChatController) : BottomSheetDialog(activity) {
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     private lateinit var dialogAttachmentBinding: DialogAttachmentBinding
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
+
         dialogAttachmentBinding = DialogAttachmentBinding.inflate(layoutInflater)
         setContentView(dialogAttachmentBinding.root)
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
 
+        viewThemeUtils.themeDialog(dialogAttachmentBinding.root)
         initItemsStrings()
         initItemsVisibility()
         initItemsClickListeners()

+ 7 - 12
app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt

@@ -31,7 +31,6 @@ import com.nextcloud.talk.R
 import com.nextcloud.talk.activities.CallActivity
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.databinding.DialogAudioOutputBinding
-import com.nextcloud.talk.ui.theme.ServerTheme
 import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.webrtc.WebRtcAudioManager
 import javax.inject.Inject
@@ -42,21 +41,17 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call
     @Inject
     lateinit var viewThemeUtils: ViewThemeUtils
 
-    @Inject
-    lateinit var serverTheme: ServerTheme
-
     private lateinit var dialogAudioOutputBinding: DialogAudioOutputBinding
 
-    init {
-        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
-    }
-
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
+
         dialogAudioOutputBinding = DialogAudioOutputBinding.inflate(layoutInflater)
         setContentView(dialogAudioOutputBinding.root)
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
 
+        viewThemeUtils.themeDialogDark(dialogAudioOutputBinding.root)
         updateOutputDeviceList()
         initClickListeners()
     }
@@ -98,22 +93,22 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call
         when (callActivity.audioManager?.currentAudioDevice) {
             WebRtcAudioManager.AudioDevice.BLUETOOTH -> {
                 viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputBluetoothIcon)
-                dialogAudioOutputBinding.audioOutputBluetoothText.setTextColor(serverTheme.primaryColor)
+                viewThemeUtils.colorPrimaryTextViewElementDarkMode(dialogAudioOutputBinding.audioOutputBluetoothText)
             }
 
             WebRtcAudioManager.AudioDevice.SPEAKER_PHONE -> {
                 viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputSpeakerIcon)
-                dialogAudioOutputBinding.audioOutputSpeakerText.setTextColor(serverTheme.primaryColor)
+                viewThemeUtils.colorPrimaryTextViewElementDarkMode(dialogAudioOutputBinding.audioOutputSpeakerText)
             }
 
             WebRtcAudioManager.AudioDevice.EARPIECE -> {
                 viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputEarspeakerIcon)
-                dialogAudioOutputBinding.audioOutputEarspeakerText.setTextColor(serverTheme.primaryColor)
+                viewThemeUtils.colorPrimaryTextViewElementDarkMode(dialogAudioOutputBinding.audioOutputEarspeakerText)
             }
 
             WebRtcAudioManager.AudioDevice.WIRED_HEADSET -> {
                 viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputWiredHeadsetIcon)
-                dialogAudioOutputBinding.audioOutputWiredHeadsetText.setTextColor(serverTheme.primaryColor)
+                viewThemeUtils.colorPrimaryTextViewElementDarkMode(dialogAudioOutputBinding.audioOutputWiredHeadsetText)
             }
 
             else -> Log.d(TAG, "AudioOutputDialog doesn't know this AudioDevice")

+ 51 - 32
app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java

@@ -39,7 +39,6 @@ import android.view.ViewGroup;
 import com.facebook.drawee.backends.pipeline.Fresco;
 import com.facebook.drawee.interfaces.DraweeController;
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-import com.nextcloud.talk.R;
 import com.nextcloud.talk.activities.MainActivity;
 import com.nextcloud.talk.adapters.items.AdvancedUserItem;
 import com.nextcloud.talk.api.NcApi;
@@ -113,12 +112,18 @@ public class ChooseAccountDialogFragment extends DialogFragment {
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
+        User user = userManager.getCurrentUser().blockingGet();
+
+        themeViews();
+        setupCurrentUser(user);
+        setupListeners(user);
+        setupAdapter();
+        prepareViews();
+    }
 
+    private void setupCurrentUser(User user) {
         // Defining user picture
         binding.currentAccount.userIcon.setTag("");
-
-        // Defining user texts, accounts, etc.
-        User user = userManager.getCurrentUser().blockingGet();
         if (user != null) {
             binding.currentAccount.userName.setText(user.getDisplayName());
             binding.currentAccount.ticker.setVisibility(View.GONE);
@@ -148,32 +153,9 @@ public class ChooseAccountDialogFragment extends DialogFragment {
 
             loadCurrentStatus(user);
         }
+    }
 
-        // Creating listeners for quick-actions
-        binding.currentAccount.getRoot().setOnClickListener(v -> dismiss());
-
-        if (getActivity() instanceof MainActivity) {
-            binding.addAccount.setOnClickListener(v -> {
-                dismiss();
-                ((MainActivity) getActivity()).addAccount();
-            });
-            binding.manageSettings.setOnClickListener(v -> {
-                dismiss();
-                ((MainActivity) getActivity()).openSettings();
-            });
-        }
-
-        binding.setStatus.setOnClickListener(v -> {
-            dismiss();
-
-            if (status != null) {
-                SetStatusDialogFragment setStatusDialog = SetStatusDialogFragment.newInstance(user, status);
-                setStatusDialog.show(getActivity().getSupportFragmentManager(), "fragment_set_status");
-            } else {
-                Log.w(TAG, "status was null");
-            }
-        });
-
+    private void setupAdapter() {
         if (adapter == null) {
             adapter = new FlexibleAdapter<>(userItems, getActivity(), false);
 
@@ -194,15 +176,52 @@ public class ChooseAccountDialogFragment extends DialogFragment {
                     participant.setActorType(Participant.ActorType.USERS);
                     participant.setActorId(userId);
                     participant.setDisplayName(userEntity.getDisplayName());
-                    userItems.add(new AdvancedUserItem(participant, userEntity, null));
+                    userItems.add(new AdvancedUserItem(participant, userEntity, null, viewThemeUtils));
                 }
             }
 
             adapter.addListener(onSwitchItemClickListener);
             adapter.updateDataSet(userItems, false);
         }
+    }
 
-        prepareViews();
+    private void setupListeners(User user) {
+        // Creating listeners for quick-actions
+        binding.currentAccount.getRoot().setOnClickListener(v -> dismiss());
+
+        if (getActivity() instanceof MainActivity) {
+            binding.addAccount.setOnClickListener(v -> {
+                dismiss();
+                ((MainActivity) getActivity()).addAccount();
+            });
+            binding.manageSettings.setOnClickListener(v -> {
+                dismiss();
+                ((MainActivity) getActivity()).openSettings();
+            });
+        }
+
+        binding.setStatus.setOnClickListener(v -> {
+            dismiss();
+
+            if (status != null) {
+                SetStatusDialogFragment setStatusDialog = SetStatusDialogFragment.newInstance(user, status);
+                setStatusDialog.show(getActivity().getSupportFragmentManager(), "fragment_set_status");
+            } else {
+                Log.w(TAG, "status was null");
+            }
+        });
+    }
+
+    private void themeViews() {
+        viewThemeUtils.themeDialog(binding.getRoot());
+        viewThemeUtils.themeDialogDivider(binding.divider);
+
+        viewThemeUtils.colorMaterialTextButton(binding.setStatus);
+        viewThemeUtils.colorDialogMenuText(binding.setStatus);
+        viewThemeUtils.colorMaterialTextButton(binding.addAccount);
+        viewThemeUtils.colorDialogMenuText(binding.addAccount);
+        viewThemeUtils.colorMaterialTextButton(binding.manageSettings);
+        viewThemeUtils.colorDialogMenuText(binding.manageSettings);
     }
 
     private void loadCurrentStatus(User user) {
@@ -305,7 +324,7 @@ public class ChooseAccountDialogFragment extends DialogFragment {
             status.getStatus(),
             status.getIcon(),
             size,
-            getContext().getResources().getColor(R.color.dialog_background),
+            viewThemeUtils.getScheme(binding.currentAccount.ticker.getContext()).getSurface(),
             getContext()));
         binding.currentAccount.ticker.setVisibility(View.VISIBLE);
 

+ 8 - 4
app/src/main/java/com/nextcloud/talk/ui/dialog/ContactsBottomDialog.kt

@@ -35,6 +35,8 @@ import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.controllers.bottomsheet.EntryMenuController
 import com.nextcloud.talk.databinding.DialogBottomContactsBinding
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
+import javax.inject.Inject
 
 @AutoInjector(NextcloudTalkApplication::class)
 class ContactsBottomDialog(
@@ -42,20 +44,22 @@ class ContactsBottomDialog(
     val bundle: Bundle
 ) : BottomSheetDialog(activity) {
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     private var dialogRouter: Router? = null
 
     private lateinit var binding: DialogBottomContactsBinding
 
-    init {
-        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
-    }
-
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
+
         binding = DialogBottomContactsBinding.inflate(layoutInflater)
         setContentView(binding.root)
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
 
+        viewThemeUtils.themeDialog(binding.root)
         executeEntryMenuController(bundle)
     }
 

+ 7 - 4
app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt

@@ -56,6 +56,7 @@ import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.DialogConversationOperationsBinding
 import com.nextcloud.talk.jobs.LeaveConversationWorker
 import com.nextcloud.talk.models.json.conversations.Conversation
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.users.UserManager
 import com.nextcloud.talk.utils.Mimetype.TEXT_PLAIN
 import com.nextcloud.talk.utils.ShareUtils
@@ -83,18 +84,20 @@ class ConversationsListBottomDialog(
     lateinit var ncApi: NcApi
 
     @Inject
-    lateinit var userManager: UserManager
+    lateinit var viewThemeUtils: ViewThemeUtils
 
-    init {
-        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
-    }
+    @Inject
+    lateinit var userManager: UserManager
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
+
         binding = DialogConversationOperationsBinding.inflate(layoutInflater)
         setContentView(binding.root)
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
 
+        viewThemeUtils.themeDialog(binding.root)
         initHeaderDescription()
         initItemsVisibility()
         initClickListeners()

+ 12 - 2
app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt

@@ -31,18 +31,20 @@ import android.view.View
 import android.view.ViewGroup
 import android.view.inputmethod.InputMethodManager
 import androidx.annotation.NonNull
-import androidx.appcompat.content.res.AppCompatResources
+import autodagger.AutoInjector
 import com.google.android.material.bottomsheet.BottomSheetBehavior
 import com.google.android.material.bottomsheet.BottomSheetDialog
 import com.nextcloud.talk.BuildConfig
 import com.nextcloud.talk.R
 import com.nextcloud.talk.api.NcApi
+import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.controllers.ChatController
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.DialogMessageActionsBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.conversations.Conversation
 import com.nextcloud.talk.models.json.generic.GenericOverall
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
 import com.vanniktech.emoji.EmojiPopup
@@ -53,7 +55,9 @@ import io.reactivex.Observer
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
 import io.reactivex.schedulers.Schedulers
+import javax.inject.Inject
 
+@AutoInjector(NextcloudTalkApplication::class)
 class MessageActionsDialog(
     private val chatController: ChatController,
     private val message: ChatMessage,
@@ -64,16 +68,22 @@ class MessageActionsDialog(
     private val ncApi: NcApi
 ) : BottomSheetDialog(chatController.activity!!) {
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     private lateinit var dialogMessageActionsBinding: DialogMessageActionsBinding
 
     private lateinit var popup: EmojiPopup
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
+
         dialogMessageActionsBinding = DialogMessageActionsBinding.inflate(layoutInflater)
         setContentView(dialogMessageActionsBinding.root)
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
 
+        viewThemeUtils.themeDialog(dialogMessageActionsBinding.root)
         initEmojiBar(hasChatPermission)
         initMenuItemCopy(!message.isDeleted)
         initMenuReplyToMessage(message.replyable && hasChatPermission)
@@ -215,7 +225,7 @@ class MessageActionsDialog(
 
     private fun checkAndSetEmojiSelfReaction(emoji: EmojiTextView) {
         if (emoji.text?.toString() != null && message.reactionsSelf?.contains(emoji.text?.toString()) == true) {
-            emoji.background = AppCompatResources.getDrawable(context, R.drawable.reaction_self_bottom_sheet_background)
+            viewThemeUtils.setCheckedBackground(emoji)
         }
     }
 

+ 12 - 0
app/src/main/java/com/nextcloud/talk/ui/dialog/ScopeDialog.kt

@@ -26,13 +26,18 @@ import android.content.Context
 import android.os.Bundle
 import android.view.View
 import android.view.ViewGroup
+import autodagger.AutoInjector
 import com.google.android.material.bottomsheet.BottomSheetBehavior
 import com.google.android.material.bottomsheet.BottomSheetDialog
 import com.nextcloud.talk.R
+import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.controllers.ProfileController
 import com.nextcloud.talk.databinding.DialogScopeBinding
 import com.nextcloud.talk.models.json.userprofile.Scope
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
+import javax.inject.Inject
 
+@AutoInjector(NextcloudTalkApplication::class)
 class ScopeDialog(
     con: Context,
     private val userInfoAdapter: ProfileController.UserInfoAdapter,
@@ -40,15 +45,22 @@ class ScopeDialog(
     private val position: Int
 ) : BottomSheetDialog(con) {
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     private lateinit var dialogScopeBinding: DialogScopeBinding
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
+
         dialogScopeBinding = DialogScopeBinding.inflate(layoutInflater)
         setContentView(dialogScopeBinding.root)
 
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
 
+        viewThemeUtils.themeDialog(dialogScopeBinding.root)
+
         if (field == ProfileController.Field.DISPLAYNAME || field == ProfileController.Field.EMAIL) {
             dialogScopeBinding.scopePrivate.visibility = View.GONE
         }

+ 10 - 7
app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt

@@ -36,13 +36,13 @@ import android.widget.AdapterView.OnItemSelectedListener
 import android.widget.ArrayAdapter
 import android.widget.ImageView
 import android.widget.TextView
-import androidx.appcompat.app.AlertDialog
 import androidx.core.widget.doAfterTextChanged
 import androidx.fragment.app.DialogFragment
 import androidx.recyclerview.widget.LinearLayoutManager
 import autodagger.AutoInjector
 import com.bluelinelabs.logansquare.LoganSquare
 import com.google.android.material.card.MaterialCardView
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.nextcloud.talk.R
 import com.nextcloud.talk.adapters.PredefinedStatusClickListener
 import com.nextcloud.talk.adapters.PredefinedStatusListAdapter
@@ -166,9 +166,10 @@ class SetStatusDialogFragment :
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
         binding = DialogSetStatusBinding.inflate(LayoutInflater.from(context))
 
-        return AlertDialog.Builder(requireContext())
-            .setView(binding.root)
-            .create()
+        val dialogBuilder = MaterialAlertDialogBuilder(binding.root.context).setView(binding.root)
+        viewThemeUtils.colorMaterialAlertDialogBackground(binding.root.context, dialogBuilder)
+
+        return dialogBuilder.create()
     }
 
     @SuppressLint("DefaultLocale")
@@ -241,10 +242,12 @@ class SetStatusDialogFragment :
             }
         }
 
+        viewThemeUtils.themeDialog(binding.root)
+
         viewThemeUtils.colorMaterialButtonText(binding.clearStatus)
-        viewThemeUtils.colorMaterialButtonBackground(binding.setStatus)
+        viewThemeUtils.colorMaterialButtonPrimaryFilled(binding.setStatus)
 
-        binding.customStatusInput.highlightColor = resources.getColor(R.color.colorPrimary)
+        viewThemeUtils.colorTextInputLayout(binding.customStatusInputContainer)
 
         binding.customStatusInput.doAfterTextChanged { text ->
             binding.setStatus.isEnabled = !text.isNullOrEmpty()
@@ -416,7 +419,7 @@ class SetStatusDialogFragment :
             }
         }
         viewThemeUtils.colorCardViewBackground(views.first)
-        viewThemeUtils.colorTextViewText(views.second)
+        viewThemeUtils.colorPrimaryTextViewElement(views.second)
     }
 
     private fun clearTopStatus() {

+ 11 - 4
app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt

@@ -51,13 +51,14 @@ import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.conversations.Conversation
 import com.nextcloud.talk.models.json.generic.GenericOverall
 import com.nextcloud.talk.models.json.reactions.ReactionsOverall
-import com.nextcloud.talk.ui.theme.ServerTheme
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
 import com.nextcloud.talk.utils.ApiUtils
 import io.reactivex.Observer
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
 import io.reactivex.schedulers.Schedulers
 import java.util.Collections
+import javax.inject.Inject
 
 @AutoInjector(NextcloudTalkApplication::class)
 class ShowReactionsDialog(
@@ -66,10 +67,12 @@ class ShowReactionsDialog(
     private val chatMessage: ChatMessage,
     private val user: User?,
     private val hasChatPermission: Boolean,
-    private val ncApi: NcApi,
-    private val serverTheme: ServerTheme
+    private val ncApi: NcApi
 ) : BottomSheetDialog(activity), ReactionItemClickListener {
 
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
     private lateinit var binding: DialogMessageReactionsBinding
 
     private var adapter: ReactionsAdapter? = null
@@ -78,9 +81,12 @@ class ShowReactionsDialog(
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this)
+
         binding = DialogMessageReactionsBinding.inflate(layoutInflater)
         setContentView(binding.root)
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+        viewThemeUtils.themeDialog(binding.root)
         adapter = ReactionsAdapter(this, user)
         binding.reactionsList.adapter = adapter
         binding.reactionsList.layoutManager = LinearLayoutManager(context)
@@ -98,7 +104,6 @@ class ShowReactionsDialog(
         adapter?.list?.clear()
         if (chatMessage.reactions != null && chatMessage.reactions!!.isNotEmpty()) {
             var reactionsTotal = 0
-            binding.emojiReactionsTabs.setSelectedTabIndicatorColor(serverTheme.primaryColor)
             for ((emoji, amount) in chatMessage.reactions!!) {
                 reactionsTotal = reactionsTotal.plus(amount as Int)
                 val tab: TabLayout.Tab = binding.emojiReactionsTabs.newTab() // Create a new Tab names "First Tab"
@@ -139,6 +144,8 @@ class ShowReactionsDialog(
                 }
             })
 
+            viewThemeUtils.themeTabLayoutOnSurface(binding.emojiReactionsTabs)
+
             updateParticipantsForEmoji(chatMessage, tagAll)
         }
         adapter?.notifyDataSetChanged()

+ 3 - 2
app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java

@@ -120,7 +120,8 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O
      * find all relevant UI elements and set their values.
      */
     private void setupDialogElements() {
-        viewThemeUtils.colorMaterialButtonText(binding.cancel);
+        viewThemeUtils.themeDialog(binding.root);
+        viewThemeUtils.colorMaterialButtonPrimaryBorderless(binding.cancel);
 
         taggedViews = new View[12];
         taggedViews[0] = binding.sortByNameAscending;
@@ -165,7 +166,7 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O
                 viewThemeUtils.colorMaterialButtonText((MaterialButton) view);
             }
             if (view instanceof TextView) {
-                viewThemeUtils.colorTextViewElement((TextView) view);
+                viewThemeUtils.colorPrimaryTextViewElement((TextView) view);
                 ((TextView) view).setTypeface(Typeface.DEFAULT_BOLD);
             }
         }

+ 35 - 0
app/src/main/java/com/nextcloud/talk/ui/theme/MaterialSchemes.kt

@@ -0,0 +1,35 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.ui.theme
+
+import scheme.Scheme
+
+interface MaterialSchemes {
+    /**
+     * Schema for light theme
+     */
+    val lightScheme: Scheme
+
+    /**
+     * Schema for light theme
+     */
+    val darkScheme: Scheme
+}

+ 33 - 0
app/src/main/java/com/nextcloud/talk/ui/theme/MaterialSchemesImpl.kt

@@ -0,0 +1,33 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.ui.theme
+
+import scheme.Scheme
+
+class MaterialSchemesImpl(serverTheme: ServerTheme) : MaterialSchemes {
+    override val lightScheme: Scheme
+    override val darkScheme: Scheme
+
+    init {
+        lightScheme = Scheme.light(serverTheme.primaryColor)
+        darkScheme = Scheme.dark(serverTheme.primaryColor)
+    }
+}

+ 4 - 4
app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProvider.kt → app/src/main/java/com/nextcloud/talk/ui/theme/MaterialSchemesProvider.kt

@@ -24,8 +24,8 @@ package com.nextcloud.talk.ui.theme
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.models.json.capabilities.Capabilities
 
-interface ServerThemeProvider {
-    fun getServerThemeForUser(user: User?): ServerTheme
-    fun getServerThemeForCapabilities(capabilities: Capabilities?): ServerTheme
-    fun getServerThemeForCurrentUser(): ServerTheme
+interface MaterialSchemesProvider {
+    fun getMaterialSchemesForUser(user: User?): MaterialSchemes
+    fun getMaterialSchemesForCapabilities(capabilities: Capabilities?): MaterialSchemes
+    fun getMaterialSchemesForCurrentUser(): MaterialSchemes
 }

+ 9 - 9
app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt → app/src/main/java/com/nextcloud/talk/ui/theme/MaterialSchemesProviderImpl.kt

@@ -30,14 +30,14 @@ import com.nextcloud.talk.utils.ui.ColorUtil
 import java.util.concurrent.ConcurrentHashMap
 import javax.inject.Inject
 
-internal class ServerThemeProviderImpl @Inject constructor(
+internal class MaterialSchemesProviderImpl @Inject constructor(
     private val userProvider: CurrentUserProviderNew,
     private val colorUtil: ColorUtil
-) : ServerThemeProvider {
+) : MaterialSchemesProvider {
 
-    private val themeCache: ConcurrentHashMap<String, ServerTheme> = ConcurrentHashMap()
+    private val themeCache: ConcurrentHashMap<String, MaterialSchemes> = ConcurrentHashMap()
 
-    override fun getServerThemeForUser(user: User?): ServerTheme {
+    override fun getMaterialSchemesForUser(user: User?): MaterialSchemes {
         val url: String = if (user?.baseUrl != null) {
             user.baseUrl!!
         } else {
@@ -45,18 +45,18 @@ internal class ServerThemeProviderImpl @Inject constructor(
         }
 
         if (!themeCache.containsKey(url)) {
-            themeCache[url] = getServerThemeForCapabilities(user?.capabilities)
+            themeCache[url] = getMaterialSchemesForCapabilities(user?.capabilities)
         }
 
         return themeCache[url]!!
     }
 
-    override fun getServerThemeForCurrentUser(): ServerTheme {
-        return getServerThemeForUser(userProvider.currentUser.blockingGet())
+    override fun getMaterialSchemesForCurrentUser(): MaterialSchemes {
+        return getMaterialSchemesForUser(userProvider.currentUser.blockingGet())
     }
 
-    override fun getServerThemeForCapabilities(capabilities: Capabilities?): ServerTheme {
-        return ServerThemeImpl(capabilities?.themingCapability, colorUtil)
+    override fun getMaterialSchemesForCapabilities(capabilities: Capabilities?): MaterialSchemes {
+        return MaterialSchemesImpl(ServerThemeImpl(capabilities?.themingCapability, colorUtil))
     }
 
     companion object {

+ 1 - 4
app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt

@@ -27,8 +27,7 @@ import com.nextcloud.talk.R
 import com.nextcloud.talk.models.json.capabilities.ThemingCapability
 import com.nextcloud.talk.utils.ui.ColorUtil
 
-internal class ServerThemeImpl(themingCapability: ThemingCapability?, colorUtil: ColorUtil) :
-    ServerTheme {
+internal class ServerThemeImpl(themingCapability: ThemingCapability?, colorUtil: ColorUtil) : ServerTheme {
 
     override val primaryColor: Int
     override val colorElement: Int
@@ -38,11 +37,9 @@ internal class ServerThemeImpl(themingCapability: ThemingCapability?, colorUtil:
 
     init {
         primaryColor = colorUtil.getNullSafeColorWithFallbackRes(themingCapability?.color, R.color.colorPrimary)
-
         colorElement = colorUtil.getNullSafeColor(themingCapability?.colorElement, primaryColor)
         colorElementBright = colorUtil.getNullSafeColor(themingCapability?.colorElementBright, primaryColor)
         colorElementDark = colorUtil.getNullSafeColor(themingCapability?.colorElementDark, primaryColor)
-
         colorText = colorUtil.getTextColor(themingCapability?.colorText, primaryColor)
     }
 }

+ 3 - 3
app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt

@@ -33,12 +33,12 @@ internal abstract class ThemeModule {
 
     @Binds
     @Reusable
-    abstract fun bindServerThemeProvider(provider: ServerThemeProviderImpl): ServerThemeProvider
+    abstract fun bindMaterialSchemesProvider(provider: MaterialSchemesProviderImpl): MaterialSchemesProvider
 
     companion object {
         @Provides
-        fun provideCurrentServerTheme(themeProvider: ServerThemeProvider): ServerTheme {
-            return themeProvider.getServerThemeForCurrentUser()
+        fun provideCurrentMaterialSchemes(themeProvider: MaterialSchemesProvider): MaterialSchemes {
+            return themeProvider.getMaterialSchemesForCurrentUser()
         }
     }
 }

+ 567 - 87
app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt

@@ -21,72 +21,191 @@
 
 package com.nextcloud.talk.ui.theme
 
+import android.annotation.TargetApi
+import android.app.Activity
 import android.content.Context
 import android.content.res.ColorStateList
 import android.graphics.Color
 import android.graphics.PorterDuff
 import android.graphics.drawable.Drawable
+import android.graphics.drawable.LayerDrawable
+import android.os.Build
+import android.text.Spannable
+import android.text.SpannableString
+import android.view.MenuItem
 import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
 import android.widget.CheckBox
 import android.widget.EditText
+import android.widget.ImageButton
 import android.widget.ImageView
+import android.widget.LinearLayout
 import android.widget.ProgressBar
 import android.widget.RadioButton
 import android.widget.SeekBar
 import android.widget.TextView
 import androidx.annotation.ColorInt
+import androidx.annotation.DrawableRes
 import androidx.appcompat.content.res.AppCompatResources
+import androidx.appcompat.widget.SearchView
+import androidx.appcompat.widget.SearchView.SearchAutoComplete
 import androidx.appcompat.widget.SwitchCompat
 import androidx.core.content.ContextCompat
 import androidx.core.content.res.ResourcesCompat
+import androidx.core.graphics.ColorUtils
+import androidx.core.graphics.drawable.DrawableCompat
+import androidx.core.view.ViewCompat
 import androidx.core.view.children
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+import com.google.android.material.appbar.MaterialToolbar
 import com.google.android.material.button.MaterialButton
 import com.google.android.material.card.MaterialCardView
 import com.google.android.material.chip.Chip
+import com.google.android.material.chip.ChipDrawable
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.google.android.material.floatingactionbutton.FloatingActionButton
 import com.google.android.material.progressindicator.LinearProgressIndicator
+import com.google.android.material.shape.MaterialShapeDrawable
 import com.google.android.material.tabs.TabLayout
 import com.google.android.material.textfield.TextInputLayout
+import com.google.android.material.textview.MaterialTextView
 import com.nextcloud.talk.R
+import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.DrawableUtils
 import com.nextcloud.talk.utils.ui.ColorUtil
 import com.nextcloud.talk.utils.ui.PlatformThemeUtil.isDarkMode
+import com.vanniktech.emoji.EmojiTextView
 import com.yarolegovich.mp.MaterialPreferenceCategory
 import com.yarolegovich.mp.MaterialSwitchPreference
+import eu.davidea.flexibleadapter.utils.FlexibleUtils
+import scheme.Scheme
 import javax.inject.Inject
+import kotlin.math.roundToInt
 
 @Suppress("TooManyFunctions")
-class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private val colorUtil: ColorUtil) {
+class ViewThemeUtils @Inject constructor(private val schemes: MaterialSchemes, private val colorUtil: ColorUtil) {
 
     /**
-     * Color for painting elements
+     * Scheme for painting elements
      */
-    fun getElementColor(context: Context): Int = when {
-        isDarkMode(context) -> theme.colorElementDark
-        else -> theme.colorElementBright
+    fun getScheme(context: Context): Scheme = when {
+        isDarkMode(context) -> schemes.darkScheme
+        else -> schemes.lightScheme
     }
 
-    private fun withElementColor(view: View, block: (Int) -> Unit) {
-        block(getElementColor(view.context))
+    private fun getSchemeDark(): Scheme = schemes.darkScheme
+
+    private fun withScheme(view: View, block: (Scheme) -> Unit) {
+        block(getScheme(view.context))
+    }
+
+    private fun withScheme(context: Context, block: (Scheme) -> Unit) {
+        block(getScheme(context))
+    }
+
+    private fun withSchemeDark(block: (Scheme) -> Unit) {
+        block(getSchemeDark())
+    }
+
+    fun themeToolbar(toolbar: MaterialToolbar) {
+        withScheme(toolbar) { scheme ->
+            toolbar.setBackgroundColor(scheme.surface)
+            toolbar.setNavigationIconTint(scheme.onSurface)
+            toolbar.setTitleTextColor(scheme.onSurface)
+        }
+    }
+
+    fun colorViewBackground(view: View) {
+        withScheme(view) { scheme ->
+            view.setBackgroundColor(scheme.surface)
+        }
+    }
+
+    fun colorToolbarMenuIcon(context: Context, item: MenuItem) {
+        withScheme(context) { scheme ->
+            item.icon.setColorFilter(scheme.onSurface, PorterDuff.Mode.SRC_ATOP)
+        }
+    }
+
+    fun colorToolbarOverflowIcon(toolbar: MaterialToolbar) {
+        withScheme(toolbar) { scheme ->
+            toolbar.overflowIcon?.setColorFilter(scheme.onSurface, PorterDuff.Mode.SRC_ATOP)
+        }
+    }
+
+    fun themeSearchView(searchView: SearchView) {
+        withScheme(searchView) { scheme ->
+            // hacky as no default way is provided
+            val editText = searchView.findViewById<SearchAutoComplete>(R.id.search_src_text)
+            val searchPlate = searchView.findViewById<LinearLayout>(R.id.search_plate)
+            editText.textSize = SEARCH_TEXT_SIZE
+            editText.setHintTextColor(scheme.onSurfaceVariant)
+            editText.setTextColor(scheme.onSurface)
+            editText.setBackgroundColor(scheme.surface)
+            searchPlate.setBackgroundColor(scheme.surface)
+        }
+    }
+
+    fun themeSearchBarText(searchText: MaterialTextView) {
+        withScheme(searchText) { scheme ->
+            searchText.setHintTextColor(scheme.onSurfaceVariant)
+        }
+    }
+
+    fun themeStatusBar(activity: Activity, view: View) {
+        withScheme(view) { scheme ->
+            DisplayUtils.applyColorToStatusBar(activity, scheme.surface)
+        }
+    }
+
+    fun resetStatusBar(activity: Activity, view: View) {
+        DisplayUtils.applyColorToStatusBar(
+            activity,
+            ResourcesCompat.getColor(
+                activity.resources,
+                R.color.bg_default,
+                activity.theme
+            )
+        )
+    }
+
+    fun themeDialog(view: View) {
+        withScheme(view) { scheme ->
+            view.setBackgroundColor(scheme.surface)
+        }
+    }
+
+    fun themeDialogDark(view: View) {
+        withSchemeDark { scheme ->
+            view.setBackgroundColor(scheme.surface)
+        }
+    }
+
+    fun themeDialogDivider(view: View) {
+        withScheme(view) { scheme ->
+            view.setBackgroundColor(scheme.surfaceVariant)
+        }
     }
 
     fun themeFAB(fab: FloatingActionButton) {
-        withElementColor(fab) { color ->
-            fab.backgroundTintList = ColorStateList.valueOf(color)
-            fab.imageTintList = ColorStateList.valueOf(theme.colorText)
+        withScheme(fab) { scheme ->
+            fab.backgroundTintList = ColorStateList.valueOf(scheme.primaryContainer)
+            fab.imageTintList = ColorStateList.valueOf(scheme.onPrimaryContainer)
         }
     }
 
-    fun themeHorizontalSeekBar(seekBar: SeekBar) {
-        withElementColor(seekBar) { color ->
-            themeHorizontalSeekBar(seekBar, color)
+    fun themeCardView(cardView: MaterialCardView) {
+        withScheme(cardView) { scheme ->
+            cardView.backgroundTintList = ColorStateList.valueOf(scheme.surface)
         }
     }
 
-    fun themeHorizontalSeekBar(seekBar: SeekBar, @ColorInt color: Int) {
-        themeHorizontalProgressBar(seekBar, color)
-        seekBar.thumb.setColorFilter(color, PorterDuff.Mode.SRC_IN)
+    fun themeHorizontalSeekBar(seekBar: SeekBar) {
+        withScheme(seekBar) { scheme ->
+            themeHorizontalProgressBar(seekBar, scheme.primary)
+            seekBar.thumb.setColorFilter(scheme.primary, PorterDuff.Mode.SRC_IN)
+        }
     }
 
     fun themeHorizontalProgressBar(progressBar: ProgressBar?, @ColorInt color: Int) {
@@ -96,23 +215,50 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private
         }
     }
 
-    fun colorTextViewElement(textView: TextView) {
-        withElementColor(textView) { color ->
-            textView.setTextColor(color)
+    fun colorPrimaryTextViewElement(textView: TextView) {
+        withScheme(textView) { scheme ->
+            textView.setTextColor(scheme.primary)
+        }
+    }
+
+    fun colorPrimaryTextViewElementDarkMode(textView: TextView) {
+        withSchemeDark { scheme ->
+            textView.setTextColor(scheme.primary)
         }
     }
 
-    fun colorTextViewText(textView: TextView) {
-        textView.setTextColor(theme.colorText)
+    fun colorPrimaryView(view: View) {
+        withScheme(view) { scheme ->
+            view.setBackgroundColor(scheme.primary)
+        }
     }
 
     /**
      * Colors the background as element color and the foreground as text color.
      */
     fun colorImageViewButton(imageView: ImageView) {
-        withElementColor(imageView) { color ->
-            imageView.imageTintList = ColorStateList.valueOf(theme.colorText)
-            imageView.backgroundTintList = ColorStateList.valueOf(color)
+        withScheme(imageView) { scheme ->
+            imageView.imageTintList = ColorStateList.valueOf(scheme.onPrimaryContainer)
+            imageView.backgroundTintList = ColorStateList.valueOf(scheme.primaryContainer)
+        }
+    }
+
+    fun themeImageButton(imageButton: ImageButton) {
+        withScheme(imageButton) { scheme ->
+            imageButton.imageTintList = ColorStateList(
+                arrayOf(
+                    intArrayOf(android.R.attr.state_selected),
+                    intArrayOf(-android.R.attr.state_selected),
+                    intArrayOf(android.R.attr.state_enabled),
+                    intArrayOf(-android.R.attr.state_enabled)
+                ),
+                intArrayOf(
+                    scheme.primary,
+                    scheme.onSurfaceVariant,
+                    scheme.onSurfaceVariant,
+                    colorUtil.adjustOpacity(scheme.onSurface, ON_SURFACE_OPACITY_BUTTON_DISABLED)
+                )
+            )
         }
     }
 
@@ -120,61 +266,256 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private
      * Tints the image with element color
      */
     fun colorImageView(imageView: ImageView) {
-        withElementColor(imageView) { color ->
-            imageView.imageTintList = ColorStateList.valueOf(color)
+        withScheme(imageView) { scheme ->
+            imageView.imageTintList = ColorStateList.valueOf(scheme.primary)
         }
     }
 
-    /**
-     * Tints the image with text color
-     */
-    fun colorImageViewText(imageView: ImageView) {
-        imageView.imageTintList = ColorStateList.valueOf(theme.colorText)
+    fun colorOutgoingQuoteText(textView: TextView) {
+        withScheme(textView) { scheme ->
+            textView.setTextColor(scheme.onSurfaceVariant)
+        }
+    }
+
+    fun colorOutgoingQuoteAuthorText(textView: TextView) {
+        withScheme(textView) { scheme ->
+            ColorUtils.setAlphaComponent(scheme.onSurfaceVariant, ALPHA_80_INT)
+        }
+    }
+
+    fun colorOutgoingQuoteBackground(view: View) {
+        withScheme(view) { scheme ->
+            view.setBackgroundColor(scheme.onSurfaceVariant)
+        }
+    }
+
+    fun colorMaterialTextButton(button: MaterialButton) {
+        withScheme(button) { scheme ->
+            button.rippleColor = ColorStateList(
+                arrayOf(
+                    intArrayOf(android.R.attr.state_pressed)
+                ),
+                intArrayOf(
+                    colorUtil.adjustOpacity(scheme.primary, SURFACE_OPACITY_BUTTON_DISABLED)
+                )
+            )
+        }
     }
 
     fun colorMaterialButtonText(button: MaterialButton) {
-        withElementColor(button) { color ->
+        withScheme(button) { scheme ->
             val disabledColor = ContextCompat.getColor(button.context, R.color.disabled_text)
             val colorStateList = ColorStateList(
                 arrayOf(
                     intArrayOf(android.R.attr.state_enabled),
                     intArrayOf(-android.R.attr.state_enabled)
                 ),
-                intArrayOf(color, disabledColor)
+                intArrayOf(scheme.primary, disabledColor)
             )
             button.setTextColor(colorStateList)
             button.iconTint = colorStateList
         }
     }
 
-    fun colorMaterialButtonBackground(button: MaterialButton) {
-        withElementColor(button) { color ->
-            button.setBackgroundColor(color)
+    fun colorTextButtons(vararg buttons: Button) {
+        withScheme(buttons[0]) { scheme ->
+            for (button in buttons) {
+                button.setTextColor(
+                    ColorStateList(
+                        arrayOf(
+                            intArrayOf(android.R.attr.state_enabled),
+                            intArrayOf(-android.R.attr.state_enabled)
+                        ),
+                        intArrayOf(
+                            scheme.primary,
+                            colorUtil.adjustOpacity(scheme.onSurface, ON_SURFACE_OPACITY_BUTTON_DISABLED)
+                        )
+                    )
+                )
+            }
+        }
+    }
 
-            val disabledColor = ContextCompat.getColor(button.context, R.color.disabled_text)
-            val colorStateList = ColorStateList(
+    fun colorMaterialButtonPrimaryFilled(button: MaterialButton) {
+        withScheme(button) { scheme ->
+            button.backgroundTintList =
+                ColorStateList(
+                    arrayOf(
+                        intArrayOf(android.R.attr.state_enabled),
+                        intArrayOf(-android.R.attr.state_enabled)
+                    ),
+                    intArrayOf(
+                        scheme.primary,
+                        colorUtil.adjustOpacity(scheme.onSurface, SURFACE_OPACITY_BUTTON_DISABLED)
+                    )
+                )
+
+            button.setTextColor(
+                ColorStateList(
+                    arrayOf(
+                        intArrayOf(android.R.attr.state_enabled),
+                        intArrayOf(-android.R.attr.state_enabled)
+                    ),
+                    intArrayOf(
+                        scheme.onPrimary,
+                        colorUtil.adjustOpacity(scheme.onSurface, ON_SURFACE_OPACITY_BUTTON_DISABLED)
+                    )
+                )
+            )
+
+            button.iconTint = ColorStateList(
                 arrayOf(
                     intArrayOf(android.R.attr.state_enabled),
                     intArrayOf(-android.R.attr.state_enabled)
                 ),
-                intArrayOf(theme.colorText, disabledColor)
+                intArrayOf(
+                    scheme.onPrimary,
+                    colorUtil.adjustOpacity(scheme.onSurface, ON_SURFACE_OPACITY_BUTTON_DISABLED)
+                )
             )
+        }
+    }
 
-            button.setTextColor(colorStateList)
-            button.iconTint = colorStateList
+    fun colorMaterialButtonPrimaryOutlined(button: MaterialButton) {
+        withScheme(button) { scheme ->
+            button.strokeColor = ColorStateList.valueOf(scheme.outline)
+            button.setTextColor(
+                ColorStateList(
+                    arrayOf(
+                        intArrayOf(android.R.attr.state_enabled),
+                        intArrayOf(-android.R.attr.state_enabled)
+                    ),
+                    intArrayOf(
+                        scheme.primary,
+                        colorUtil.adjustOpacity(scheme.onSurface, ON_SURFACE_OPACITY_BUTTON_DISABLED)
+                    )
+                )
+            )
+            button.iconTint = ColorStateList(
+                arrayOf(
+                    intArrayOf(android.R.attr.state_enabled),
+                    intArrayOf(-android.R.attr.state_enabled)
+                ),
+                intArrayOf(
+                    scheme.primary,
+                    colorUtil.adjustOpacity(scheme.onSurface, ON_SURFACE_OPACITY_BUTTON_DISABLED)
+                )
+            )
+        }
+    }
+
+    fun colorMaterialButtonPrimaryBorderless(button: MaterialButton) {
+        withScheme(button) { scheme ->
+            button.setTextColor(
+                ColorStateList(
+                    arrayOf(
+                        intArrayOf(android.R.attr.state_enabled),
+                        intArrayOf(-android.R.attr.state_enabled)
+                    ),
+                    intArrayOf(
+                        scheme.primary,
+                        colorUtil.adjustOpacity(scheme.onSurface, ON_SURFACE_OPACITY_BUTTON_DISABLED)
+                    )
+                )
+            )
+            button.iconTint = ColorStateList(
+                arrayOf(
+                    intArrayOf(android.R.attr.state_enabled),
+                    intArrayOf(-android.R.attr.state_enabled)
+                ),
+                intArrayOf(
+                    scheme.primary,
+                    colorUtil.adjustOpacity(scheme.onSurface, ON_SURFACE_OPACITY_BUTTON_DISABLED)
+                )
+            )
+        }
+    }
+
+    fun themeIncomingMessageBubble(bubble: ViewGroup, grouped: Boolean, deleted: Boolean) {
+        val resources = bubble.resources
+
+        var bubbleResource = R.drawable.shape_incoming_message
+
+        if (grouped) {
+            bubbleResource = R.drawable.shape_grouped_incoming_message
+        }
+
+        val bgBubbleColor = if (deleted) {
+            resources.getColor(R.color.bg_message_list_incoming_bubble_deleted)
+        } else {
+            resources.getColor(R.color.bg_message_list_incoming_bubble)
+        }
+        val bubbleDrawable = DisplayUtils.getMessageSelector(
+            bgBubbleColor,
+            resources.getColor(R.color.transparent),
+            bgBubbleColor, bubbleResource
+        )
+        ViewCompat.setBackground(bubble, bubbleDrawable)
+    }
+
+    fun themeOutgoingMessageBubble(bubble: ViewGroup, grouped: Boolean, deleted: Boolean) {
+        withScheme(bubble) { scheme ->
+            val bgBubbleColor = if (deleted) {
+                ColorUtils.setAlphaComponent(scheme.surfaceVariant, HALF_ALPHA_INT)
+            } else {
+                scheme.surfaceVariant
+            }
+
+            val layout = if (grouped) {
+                R.drawable.shape_grouped_outcoming_message
+            } else {
+                R.drawable.shape_outcoming_message
+            }
+            val bubbleDrawable = DisplayUtils.getMessageSelector(
+                bgBubbleColor,
+                ResourcesCompat.getColor(bubble.resources, R.color.transparent, null),
+                bgBubbleColor,
+                layout
+            )
+            ViewCompat.setBackground(bubble, bubbleDrawable)
         }
     }
 
     fun colorCardViewBackground(card: MaterialCardView) {
-        withElementColor(card) { color ->
-            card.setCardBackgroundColor(color)
+        withScheme(card) { scheme ->
+            card.setCardBackgroundColor(scheme.surfaceVariant)
+        }
+    }
+
+    fun colorContactChatItemName(contactName: androidx.emoji.widget.EmojiTextView) {
+        withScheme(contactName) { scheme ->
+            contactName.setTextColor(scheme.onPrimaryContainer)
+        }
+    }
+
+    fun colorContactChatItemBackground(card: MaterialCardView) {
+        withScheme(card) { scheme ->
+            card.setCardBackgroundColor(scheme.primaryContainer)
+        }
+    }
+
+    fun colorCircularProgressBarOnPrimaryContainer(progressBar: ProgressBar) {
+        withScheme(progressBar) { scheme ->
+            progressBar.indeterminateDrawable.setColorFilter(scheme.onPrimaryContainer, PorterDuff.Mode.SRC_ATOP)
+        }
+    }
+
+    fun colorCircularProgressBar(progressBar: ProgressBar) {
+        withScheme(progressBar) { scheme ->
+            progressBar.indeterminateDrawable.setColorFilter(scheme.primary, PorterDuff.Mode.SRC_ATOP)
+        }
+    }
+
+    fun colorCircularProgressBarOnSurfaceVariant(progressBar: ProgressBar) {
+        withScheme(progressBar) { scheme ->
+            progressBar.indeterminateDrawable.setColorFilter(scheme.onSurfaceVariant, PorterDuff.Mode.SRC_ATOP)
         }
     }
 
     // TODO split this util into classes depending on framework views vs library views
     fun colorPreferenceCategory(category: MaterialPreferenceCategory) {
-        withElementColor(category) { color ->
-            category.setTitleColor(color)
+        withScheme(category) { scheme ->
+            category.setTitleColor(scheme.primary)
         }
     }
 
@@ -188,7 +529,7 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private
     }
 
     fun colorSwitchCompat(switchCompat: SwitchCompat) {
-        withElementColor(switchCompat) { color ->
+        withScheme(switchCompat) { scheme ->
 
             val context = switchCompat.context
 
@@ -203,11 +544,16 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private
                 context.theme
             )
 
-            val trackColor =
-                Color.argb(SWITCHCOMPAT_TRACK_ALPHA, Color.red(color), Color.green(color), Color.blue(color))
+            val trackColor = Color.argb(
+                SWITCH_COMPAT_TRACK_ALPHA,
+                Color.red(scheme.primary),
+                Color.green(scheme.primary),
+                Color.blue(scheme.primary)
+            )
+
             switchCompat.thumbTintList = ColorStateList(
                 arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()),
-                intArrayOf(color, thumbUncheckedColor)
+                intArrayOf(scheme.primary, thumbUncheckedColor)
             )
 
             switchCompat.trackTintList = ColorStateList(
@@ -218,58 +564,49 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private
     }
 
     fun colorDrawable(context: Context, drawable: Drawable) {
-        val color = getElementColor(context)
-        drawable.setTint(color)
+        val scheme = getScheme(context)
+        drawable.setTint(scheme.primary)
     }
 
     fun themeCheckbox(checkbox: CheckBox) {
-        withElementColor(checkbox) { color ->
+        withScheme(checkbox) { scheme ->
             checkbox.buttonTintList = ColorStateList(
                 arrayOf(
                     intArrayOf(-android.R.attr.state_checked),
                     intArrayOf(android.R.attr.state_checked)
                 ),
-                intArrayOf(Color.GRAY, color)
+                intArrayOf(Color.GRAY, scheme.primary)
             )
         }
     }
 
     fun themeRadioButton(radioButton: RadioButton) {
-        withElementColor(radioButton) { color ->
+        withScheme(radioButton) { scheme ->
             radioButton.buttonTintList = ColorStateList(
                 arrayOf(
                     intArrayOf(-android.R.attr.state_checked),
                     intArrayOf(android.R.attr.state_checked)
                 ),
-                intArrayOf(Color.GRAY, color)
+                intArrayOf(Color.GRAY, scheme.primary)
             )
         }
     }
 
     fun themeSwipeRefreshLayout(swipeRefreshLayout: SwipeRefreshLayout) {
-        withElementColor(swipeRefreshLayout) { color ->
-            swipeRefreshLayout.setColorSchemeColors(color)
+        withScheme(swipeRefreshLayout) { scheme ->
+            swipeRefreshLayout.setColorSchemeColors(scheme.primary)
             swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background)
         }
     }
 
     fun colorProgressBar(progressIndicator: LinearProgressIndicator) {
-        withElementColor(progressIndicator) { color ->
-            progressIndicator.setIndicatorColor(progressColor(progressIndicator.context, color))
+        withScheme(progressIndicator) { scheme ->
+            progressIndicator.setIndicatorColor(scheme.primary)
         }
     }
 
-    private fun progressColor(context: Context, color: Int): Int {
-        val lightness = when (isDarkMode(context)) {
-            true -> PROGRESS_LIGHTNESS_DARK_THEME
-            false -> PROGRESS_LIGHTNESS_LIGHT_THEME
-        }
-        return colorUtil.setLightness(color, lightness)
-    }
-
     fun colorEditText(editText: EditText) {
-        withElementColor(editText) { color ->
-            editText.setTextColor(color)
+        withScheme(editText) { scheme ->
             // TODO check API-level compatibility
             // editText.background.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
             editText.backgroundTintList = ColorStateList(
@@ -278,16 +615,18 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private
                     intArrayOf(android.R.attr.state_focused)
                 ),
                 intArrayOf(
-                    Color.GRAY,
-                    color
+                    scheme.outline,
+                    scheme.primary
                 )
             )
+            editText.setHintTextColor(scheme.onSurfaceVariant)
+            editText.setTextColor(scheme.onSurface)
         }
     }
 
     fun colorTextInputLayout(textInputLayout: TextInputLayout) {
-        withElementColor(textInputLayout) { color ->
-            val errorColor = Color.GRAY
+        withScheme(textInputLayout) { scheme ->
+            val errorColor = scheme.onSurfaceVariant
 
             val errorColorStateList = ColorStateList(
                 arrayOf(
@@ -305,8 +644,8 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private
                     intArrayOf(android.R.attr.state_focused)
                 ),
                 intArrayOf(
-                    Color.GRAY,
-                    color
+                    scheme.outline,
+                    scheme.primary
                 )
             )
 
@@ -318,12 +657,32 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private
         }
     }
 
-    fun colorTabLayout(tabLayout: TabLayout) {
-        withElementColor(tabLayout) { color ->
-            tabLayout.setSelectedTabIndicatorColor(color)
+    fun themeTabLayoutOnSurface(tabLayout: TabLayout) {
+        withScheme(tabLayout) { scheme ->
+            tabLayout.setBackgroundColor(scheme.surface)
+            colorTabLayout(tabLayout, scheme)
         }
     }
 
+    fun colorTabLayout(tabLayout: TabLayout, scheme: Scheme) {
+        tabLayout.setSelectedTabIndicatorColor(scheme.primary)
+        tabLayout.tabTextColors = ColorStateList(
+            arrayOf(
+                intArrayOf(android.R.attr.state_selected),
+                intArrayOf(-android.R.attr.state_selected)
+            ),
+            intArrayOf(scheme.primary, ContextCompat.getColor(tabLayout.context, R.color.high_emphasis_text))
+        )
+        tabLayout.tabRippleColor = ColorStateList(
+            arrayOf(
+                intArrayOf(android.R.attr.state_pressed)
+            ),
+            intArrayOf(
+                colorUtil.adjustOpacity(scheme.primary, SURFACE_OPACITY_BUTTON_DISABLED)
+            )
+        )
+    }
+
     fun getPlaceholderImage(context: Context, mimetype: String?): Drawable? {
         val drawableResourceId = DrawableUtils.getDrawableResourceIdForMimeType(mimetype)
         val drawable = AppCompatResources.getDrawable(
@@ -337,28 +696,149 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private
     }
 
     fun colorChipBackground(chip: Chip) {
-        withElementColor(chip) { color ->
-            chip.chipBackgroundColor = ColorStateList.valueOf(color)
-            chip.setTextColor(theme.colorText)
+        withScheme(chip) { scheme ->
+            chip.chipBackgroundColor = ColorStateList.valueOf(scheme.primary)
+            chip.setTextColor(scheme.onPrimary)
         }
     }
 
     fun colorChipOutlined(chip: Chip, strokeWidth: Float) {
-        withElementColor(chip) { color ->
+        withScheme(chip) { scheme ->
             chip.chipBackgroundColor = ColorStateList.valueOf(Color.TRANSPARENT)
             chip.chipStrokeWidth = strokeWidth
-            chip.chipStrokeColor = ColorStateList.valueOf(color)
-            chip.setTextColor(color)
+            chip.chipStrokeColor = ColorStateList.valueOf(scheme.primary)
+            chip.setTextColor(scheme.primary)
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.O)
+    fun themePlaceholderAvatar(avatar: View, @DrawableRes foreground: Int): Drawable? {
+        var drawable: LayerDrawable? = null
+        withScheme(avatar) { scheme ->
+            val layers = arrayOfNulls<Drawable>(2)
+            layers[0] = ContextCompat.getDrawable(avatar.context, R.drawable.ic_avatar_background)
+            layers[0]?.setTint(scheme.surfaceVariant)
+            layers[1] = ContextCompat.getDrawable(avatar.context, foreground)
+            layers[1]?.setTint(scheme.onSurfaceVariant)
+            drawable = LayerDrawable(layers)
+        }
+
+        return drawable
+    }
+
+    fun themePrimaryMentionChip(context: Context, chip: ChipDrawable) {
+        withScheme(context) { scheme ->
+            chip.chipBackgroundColor = ColorStateList.valueOf(scheme.primary)
+            chip.setTextColor(scheme.onPrimary)
+        }
+    }
+
+    fun setCheckedBackground(emoji: EmojiTextView) {
+        withScheme(emoji) { scheme ->
+            val drawable = AppCompatResources
+                .getDrawable(emoji.context, R.drawable.reaction_self_bottom_sheet_background)!!
+                .mutate()
+            DrawableCompat.setTintList(
+                drawable,
+                ColorStateList.valueOf(scheme.primary)
+            )
+            emoji.background = drawable
+        }
+    }
+
+    fun setCheckedBackground(linearLayout: LinearLayout, @ColorInt backgroundColor: Int) {
+        withScheme(linearLayout) { scheme ->
+            val drawable = AppCompatResources
+                .getDrawable(linearLayout.context, R.drawable.reaction_self_background)!!
+                .mutate()
+            DrawableCompat.setTintList(
+                drawable,
+                ColorStateList.valueOf(backgroundColor)
+            )
+            linearLayout.background = drawable
+        }
+    }
+
+    fun colorDialogMenuText(button: MaterialButton) {
+        withScheme(button) { scheme ->
+            button.setTextColor(scheme.onSurface)
+            button.iconTint = ColorStateList.valueOf(scheme.onSurface)
+        }
+    }
+
+    fun colorMaterialAlertDialogBackground(context: Context, dialogBuilder: MaterialAlertDialogBuilder) {
+        withScheme(dialogBuilder.context) { scheme ->
+            val materialShapeDrawable = MaterialShapeDrawable(
+                context,
+                null,
+                com.google.android.material.R.attr.alertDialogStyle,
+                com.google.android.material.R.style.MaterialAlertDialog_MaterialComponents
+            )
+            materialShapeDrawable.initializeElevationOverlay(context)
+            materialShapeDrawable.fillColor = ColorStateList.valueOf(scheme.surface)
+
+            // dialogCornerRadius first appeared in Android Pie
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+                val radius = context.resources.getDimension(R.dimen.dialogBorderRadius)
+                materialShapeDrawable.setCornerSize(radius)
+            }
+
+            dialogBuilder.background = materialShapeDrawable
+        }
+    }
+
+    fun colorDialogHeadline(textView: TextView) {
+        withScheme(textView) { scheme ->
+            textView.setTextColor(scheme.onSurface)
+        }
+    }
+
+    fun colorDialogSupportingText(textView: TextView) {
+        withScheme(textView) { scheme ->
+            textView.setTextColor(scheme.onSurfaceVariant)
+        }
+    }
+
+    fun colorDialogIcon(icon: ImageView) {
+        withScheme(icon) { scheme ->
+            icon.setColorFilter(scheme.secondary)
         }
     }
 
+    fun highlightText(textView: TextView, originalText: String, constraint: String) {
+        withScheme(textView) { scheme ->
+            FlexibleUtils.highlightText(textView, originalText, constraint, scheme.primary)
+        }
+    }
+
+    fun createHighlightedSpan(context: Context, messageSpannable: SpannableString, searchTerm: String): Spannable {
+        var spannable: Spannable = messageSpannable
+        withScheme(context) { scheme ->
+            spannable = DisplayUtils.searchAndColor(messageSpannable, searchTerm, scheme.primary)
+        }
+        return spannable
+    }
+
+    fun colorMaterialAlertDialogIcon(context: Context, drawableId: Int): Drawable {
+        val drawable = AppCompatResources.getDrawable(context, drawableId)!!
+        withScheme(context) { scheme ->
+            DrawableCompat.setTint(drawable, scheme.secondary)
+        }
+        return drawable
+    }
+
     companion object {
         private val THEMEABLE_PLACEHOLDER_IDS = listOf(
             R.drawable.ic_mimetype_package_x_generic,
             R.drawable.ic_mimetype_folder
         )
-        private const val SWITCHCOMPAT_TRACK_ALPHA: Int = 77
-        private const val PROGRESS_LIGHTNESS_LIGHT_THEME: Float = 0.76f
-        private const val PROGRESS_LIGHTNESS_DARK_THEME: Float = 0.28f
+
+        private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt()
+
+        private const val SWITCH_COMPAT_TRACK_ALPHA: Int = 77
+        private const val HALF_ALPHA_INT: Int = 255 / 2
+        private const val SURFACE_OPACITY_BUTTON_DISABLED: Float = 0.12f
+        private const val ON_SURFACE_OPACITY_BUTTON_DISABLED: Float = 0.38f
+        private const val SEARCH_TEXT_SIZE: Float = 16f
     }
 }

+ 18 - 17
app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java

@@ -81,6 +81,7 @@ import com.nextcloud.talk.R;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.data.user.model.User;
 import com.nextcloud.talk.events.UserMentionClickEvent;
+import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.nextcloud.talk.utils.text.Spans;
 
 import org.greenrobot.eventbus.EventBus;
@@ -103,7 +104,6 @@ import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 import androidx.annotation.XmlRes;
 import androidx.appcompat.widget.AppCompatDrawableManager;
-import androidx.appcompat.widget.SearchView;
 import androidx.core.content.ContextCompat;
 import androidx.core.content.res.ResourcesCompat;
 import androidx.core.graphics.ColorUtils;
@@ -297,11 +297,16 @@ public class DisplayUtils {
                                                          User conversationUser,
                                                          String type,
                                                          @XmlRes int chipResource,
-                                                         @Nullable EditText emojiEditText) {
+                                                         @Nullable EditText emojiEditText,
+                                                         ViewThemeUtils viewThemeUtils) {
         ChipDrawable chip = ChipDrawable.createFromResource(context, chipResource);
         chip.setText(EmojiCompat.get().process(label));
         chip.setEllipsize(TextUtils.TruncateAt.MIDDLE);
 
+        if (chipResource == R.xml.chip_you) {
+            viewThemeUtils.themePrimaryMentionChip(context, chip);
+        }
+
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             Configuration config = context.getResources().getConfiguration();
             chip.setLayoutDirection(config.getLayoutDirection());
@@ -367,7 +372,8 @@ public class DisplayUtils {
     public static Spannable searchAndReplaceWithMentionSpan(Context context, Spannable text,
                                                             String id, String label, String type,
                                                             User conversationUser,
-                                                            @XmlRes int chipXmlRes) {
+                                                            @XmlRes int chipXmlRes,
+                                                            ViewThemeUtils viewThemeUtils) {
 
         Spannable spannableString = new SpannableString(text);
         String stringText = text.toString();
@@ -395,10 +401,18 @@ public class DisplayUtils {
                                                                                                    conversationUser,
                                                                                                    type,
                                                                                                    chipXmlRes,
-                                                                                                   null),
+                                                                                                   null,
+                                                                                                   viewThemeUtils),
                                                         BetterImageSpan.ALIGN_CENTER, id,
                                                         label);
             spannableString.setSpan(mentionChipSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            if (chipXmlRes == R.xml.chip_you) {
+                spannableString.setSpan(
+                    new ForegroundColorSpan(viewThemeUtils.getScheme(context).getOnPrimary()),
+                    start,
+                    end,
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            }
             if ("user".equals(type) && !conversationUser.getUserId().equals(id)) {
                 spannableString.setSpan(clickableSpan, start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
             }
@@ -517,19 +531,6 @@ public class DisplayUtils {
         window.setNavigationBarColor(color);
     }
 
-    /**
-     * Theme search view
-     *
-     * @param searchView searchView to be changed
-     * @param context    the app's context
-     */
-    public static void themeSearchView(SearchView searchView, Context context) {
-        // hacky as no default way is provided
-        SearchView.SearchAutoComplete editText = searchView.findViewById(R.id.search_src_text);
-        editText.setTextSize(16);
-        editText.setHintTextColor(context.getResources().getColor(R.color.fontSecondaryAppbar));
-    }
-
     /**
      * beautifies a given URL by removing any http/https protocol prefix.
      *

+ 27 - 8
app/src/main/java/com/nextcloud/talk/utils/preferences/MagicUserInputModule.java

@@ -28,22 +28,30 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.inputmethod.EditorInfo;
 import android.widget.EditText;
-import androidx.appcompat.app.AlertDialog;
-import autodagger.AutoInjector;
+import android.widget.TextView;
+
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
+import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.yarolegovich.mp.io.StandardUserInputModule;
 
-import javax.inject.Inject;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+
+import autodagger.AutoInjector;
+
 @AutoInjector(NextcloudTalkApplication.class)
 public class MagicUserInputModule extends StandardUserInputModule {
 
     @Inject
     AppPreferences appPreferences;
 
+    @Inject
+    ViewThemeUtils viewThemeUtils;
+
     private List<String> keysWithIntegerInput = new ArrayList<>();
 
     public MagicUserInputModule(Context context) {
@@ -65,6 +73,11 @@ public class MagicUserInputModule extends StandardUserInputModule {
             final Listener<String> listener) {
         final View view = LayoutInflater.from(context).inflate(R.layout.dialog_edittext, null);
         final EditText inputField = view.findViewById(R.id.mp_text_input);
+        viewThemeUtils.colorEditText(inputField);
+
+        int paddingStartEnd = Math.round(view.getResources().getDimension(R.dimen.standard_padding));
+        int paddingTopBottom = Math.round(view.getResources().getDimension(R.dimen.dialog_padding_top_bottom));
+        view.setPadding(paddingStartEnd, paddingTopBottom, paddingStartEnd, paddingTopBottom);
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences.getIsKeyboardIncognito()) {
             inputField.setImeOptions(inputField.getImeOptions() | EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING);
@@ -79,11 +92,17 @@ public class MagicUserInputModule extends StandardUserInputModule {
             inputField.setInputType(InputType.TYPE_CLASS_NUMBER);
         }
 
-        final Dialog dialog = new AlertDialog.Builder(context)
-                .setTitle(title)
-                .setView(view)
-                .show();
-        view.findViewById(R.id.mp_btn_confirm).setOnClickListener(new View.OnClickListener() {
+        final MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(view.getContext())
+            .setTitle(title)
+            .setView(view);
+
+        viewThemeUtils.colorMaterialAlertDialogBackground(view.getContext(), dialogBuilder);
+
+        final Dialog dialog = dialogBuilder.show();
+
+        TextView button = view.findViewById(R.id.mp_btn_confirm);
+        viewThemeUtils.colorPrimaryTextViewElement(button);
+        button.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 listener.onInput(inputField.getText().toString());

+ 11 - 0
app/src/main/java/com/nextcloud/talk/utils/ui/ColorUtil.kt

@@ -28,6 +28,7 @@ import androidx.core.content.ContextCompat
 import androidx.core.graphics.ColorUtils
 import com.nextcloud.talk.R
 import javax.inject.Inject
+import kotlin.math.roundToInt
 
 class ColorUtil @Inject constructor(private val context: Context) {
 
@@ -73,6 +74,16 @@ class ColorUtil @Inject constructor(private val context: Context) {
         return this?.let { Color.parseColor(this) } ?: fallback()
     }
 
+    @ColorInt
+    fun adjustOpacity(color: Int, opacity: Float): Int {
+        return Color.argb(
+            (Color.alpha(color) * opacity).roundToInt(),
+            Color.red(color),
+            Color.green(color),
+            Color.blue(color)
+        )
+    }
+
     companion object {
         private const val HSL_SIZE: Int = 3
         private const val INDEX_LIGHTNESS: Int = 2

+ 43 - 0
app/src/main/res/drawable-v24/ic_avatar_background.xml

@@ -0,0 +1,43 @@
+<!--
+  ~ /*
+  ~  * Nextcloud Talk application
+  ~  *
+  ~  * @author Mario Danic
+  ~  * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
+  ~  *
+  ~  * This program is free software: you can redistribute it and/or modify
+  ~  * it under the terms of the GNU General Public License as published by
+  ~  * the Free Software Foundation, either version 3 of the License, or
+  ~  * at your option) any later version.
+  ~  *
+  ~  * This program is distributed in the hope that it will be useful,
+  ~  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  ~  * GNU General Public License for more details.
+  ~  *
+  ~  * You should have received a copy of the GNU General Public License
+  ~  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+  ~  */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108"
+    android:autoMirrored="true">
+  <group android:scaleX="0.08035714"
+      android:scaleY="0.08035714">
+      <path android:fillType="evenOdd"
+          android:pathData="M0,0h1344v1344h-1344z" android:strokeLineJoin="round">
+          <aapt:attr name="android:fillColor">
+              <gradient android:endX="1343.9999"
+                  android:endY="1.2959057E-4" android:startX="163.34073"
+                  android:startY="1344.0002" android:type="linear">
+                  <item android:color="#FF0082C9" android:offset="0"/>
+                  <item android:color="#FF1CAFFF" android:offset="1"/>
+              </gradient>
+          </aapt:attr>
+      </path>
+  </group>
+</vector>

+ 31 - 0
app/src/main/res/drawable/ic_avatar_document.xml

@@ -0,0 +1,31 @@
+<!--
+  ~ Nextcloud Talk application
+  ~
+  ~ @author Andy Scherzinger
+  ~ Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+  ~
+  ~ This program is free software: you can redistribute it and/or modify
+  ~ it under the terms of the GNU General Public License as published by
+  ~ the Free Software Foundation, either version 3 of the License, or
+  ~ at your option) any later version.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  ~ GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License
+  ~ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:autoMirrored="true"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#ffffff"
+        android:fillType="nonZero"
+        android:pathData="M7.4167,6C7.1833,6 7,6.1833 7,6.4167L7,17.25C7,17.4833 7.1833,17.6667 7.4167,17.6667L16.5833,17.6667C16.8167,17.6667 17,17.4833 17,17.25L17,8.5L14.5,6L7.4167,6ZM8.6667,7.6667L13.6667,7.6667L13.6667,8.5L8.6667,8.5L8.6667,7.6667ZM8.6667,10.1667L12.8333,10.1667L12.8333,11L8.6667,11L8.6667,10.1667ZM8.6667,12.6667L15.3333,12.6667L15.3333,13.5L8.6667,13.5L8.6667,12.6667ZM8.6667,15.1667L12,15.1667L12,16L8.6667,16L8.6667,15.1667Z" />
+</vector>

+ 31 - 0
app/src/main/res/drawable/ic_avatar_group.xml

@@ -0,0 +1,31 @@
+<!--
+  ~ Nextcloud Talk application
+  ~
+  ~ @author Andy Scherzinger
+  ~ Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+  ~
+  ~ This program is free software: you can redistribute it and/or modify
+  ~ it under the terms of the GNU General Public License as published by
+  ~ the Free Software Foundation, either version 3 of the License, or
+  ~ at your option) any later version.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  ~ GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License
+  ~ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:autoMirrored="true"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#ffffff"
+        android:fillType="nonZero"
+        android:pathData="M12.729,5C11.044,5 9.833,6.38 9.833,7.702C9.833,9.054 9.93,10.019 10.605,11.08C10.822,11.36 11.074,11.418 11.281,11.659C11.411,12.142 11.513,12.625 11.378,13.107C10.957,13.255 10.557,13.428 10.152,13.59C9.66,13.326 9.09,13.107 8.598,12.914C8.53,12.644 8.579,12.444 8.646,12.19C8.762,12.07 8.868,12.016 8.994,11.901C9.351,11.466 9.37,10.733 9.37,10.212C9.37,9.44 8.675,8.861 7.922,8.861C7.082,8.861 6.474,9.555 6.474,10.212L6.455,10.212C6.455,10.887 6.503,11.37 6.841,11.901C6.938,12.045 7.075,12.07 7.179,12.19C7.244,12.431 7.296,12.673 7.227,12.914C6.61,13.129 6.027,13.397 5.49,13.686C5.085,13.976 5.265,13.862 5.007,14.796C4.888,15.279 6.262,15.501 7.247,15.578C7.198,15.843 7.131,16.196 6.938,16.871C6.629,18.078 11.139,18.512 12.729,18.512C15.074,18.512 18.822,18.072 18.501,16.871C17.999,14.999 18.3,15.221 17.555,14.651C16.503,14.02 15.188,13.525 14.08,13.107C13.935,12.57 14.041,12.171 14.177,11.659C14.403,11.418 14.659,11.312 14.872,11.08C15.537,10.227 15.624,8.741 15.624,7.702C15.624,6.172 14.244,5 12.729,5Z" />
+</vector>

+ 31 - 0
app/src/main/res/drawable/ic_avatar_link.xml

@@ -0,0 +1,31 @@
+<!--
+  ~ Nextcloud Talk application
+  ~
+  ~ @author Andy Scherzinger
+  ~ Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+  ~
+  ~ This program is free software: you can redistribute it and/or modify
+  ~ it under the terms of the GNU General Public License as published by
+  ~ the Free Software Foundation, either version 3 of the License, or
+  ~ at your option) any later version.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  ~ GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License
+  ~ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:autoMirrored="true"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#ffffff"
+        android:fillType="nonZero"
+        android:pathData="M13,5.921L9.818,9.105C9.111,9.812 8.781,10.723 8.83,11.562C8.88,12.401 9.263,13.146 9.818,13.701L11.23,12.285C10.663,11.717 10.686,11.065 11.232,10.519L14.414,7.337C14.939,6.812 15.664,6.814 16.186,7.335C16.668,7.891 16.713,8.574 16.182,9.105L15.362,9.925C15.917,10.71 16.007,11.291 15.955,12.16L17.596,10.519C18.833,9.282 18.833,7.154 17.596,5.917C16.36,4.681 14.254,4.706 13,5.921ZM13.707,9.806L12.293,11.224L12.297,11.224C12.847,11.774 12.804,12.482 12.293,12.994L9.111,16.175C8.415,16.767 7.813,16.646 7.342,16.175C6.715,15.549 6.842,14.907 7.342,14.407L8.192,13.56C7.636,12.777 7.543,12.195 7.594,11.328L5.928,12.994C4.689,14.233 4.692,16.354 5.928,17.589C7.163,18.825 9.29,18.825 10.526,17.589L13.707,14.407C14.416,13.699 14.747,12.789 14.698,11.949C14.65,11.109 14.266,10.362 13.709,9.808L13.707,9.806Z" />
+</vector>

+ 31 - 0
app/src/main/res/drawable/ic_avatar_mail.xml

@@ -0,0 +1,31 @@
+<!--
+  ~ Nextcloud Talk application
+  ~
+  ~ @author Andy Scherzinger
+  ~ Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+  ~
+  ~ This program is free software: you can redistribute it and/or modify
+  ~ it under the terms of the GNU General Public License as published by
+  ~ the Free Software Foundation, either version 3 of the License, or
+  ~ at your option) any later version.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  ~ GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License
+  ~ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:autoMirrored="true"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#ffffff"
+        android:fillType="nonZero"
+        android:pathData="M6.6675,8.25C6.2985,8.25 6,8.55 6,8.9175L6,15.0825C6,15.4522 6.3,15.75 6.6675,15.75L17.3325,15.75C17.7015,15.75 18,15.45 18,15.0825L18,8.9175C18,8.5485 17.7,8.25 17.3325,8.25L6.6675,8.25ZM7.23,9.021L11.7922,13.5825L12.1875,13.5825L16.7708,9.021L17.229,9.4792L14.4998,12.249L16.5623,14.3527L16.104,14.811L14.0002,12.7072L12.48,14.2485L11.5215,14.2485L10.0013,12.7072L7.8975,14.8312L7.4385,14.352L9.522,12.2483L6.7725,9.4785L7.23,9.021Z" />
+</vector>

+ 2 - 2
app/src/main/res/drawable/reaction_self_background.xml

@@ -21,10 +21,10 @@
 
     <stroke
         android:width="1dp"
-        android:color="@color/colorPrimary" />
+        android:color="@color/high_emphasis_text" />
 
     <solid
-        android:color="@color/bg_message_own_reaction" />
+        android:color="#FFFFFF" />
 
     <padding
         android:left="1dp"

+ 3 - 2
app/src/main/res/layout/account_item.xml

@@ -21,14 +21,15 @@
 -->
 <com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
     xmlns:fresco="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="72dp"
     android:layout_margin="4dp"
     android:orientation="horizontal"
     app:cardBackgroundColor="@color/transparent"
-    app:cardElevation="0dp">
+    app:cardElevation="0dp"
+    app:strokeWidth="@dimen/zero">
 
     <RelativeLayout
         android:layout_width="match_parent"

+ 0 - 21
app/src/main/res/layout/activity_main.xml

@@ -115,17 +115,6 @@
                         app:iconSize="@dimen/avatar_size_app_bar"
                         tools:visibility="gone" />
 
-                    <ProgressBar
-                        android:id="@+id/searchProgressBar"
-                        android:layout_width="32dp"
-                        android:layout_height="32dp"
-                        android:padding="4dp"
-                        android:layout_gravity="center"
-                        android:indeterminate="true"
-                        android:indeterminateTint="@color/colorPrimary"
-                        android:scaleType="fitCenter"
-                        android:visibility="gone" />
-
                 </FrameLayout>
 
             </androidx.constraintlayout.widget.ConstraintLayout>
@@ -144,16 +133,6 @@
             app:titleTextColor="@color/fontAppbar"
             tools:title="@string/nc_app_product_name">
 
-            <ProgressBar
-                android:id="@+id/toolbarProgressBar"
-                android:layout_width="32dp"
-                android:layout_height="32dp"
-                android:layout_gravity="center_vertical|end"
-                android:layout_marginEnd="8dp"
-                android:visibility="gone"
-                android:indeterminateTint="@color/white"
-                android:scaleType="fitCenter" />
-
         </com.google.android.material.appbar.MaterialToolbar>
 
     </com.google.android.material.appbar.AppBarLayout>

+ 3 - 2
app/src/main/res/layout/controller_chat.xml

@@ -74,6 +74,7 @@
             app:incomingImageTimeTextSize="12sp"
             app:incomingTextColor="@color/nc_incoming_text_default"
             app:incomingTextLinkColor="@color/nc_incoming_text_default"
+            app:incomingTimeTextColor="@color/no_emphasis_text"
             app:incomingTextSize="@dimen/chat_text_size"
             app:incomingTimeTextSize="12sp"
             app:outcomingBubblePaddingBottom="@dimen/message_bubble_corners_padding"
@@ -84,8 +85,8 @@
             app:outcomingDefaultBubblePressedColor="@color/colorPrimary"
             app:outcomingDefaultBubbleSelectedColor="@color/transparent"
             app:outcomingImageTimeTextSize="12sp"
-            app:outcomingTextColor="@color/nc_outcoming_text_default"
-            app:outcomingTextLinkColor="@color/nc_outcoming_text_default"
+            app:outcomingTextColor="@color/high_emphasis_text"
+            app:outcomingTextLinkColor="@color/high_emphasis_text"
             app:outcomingTextSize="@dimen/chat_text_size"
             app:outcomingTimeTextSize="12sp"
             app:textAutoLink="all" />

+ 43 - 36
app/src/main/res/layout/controller_profile.xml

@@ -29,8 +29,7 @@
     <RelativeLayout
         android:id="@+id/avatarContainer"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingBottom="@dimen/standard_padding">
+        android:layout_height="wrap_content">
 
         <com.facebook.drawee.view.SimpleDraweeView
             android:id="@+id/avatar_image"
@@ -60,7 +59,7 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/userinfo_fullName"
             android:layout_centerHorizontal="true"
-            android:layout_margin="4dp"
+            android:layout_margin="@dimen/standard_quarter_margin"
             android:ellipsize="end"
             android:lines="2"
             android:textColor="@color/medium_emphasis_text"
@@ -72,54 +71,62 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/userinfo_baseurl"
             android:layout_centerInParent="true"
-            android:layout_centerHorizontal="true"
             android:orientation="horizontal"
             android:visibility="invisible"
             tools:visibility="visible">
 
-            <ImageButton
+            <com.google.android.material.floatingactionbutton.FloatingActionButton
                 android:id="@+id/avatar_upload"
-                android:layout_width="@dimen/min_size_clickable_area"
-                android:layout_height="@dimen/min_size_clickable_area"
-                android:layout_marginLeft="@dimen/standard_half_margin"
-                android:layout_marginRight="@dimen/standard_half_margin"
-                android:background="@drawable/round_corner"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/standard_quarter_margin"
+                android:layout_marginRight="@dimen/standard_quarter_margin"
+                android:layout_marginBottom="@dimen/standard_margin"
                 android:contentDescription="@string/upload_new_avatar_from_device"
-                android:src="@drawable/upload"
-                app:tint="@color/black" />
+                android:tint="@android:color/white"
+                app:elevation="0dp"
+                app:fabSize="mini"
+                app:srcCompat="@drawable/upload" />
 
-            <ImageButton
+            <com.google.android.material.floatingactionbutton.FloatingActionButton
                 android:id="@+id/avatar_choose"
-                android:layout_width="@dimen/min_size_clickable_area"
-                android:layout_height="@dimen/min_size_clickable_area"
-                android:layout_marginLeft="@dimen/standard_half_margin"
-                android:layout_marginRight="@dimen/standard_half_margin"
-                android:background="@drawable/round_corner"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/standard_quarter_margin"
+                android:layout_marginRight="@dimen/standard_quarter_margin"
+                android:layout_marginBottom="@dimen/standard_margin"
                 android:contentDescription="@string/choose_avatar_from_cloud"
-                android:src="@drawable/ic_mimetype_folder"
-                app:tint="@color/colorPrimary" />
+                android:tint="@android:color/white"
+                app:elevation="0dp"
+                app:fabSize="mini"
+                app:srcCompat="@drawable/ic_mimetype_folder" />
 
-            <ImageButton
+            <com.google.android.material.floatingactionbutton.FloatingActionButton
                 android:id="@+id/avatar_camera"
-                android:layout_width="@dimen/min_size_clickable_area"
-                android:layout_height="@dimen/min_size_clickable_area"
-                android:layout_marginLeft="@dimen/standard_half_margin"
-                android:layout_marginRight="@dimen/standard_half_margin"
-                android:background="@drawable/round_corner"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/standard_quarter_margin"
+                android:layout_marginRight="@dimen/standard_quarter_margin"
+                android:layout_marginBottom="@dimen/standard_margin"
                 android:contentDescription="@string/set_avatar_from_camera"
-                android:src="@drawable/ic_baseline_photo_camera_24"
-                app:tint="@color/colorPrimary" />
+                android:tint="@android:color/white"
+                app:elevation="0dp"
+                app:fabSize="mini"
+                app:srcCompat="@drawable/ic_baseline_photo_camera_24" />
 
-            <ImageButton
+            <com.google.android.material.floatingactionbutton.FloatingActionButton
                 android:id="@+id/avatar_delete"
-                android:layout_width="@dimen/min_size_clickable_area"
-                android:layout_height="@dimen/min_size_clickable_area"
-                android:layout_marginLeft="@dimen/standard_half_margin"
-                android:layout_marginRight="@dimen/standard_half_margin"
-                android:background="@drawable/round_corner"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/standard_quarter_margin"
+                android:layout_marginRight="@dimen/standard_quarter_margin"
+                android:layout_marginBottom="@dimen/standard_margin"
                 android:contentDescription="@string/delete_avatar"
-                android:src="@drawable/trashbin"
-                app:tint="@color/black" />
+                android:tint="@android:color/white"
+                app:elevation="0dp"
+                app:fabSize="mini"
+                app:srcCompat="@drawable/trashbin" />
+
         </LinearLayout>
 
     </RelativeLayout>

+ 3 - 2
app/src/main/res/layout/current_account_item.xml

@@ -21,14 +21,15 @@
 -->
 <com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
     xmlns:fresco="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="72dp"
     android:layout_margin="4dp"
     android:orientation="horizontal"
     app:cardBackgroundColor="@color/transparent"
-    app:cardElevation="0dp">
+    app:cardElevation="0dp"
+    app:strokeWidth="@dimen/zero">
 
     <RelativeLayout
         tools:background="@color/white"

+ 8 - 14
app/src/main/res/layout/dialog_choose_account.xml

@@ -44,12 +44,6 @@
         app:layout_constraintTop_toBottomOf="@id/current_account"
         tools:visibility="visible">
 
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="1dp"
-            android:layout_marginTop="4dp"
-            android:background="@color/list_divider_background" />
-
         <com.google.android.material.button.MaterialButton
             android:id="@+id/set_status"
             style="@style/Nextcloud.Material.TextButton"
@@ -62,16 +56,16 @@
             android:text="@string/set_status"
             android:textAlignment="textStart"
             android:textAllCaps="false"
-            android:textColor="@color/fontAppbar"
+            android:textColor="@color/high_emphasis_text"
             android:enabled="false"
             app:icon="@drawable/ic_edit"
             app:iconGravity="start"
             app:iconPadding="22dp"
-            app:iconTint="@color/fontAppbar" />
+            app:iconTint="@color/high_emphasis_text" />
     </LinearLayout>
 
     <View
-        android:id="@+id/separator_line"
+        android:id="@+id/divider"
         android:layout_width="0dp"
         android:layout_height="1dp"
         android:layout_marginTop="4dp"
@@ -90,7 +84,7 @@
         app:layout_constraintBottom_toTopOf="@+id/add_account"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/separator_line"
+        app:layout_constraintTop_toBottomOf="@+id/divider"
         tools:listitem="@layout/account_item" />
 
     <com.google.android.material.button.MaterialButton
@@ -105,11 +99,11 @@
         android:text="@string/nc_account_chooser_add_account"
         android:textAlignment="textStart"
         android:textAllCaps="false"
-        android:textColor="@color/fontAppbar"
+        android:textColor="@color/high_emphasis_text"
         app:icon="@drawable/ic_account_plus"
         app:iconGravity="start"
         app:iconPadding="22dp"
-        app:iconTint="@color/fontAppbar"
+        app:iconTint="@color/high_emphasis_text"
         app:layout_constraintBottom_toTopOf="@+id/manage_settings"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent" />
@@ -127,11 +121,11 @@
         android:text="@string/nc_settings"
         android:textAlignment="textStart"
         android:textAllCaps="false"
-        android:textColor="@color/fontAppbar"
+        android:textColor="@color/high_emphasis_text"
         app:icon="@drawable/ic_settings"
         app:iconGravity="start"
         app:iconPadding="22dp"
-        app:iconTint="@color/fontAppbar"
+        app:iconTint="@color/high_emphasis_text"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent" />

+ 1 - 0
app/src/main/res/layout/dialog_poll_loading.xml

@@ -26,6 +26,7 @@
     tools:background="@color/white">
 
     <ProgressBar
+        android:id="@+id/poll_loading_progressbar"
         android:layout_width="25dp"
         android:layout_height="25dp">
     </ProgressBar>

+ 2 - 0
app/src/main/res/layout/item_custom_incoming_location_message.xml

@@ -87,6 +87,8 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/messageText"
             android:layout_marginStart="8dp"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
             app:layout_alignSelf="center" />
 
         <include

+ 2 - 0
app/src/main/res/layout/item_custom_incoming_poll_message.xml

@@ -99,6 +99,8 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/messageText"
             android:layout_marginStart="8dp"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
             app:layout_alignSelf="center"
             tools:text="12:38" />
 

+ 6 - 4
app/src/main/res/layout/item_custom_incoming_preview_message.xml

@@ -87,7 +87,7 @@
             android:layout_height="wrap_content"
             android:layout_margin="2dp"
             android:layout_marginBottom="1dp"
-            app:cardCornerRadius="8dp"
+            app:cardCornerRadius="@dimen/dialogBorderRadius"
             app:cardElevation="2dp"
             app:layout_alignSelf="flex_start"
             app:layout_flexGrow="1"
@@ -152,10 +152,11 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="2dp"
+            android:alpha="0.6"
             android:autoLink="none"
             android:textAlignment="viewStart"
-            android:textColor="@color/warm_grey_four"
-            android:textColorLink="@color/warm_grey_four"
+            android:textColor="@color/no_emphasis_text"
+            android:textColorLink="@color/no_emphasis_text"
             android:textIsSelectable="true"
             android:textSize="12sp"
             app:layout_alignSelf="flex_start"
@@ -170,7 +171,8 @@
             android:layout_alignParentEnd="true"
             android:layout_marginStart="8dp"
             android:layout_marginEnd="2dp"
-            android:textColor="@color/warm_grey_four"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
             app:layout_alignSelf="center"
             tools:text="12:38" />
 

+ 4 - 1
app/src/main/res/layout/item_custom_incoming_text_message.xml

@@ -59,8 +59,9 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginBottom="4dp"
+            android:alpha="0.6"
             android:textAlignment="viewStart"
-            android:textColor="@color/textColorMaxContrast"
+            android:textColor="@color/no_emphasis_text"
             android:textIsSelectable="false"
             android:textSize="12sp"
             tools:text="Jane Doe" />
@@ -83,6 +84,8 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/messageText"
             android:layout_marginStart="8dp"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
             android:textIsSelectable="false"
             app:layout_alignSelf="center" />
 

+ 65 - 63
app/src/main/res/layout/item_custom_incoming_voice_message.xml

@@ -40,77 +40,79 @@
             android:layout_marginEnd="8dp"
             app:roundAsCircle="true" />
 
-        <com.google.android.flexbox.FlexboxLayout
-            android:id="@id/bubble"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/message_incoming_bubble_margin_right"
-            android:layout_toEndOf="@id/messageUserAvatar"
-            android:orientation="vertical"
-            app:alignContent="stretch"
-            app:alignItems="stretch"
-            app:flexWrap="wrap"
-            app:justifyContent="flex_end">
+    <com.google.android.flexbox.FlexboxLayout
+        android:id="@id/bubble"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginEnd="@dimen/message_incoming_bubble_margin_right"
+        android:layout_toEndOf="@id/messageUserAvatar"
+        android:orientation="vertical"
+        app:alignContent="stretch"
+        app:alignItems="stretch"
+        app:flexWrap="wrap"
+        app:justifyContent="flex_end">
 
-                <include
-                    android:id="@+id/message_quote"
-                    layout="@layout/item_message_quote"
-                    android:visibility="gone" />
+        <include
+            android:id="@+id/message_quote"
+            layout="@layout/item_message_quote"
+            android:visibility="gone" />
 
-                <androidx.emoji.widget.EmojiTextView
-                    android:id="@+id/messageAuthor"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginBottom="4dp"
-                    android:textAlignment="viewStart"
-                    android:textColor="@color/textColorMaxContrast"
-                    android:textSize="12sp" />
+        <androidx.emoji.widget.EmojiTextView
+            android:id="@+id/messageAuthor"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="4dp"
+            android:textAlignment="viewStart"
+            android:textColor="@color/textColorMaxContrast"
+            android:textSize="12sp" />
 
-                <LinearLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="horizontal"
-                    android:gravity="center_vertical">
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:orientation="horizontal">
 
-                        <ProgressBar
-                            android:id="@+id/progressBar"
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:layout_gravity="center"
-                            android:visibility="gone"/>
+            <ProgressBar
+                android:id="@+id/progressBar"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:visibility="gone" />
 
-                        <com.google.android.material.button.MaterialButton
-                            android:id="@+id/playPauseBtn"
-                            style="@style/Widget.AppTheme.Button.IconButton"
-                            android:layout_width="48dp"
-                            android:layout_height="48dp"
-                            android:contentDescription="@string/play_pause_voice_message"
-                            android:visibility="visible"
-                            app:cornerRadius="@dimen/button_corner_radius"
-                            app:icon="@drawable/ic_baseline_play_arrow_voice_message_24"
-                            app:iconSize="40dp"
-                            app:iconTint="@color/nc_incoming_text_default" />
+            <com.google.android.material.button.MaterialButton
+                android:id="@+id/playPauseBtn"
+                style="@style/Widget.AppTheme.Button.IconButton"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:contentDescription="@string/play_pause_voice_message"
+                android:visibility="visible"
+                app:cornerRadius="@dimen/button_corner_radius"
+                app:icon="@drawable/ic_baseline_play_arrow_voice_message_24"
+                app:iconSize="40dp"
+                app:iconTint="@color/nc_incoming_text_default" />
 
-                        <SeekBar
-                            android:id="@+id/seekbar"
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            tools:progress="50" />
+            <SeekBar
+                android:id="@+id/seekbar"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                tools:progress="50" />
 
-                </LinearLayout>
+        </LinearLayout>
 
-                <TextView
-                    android:id="@id/messageTime"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_below="@id/messageText"
-                    android:layout_marginStart="8dp"
-                    app:layout_alignSelf="center"
-                    tools:text="12:38"/>
+        <TextView
+            android:id="@id/messageTime"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/messageText"
+            android:layout_marginStart="8dp"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
+            app:layout_alignSelf="center"
+            tools:text="12:38" />
 
-            <include
-                android:id="@+id/reactions"
-                layout="@layout/reactions_inside_message" />
+        <include
+            android:id="@+id/reactions"
+            layout="@layout/reactions_inside_message" />
 
-        </com.google.android.flexbox.FlexboxLayout>
+    </com.google.android.flexbox.FlexboxLayout>
 </RelativeLayout>

+ 5 - 1
app/src/main/res/layout/item_custom_outcoming_location_message.xml

@@ -58,6 +58,7 @@
             android:layout_alignWithParentIfMissing="true"
             android:lineSpacingMultiplier="1.2"
             android:textAlignment="viewStart"
+            android:textColor="@color/high_emphasis_text"
             android:textColorHighlight="@color/nc_grey"
             android:textIsSelectable="false"
             tools:text="Talk to you later!" />
@@ -68,6 +69,8 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/messageText"
             android:layout_marginStart="8dp"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
             app:layout_alignSelf="center"
             tools:text="10:35" />
 
@@ -78,7 +81,8 @@
             android:layout_below="@id/messageTime"
             android:layout_marginStart="8dp"
             android:contentDescription="@null"
-            app:layout_alignSelf="center" />
+            app:layout_alignSelf="center"
+            app:tint="@color/high_emphasis_text" />
 
         <include
             android:id="@+id/reactions"

+ 6 - 6
app/src/main/res/layout/item_custom_outcoming_poll_message.xml

@@ -56,14 +56,13 @@
                 android:layout_height="wrap_content"
                 android:contentDescription="@null"
                 android:src="@drawable/ic_baseline_bar_chart_24"
-                app:tint="@color/nc_outcoming_text_default" />
+                app:tint="@color/high_emphasis_text" />
 
             <androidx.emoji.widget.EmojiTextView
                 android:id="@+id/message_poll_title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:textAlignment="viewStart"
-                android:textColor="@color/nc_outcoming_text_default"
                 android:textStyle="bold"
                 tools:text="This is the poll title?" />
 
@@ -75,7 +74,7 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/double_margin_between_elements"
             android:text="@string/message_poll_tap_to_open"
-            android:textColor="@color/nc_outcoming_text_default" />
+            android:textColor="@color/high_emphasis_text" />
 
         <TextView
             android:id="@id/messageTime"
@@ -83,7 +82,8 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/messageText"
             android:layout_marginStart="8dp"
-            android:textColor="@color/nc_outcoming_text_default"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
             app:layout_alignSelf="center"
             tools:text="10:35" />
 
@@ -94,8 +94,8 @@
             android:layout_below="@id/messageTime"
             android:layout_marginStart="8dp"
             android:contentDescription="@null"
-            android:textColor="@color/nc_outcoming_text_default"
-            app:layout_alignSelf="center" />
+            app:layout_alignSelf="center"
+            app:tint="@color/high_emphasis_text" />
 
         <include
             android:id="@+id/reactions"

+ 6 - 4
app/src/main/res/layout/item_custom_outcoming_preview_message.xml

@@ -77,7 +77,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_margin="2dp"
-            app:cardCornerRadius="8dp"
+            app:cardCornerRadius="@dimen/dialogBorderRadius"
             app:cardElevation="2dp"
             app:layout_alignSelf="flex_start"
             app:layout_flexGrow="1"
@@ -142,9 +142,10 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="2dp"
+            android:alpha="0.6"
             android:autoLink="none"
-            android:textColor="@color/warm_grey_four"
-            android:textColorLink="@color/warm_grey_four"
+            android:textColor="@color/no_emphasis_text"
+            android:textColorLink="@color/no_emphasis_text"
             android:textIsSelectable="true"
             android:textSize="12sp"
             android:visibility="invisible"
@@ -160,7 +161,8 @@
             android:layout_alignParentEnd="true"
             android:layout_marginStart="8dp"
             android:layout_marginEnd="2dp"
-            android:textColor="@color/warm_grey_four"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
             app:layout_alignSelf="center"
             tools:text="12:34" />
 

+ 4 - 1
app/src/main/res/layout/item_custom_outcoming_text_message.xml

@@ -63,6 +63,8 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/messageText"
             android:layout_marginStart="8dp"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
             android:textIsSelectable="false"
             app:layout_alignSelf="center"
             tools:text="10:35" />
@@ -74,7 +76,8 @@
             android:layout_below="@id/messageTime"
             android:layout_marginStart="8dp"
             android:contentDescription="@null"
-            app:layout_alignSelf="center" />
+            app:layout_alignSelf="center"
+            app:tint="@color/high_emphasis_text" />
 
         <include
             android:id="@+id/reactions"

+ 10 - 7
app/src/main/res/layout/item_custom_outcoming_voice_message.xml

@@ -51,17 +51,17 @@
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:gravity="center_vertical">
+            android:gravity="center_vertical"
+            android:orientation="horizontal">
 
             <ProgressBar
                 android:id="@+id/progressBar"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
+                android:indeterminateTint="@color/nc_outcoming_text_default"
                 android:progressTint="@color/fontAppbar"
-                android:visibility="gone"
-                android:indeterminateTint="@color/nc_outcoming_text_default"/>
+                android:visibility="gone" />
 
             <com.google.android.material.button.MaterialButton
                 android:id="@+id/playPauseBtn"
@@ -70,11 +70,11 @@
                 android:layout_height="48dp"
                 android:contentDescription="@string/play_pause_voice_message"
                 android:visibility="visible"
-                app:rippleColor="#1FFFFFFF"
                 app:cornerRadius="@dimen/button_corner_radius"
                 app:icon="@drawable/ic_baseline_play_arrow_voice_message_24"
                 app:iconSize="40dp"
-                app:iconTint="@color/nc_outcoming_text_default" />
+                app:iconTint="@color/high_emphasis_text"
+                app:rippleColor="#1FFFFFFF" />
 
             <SeekBar
                 android:id="@+id/seekbar"
@@ -92,6 +92,8 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/messageText"
             android:layout_marginStart="8dp"
+            android:alpha="0.6"
+            android:textColor="@color/no_emphasis_text"
             app:layout_alignSelf="center"
             tools:text="10:35" />
 
@@ -101,8 +103,9 @@
             android:layout_height="wrap_content"
             android:layout_below="@id/messageTime"
             android:layout_marginStart="8dp"
+            android:contentDescription="@null"
             app:layout_alignSelf="center"
-            android:contentDescription="@null" />
+            app:tint="@color/high_emphasis_text" />
 
         <include
             android:id="@+id/reactions"

+ 9 - 6
app/src/main/res/layout/item_message_quote.xml

@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--
+<?xml version="1.0" encoding="utf-8"?>
+<!--
   ~ Nextcloud Talk application
   ~
   ~ @author Mario Danic
@@ -34,8 +35,8 @@
         android:layout_height="match_parent"
         android:layout_alignBottom="@id/flexboxQuoted"
         android:layout_alignParentStart="true"
-        android:layout_marginEnd="4dp"
-        android:background="@color/colorPrimary" />
+        android:layout_marginEnd="8dp"
+        android:background="@color/high_emphasis_text" />
 
     <androidx.emoji.widget.EmojiTextView
         android:id="@+id/quotedMessageAuthor"
@@ -44,9 +45,10 @@
         android:layout_alignParentTop="true"
         android:layout_marginEnd="8dp"
         android:layout_toEndOf="@id/quoteColoredView"
+        android:alpha="0.6"
         android:ellipsize="end"
         android:textAlignment="viewStart"
-        android:textColor="@color/textColorMaxContrast"
+        android:textColor="@color/no_emphasis_text"
         android:textIsSelectable="false"
         android:textSize="12sp"
         tools:text="Jane Doe" />
@@ -85,6 +87,7 @@
             android:layout_alignStart="@id/quotedMessageAuthor"
             android:lineSpacingMultiplier="1.2"
             android:textAlignment="viewStart"
+            android:textColor="@color/high_emphasis_text"
             android:textIsSelectable="false"
             android:textSize="14sp"
             app:layout_alignSelf="flex_start"
@@ -102,9 +105,9 @@
         android:layout_centerVertical="true"
         android:layout_marginStart="8dp"
         android:layout_marginEnd="8dp"
-        android:background="@drawable/ic_cancel_black_24dp"
-        android:backgroundTint="@color/grey_600"
+        android:background="@color/transparent"
         android:contentDescription="@string/nc_message_quote_cancel_reply"
+        android:src="@drawable/ic_cancel_black_24dp"
         android:visibility="gone"
         tools:visibility="visible" />
 

+ 0 - 11
app/src/main/res/layout/search_layout.xml

@@ -104,17 +104,6 @@
                     app:iconSize="@dimen/avatar_size_app_bar"
                     tools:visibility="visible" />
 
-                <ProgressBar
-                    android:id="@+id/searchProgressBar"
-                    android:layout_width="32dp"
-                    android:layout_height="32dp"
-                    android:padding="4dp"
-                    android:layout_gravity="center"
-                    android:indeterminate="true"
-                    android:indeterminateTint="@color/colorPrimary"
-                    android:scaleType="fitCenter"
-                    android:visibility="gone" />
-
             </FrameLayout>
 
         </androidx.constraintlayout.widget.ConstraintLayout>

+ 5 - 2
app/src/main/res/layout/sorting_order_fragment.xml

@@ -293,9 +293,12 @@
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:gravity="end">
+        android:gravity="end"
+        android:paddingStart="@dimen/dialog_padding"
+        android:paddingEnd="@dimen/dialog_padding"
+        android:paddingBottom="@dimen/dialog_padding_top_bottom">
 
-        <com.google.android.material.button.MaterialButton
+    <com.google.android.material.button.MaterialButton
             android:id="@+id/cancel"
             style="@style/Button.Borderless"
             android:layout_width="wrap_content"

+ 2 - 1
app/src/main/res/values-night/colors.xml

@@ -35,6 +35,7 @@
     <color name="refresh_spinner_background">#222222</color>
 
     <!-- general text colors -->
+    <color name="no_emphasis_text">#ffffff</color>
     <color name="high_emphasis_text">#deffffff</color>
     <color name="medium_emphasis_text">#99ffffff</color>
     <color name="low_emphasis_text">#61ffffff</color>
@@ -71,7 +72,7 @@
     <color name="nc_shimmer_default_color">#4B4B4B</color>
     <color name="nc_shimmer_darker_color">#282828</color>
 
-    <color name="list_divider_background">#222222</color>
+    <color name="list_divider_background">#1FFFFFFF</color>
     <color name="grey_200">#818181</color>
 
     <color name="dialog_background">#353535</color>

+ 2 - 1
app/src/main/res/values/colors.xml

@@ -36,6 +36,7 @@
     <color name="refresh_spinner_background">#ffffff</color>
 
     <!-- general text colors -->
+    <color name="no_emphasis_text">#000000</color>
     <color name="high_emphasis_text">#de000000</color>
     <color name="medium_emphasis_text">#99000000</color>
     <color name="low_emphasis_text">#61000000</color>
@@ -99,7 +100,7 @@
 
     <color name="camera_bg_tint">#99121212</color>
 
-    <color name="list_divider_background">#eeeeee</color>
+    <color name="list_divider_background">#1F121212</color>
     <color name="grey_200">#EEEEEE</color>
 
     <!-- this is just a helper for status icon background because getting the background color of a dialog is not

+ 4 - 2
app/src/main/res/values/dimens.xml

@@ -37,8 +37,8 @@
     <dimen name="avatar_size_big">96dp</dimen>
 
     <dimen name="chat_text_size">14sp</dimen>
-    <dimen name="message_bubble_corners_radius">6dp</dimen>
-    <dimen name="message_bubble_corners_padding">8dp</dimen>
+    <dimen name="message_bubble_corners_radius">@dimen/dialogBorderRadius</dimen>
+    <dimen name="message_bubble_corners_padding">16dp</dimen>
 
     <dimen name="geocoding_result_text_size">18sp</dimen>
 
@@ -74,6 +74,8 @@
     <dimen name="standard_eighth_margin">2dp</dimen>
     <dimen name="scope_padding">12dp</dimen>
 
+    <dimen name="dialogBorderRadius">28dp</dimen>
+
     <dimen name="default_checkbox_dialog_start_margin">18dp</dimen>
 
     <dimen name="mediatab_file_icon_size">50dp</dimen>

+ 17 - 14
app/src/main/res/values/styles.xml

@@ -23,7 +23,7 @@
 <resources>
 
     <!-- Base application theme. -->
-    <style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge">
+    <style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar">
         <!-- Customize your theme here. -->
         <item name="colorPrimary">@color/colorPrimary</item>
         <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
@@ -42,10 +42,12 @@
         <item name="seekBarStyle">@style/Nextcloud.Material.Incoming.SeekBar</item>
         <item name="bottomSheetDialogTheme">@style/ThemeOverlay.App.BottomSheetDialog</item>
         <item name="popupMenuStyle">@style/ChatSendButtonMenu</item>
+        <item name="dialogCornerRadius">@dimen/dialogBorderRadius</item>
     </style>
 
-    <style name="ThemeOverlay.AppTheme.PopupMenu" parent="ThemeOverlay.MaterialComponents.Dark">
+    <style name="ThemeOverlay.AppTheme.PopupMenu" parent="ThemeOverlay.Material3.Dark">
         <item name="android:colorBackground">@color/bg_default</item>
+        <item name="colorSurface">@color/bg_default</item>
         <item name="android:textColorPrimary">@color/high_emphasis_text</item>
         <item name="android:textColor">@color/high_emphasis_text</item>
         <item name="android:textColorSecondary">@color/fontAppbar</item>
@@ -53,7 +55,7 @@
         <item name="iconTint">@color/fontAppbar</item>
     </style>
 
-    <style name="ChatSendButtonMenu" parent="@style/Widget.AppCompat.PopupMenu">
+    <style name="ChatSendButtonMenu" parent="@style/Widget.Material3.PopupMenu">
         <item name="android:dropDownVerticalOffset">-90dp</item>
         <item name="android:colorPrimary">@color/fg_inverse</item>
         <item name="android:textColorSecondary">@color/fontAppbar</item>
@@ -65,16 +67,16 @@
 
     <style name="CallButtonMenu" parent="@style/ChatSendButtonMenu" />
 
-    <style name="ThemeOverlay.App.BottomSheetDialog" parent="ThemeOverlay.MaterialComponents.DayNight.BottomSheetDialog">
+    <style name="ThemeOverlay.App.BottomSheetDialog" parent="ThemeOverlay.Material3.DayNight.BottomSheetDialog">
         <item name="bottomSheetStyle">@style/Talk.BottomSheetDialog</item>
     </style>
 
-    <style name="Talk.BottomSheetDialog" parent="Widget.MaterialComponents.BottomSheet.Modal">
+    <style name="Talk.BottomSheetDialog" parent="Widget.Material3.BottomSheet.Modal">
         <item name="backgroundTint">@color/bg_bottom_sheet</item>
         <item name="shapeAppearanceOverlay">@style/CustomShapeAppearanceBottomSheetDialog</item>
     </style>
 
-    <style name="TransparentTheme" parent="Theme.MaterialComponents.NoActionBar.Bridge">
+    <style name="TransparentTheme" parent="Theme.MaterialComponents.NoActionBar">
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowBackground">@android:color/background_dark</item>
         <item name="android:colorBackgroundCacheHint">@null</item>
@@ -109,11 +111,12 @@
         <item name="android:textStyle">bold</item>
     </style>
 
-    <style name="appActionBarPopupMenu" parent="@style/Widget.AppCompat.PopupMenu.Overflow">
+    <style name="appActionBarPopupMenu" parent="@style/Widget.Material3.PopupMenu.Overflow">
         <item name="android:colorPrimary">@color/fg_inverse</item>
         <item name="android:textColorSecondary">@color/fontAppbar</item>
         <item name="android:itemBackground">@color/appbar</item>
         <item name="android:background">@color/appbar</item>
+        <item name="android:backgroundTint">@color/appbar</item>
         <item name="android:textColor">@color/high_emphasis_text</item>
         <item name="iconTint">@color/fontAppbar</item>
     </style>
@@ -134,7 +137,7 @@
         <item name="searchHintIcon">@null</item>
     </style>
 
-    <style name="Button" parent="Widget.MaterialComponents.Button.UnelevatedButton">
+    <style name="Button" parent="Widget.Material3.Button.UnelevatedButton">
         <item name="colorButtonNormal">@color/colorPrimary</item>
         <item name="android:textColor">@color/white</item>
         <item name="android:textAllCaps">false</item>
@@ -150,7 +153,7 @@
         <item name="android:layout_gravity">center_vertical</item>
     </style>
 
-    <style name="Widget.AppTheme.Button.IconButton" parent="Widget.MaterialComponents.Button.TextButton">
+    <style name="Widget.AppTheme.Button.IconButton" parent="Widget.Material3.Button.TextButton">
         <item name="android:minWidth">0dp</item>
         <item name="android:insetLeft">0dp</item>
         <item name="android:insetTop">0dp</item>
@@ -160,14 +163,14 @@
         <item name="iconPadding">0dp</item>
     </style>
 
-    <style name="Button.Borderless" parent="Widget.MaterialComponents.Button.TextButton">
+    <style name="Button.Borderless" parent="Widget.Material3.Button.TextButton">
         <item name="android:textColor">@drawable/borderless_btn</item>
         <item name="android:textAllCaps">false</item>
         <item name="android:typeface">sans</item>
         <item name="android:textStyle">bold</item>
     </style>
 
-    <style name="Widget.App.Login.TextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
+    <style name="Widget.App.Login.TextInputLayout" parent="Widget.Material3.TextInputLayout.OutlinedBox">
         <item name="colorControlActivated">@color/white</item>
         <item name="colorControlHighlight">@color/white</item>
         <item name="materialThemeOverlay">@style/ThemeOverlay.App.Login.TextInputLayout</item>
@@ -185,7 +188,7 @@
         <item name="editTextStyle">@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox</item>
     </style>
 
-    <style name="TextInputLayoutLogin" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
+    <style name="TextInputLayoutLogin" parent="Widget.Material3.TextInputLayout.OutlinedBox">
         <item name="boxStrokeColor">@color/white</item>
         <item name="boxStrokeErrorColor">@color/white</item>
         <item name="hintTextAppearance">@style/HintTextLogin</item>
@@ -237,7 +240,7 @@
         <item name="android:navigationBarColor">@color/grey950</item>
     </style>
 
-    <style name="Nextcloud.Material.TextButton" parent="Widget.MaterialComponents.Button.TextButton.Icon">
+    <style name="Nextcloud.Material.TextButton" parent="Widget.Material3.Button.TextButton.Icon">
         <item name="android:typeface">sans</item>
         <item name="android:textStyle">bold</item>
     </style>
@@ -263,7 +266,7 @@
         <item name="cornerSizeBottomLeft">0dp</item>
     </style>
 
-    <style name="OutlinedButton" parent="Widget.MaterialComponents.Button.OutlinedButton">
+    <style name="OutlinedButton" parent="Widget.Material3.Button.OutlinedButton">
         <item name="colorAccent">@color/transparent</item>
         <item name="android:textColor">@color/colorPrimaryDark</item>
         <item name="android:textAllCaps">false</item>

Some files were not shown because too many files changed in this diff