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

🎨 Material 3️⃣
This commit is contained in:
Andy Scherzinger 2022-08-11 23:00:01 +02:00 committed by GitHub
commit 2bd7688f9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
127 changed files with 5872 additions and 1088 deletions

View File

@ -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") {

View File

@ -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")
}

View File

@ -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")

View File

@ -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)

View File

@ -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(() -> {

View File

@ -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());
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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));
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 (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 (status != null && status.equals(StatusType.DND.getString())) {
if (statusMessage == null || statusMessage.isEmpty()) {
holder.binding.conversationInfoStatusMessage.setText(R.string.dnd);
}
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);
}
} else if (status != null && status.equals(StatusType.AWAY.getString())) {
if (statusMessage == null || statusMessage.isEmpty()) {
holder.binding.conversationInfoStatusMessage.setText(R.string.away);
}
}
}

View File

@ -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
}

View File

@ -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())) {

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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;
}

View File

@ -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)
}

View File

@ -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") {

View File

@ -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()
}
}

View File

@ -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();

View File

@ -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()
}
}

View File

@ -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
}
}

View File

@ -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;
}

View File

@ -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()
}
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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()
}
}

View File

@ -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()
}

View File

@ -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)

View File

@ -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() {

View File

@ -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) {

View File

@ -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) {

View File

@ -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)

View File

@ -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);
}
}
}

View File

@ -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) }
}
}
}

View File

@ -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

View File

@ -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")) {

View File

@ -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));
}

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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? {

View File

@ -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(

View File

@ -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)

View File

@ -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
}

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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)

View File

@ -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() {

View File

@ -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()

View File

@ -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")

View File

@ -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,7 +153,39 @@ public class ChooseAccountDialogFragment extends DialogFragment {
loadCurrentStatus(user);
}
}
private void setupAdapter() {
if (adapter == null) {
adapter = new FlexibleAdapter<>(userItems, getActivity(), false);
User userEntity;
Participant participant;
for (Object userItem : userManager.getUsers().blockingGet()) {
userEntity = (User) userItem;
if (!userEntity.getCurrent()) {
String userId;
if (userEntity.getUserId() != null) {
userId = userEntity.getUserId();
} else {
userId = userEntity.getUsername();
}
participant = new Participant();
participant.setActorType(Participant.ActorType.USERS);
participant.setActorId(userId);
participant.setDisplayName(userEntity.getDisplayName());
userItems.add(new AdvancedUserItem(participant, userEntity, null, viewThemeUtils));
}
}
adapter.addListener(onSwitchItemClickListener);
adapter.updateDataSet(userItems, false);
}
}
private void setupListeners(User user) {
// Creating listeners for quick-actions
binding.currentAccount.getRoot().setOnClickListener(v -> dismiss());
@ -173,36 +210,18 @@ public class ChooseAccountDialogFragment extends DialogFragment {
Log.w(TAG, "status was null");
}
});
}
if (adapter == null) {
adapter = new FlexibleAdapter<>(userItems, getActivity(), false);
private void themeViews() {
viewThemeUtils.themeDialog(binding.getRoot());
viewThemeUtils.themeDialogDivider(binding.divider);
User userEntity;
Participant participant;
for (Object userItem : userManager.getUsers().blockingGet()) {
userEntity = (User) userItem;
if (!userEntity.getCurrent()) {
String userId;
if (userEntity.getUserId() != null) {
userId = userEntity.getUserId();
} else {
userId = userEntity.getUsername();
}
participant = new Participant();
participant.setActorType(Participant.ActorType.USERS);
participant.setActorId(userId);
participant.setDisplayName(userEntity.getDisplayName());
userItems.add(new AdvancedUserItem(participant, userEntity, null));
}
}
adapter.addListener(onSwitchItemClickListener);
adapter.updateDataSet(userItems, false);
}
prepareViews();
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);

View File

@ -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)
}

View File

@ -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()

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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.colorMaterialButtonText(binding.clearStatus)
viewThemeUtils.colorMaterialButtonBackground(binding.setStatus)
viewThemeUtils.themeDialog(binding.root)
binding.customStatusInput.highlightColor = resources.getColor(R.color.colorPrimary)
viewThemeUtils.colorMaterialButtonText(binding.clearStatus)
viewThemeUtils.colorMaterialButtonPrimaryFilled(binding.setStatus)
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() {

View File

@ -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()

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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()
}
}
}

View File

@ -21,74 +21,193 @@
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 themeCardView(cardView: MaterialCardView) {
withScheme(cardView) { scheme ->
cardView.backgroundTintList = ColorStateList.valueOf(scheme.surface)
}
}
fun themeHorizontalSeekBar(seekBar: SeekBar) {
withElementColor(seekBar) { color ->
themeHorizontalSeekBar(seekBar, color)
withScheme(seekBar) { scheme ->
themeHorizontalProgressBar(seekBar, scheme.primary)
seekBar.thumb.setColorFilter(scheme.primary, PorterDuff.Mode.SRC_IN)
}
}
fun themeHorizontalSeekBar(seekBar: SeekBar, @ColorInt color: Int) {
themeHorizontalProgressBar(seekBar, color)
seekBar.thumb.setColorFilter(color, PorterDuff.Mode.SRC_IN)
}
fun themeHorizontalProgressBar(progressBar: ProgressBar?, @ColorInt color: Int) {
if (progressBar != null) {
progressBar.indeterminateDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN)
@ -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 colorTextViewText(textView: TextView) {
textView.setTextColor(theme.colorText)
fun colorPrimaryTextViewElementDarkMode(textView: TextView) {
withSchemeDark { scheme ->
textView.setTextColor(scheme.primary)
}
}
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
}
}

View File

@ -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.
*

View File

@ -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());

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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"

View File

@ -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>

View File

@ -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" />

View File

@ -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>

View File

@ -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"

View File

@ -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" />

View File

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

View File

@ -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

View File

@ -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" />

View File

@ -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" />

View File

@ -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" />

View File

@ -40,77 +40,79 @@
android:layout_marginEnd="8dp"
app:roundAsCircle="true" />
<com.google.android.flexbox.FlexboxLayout
android:id="@id/bubble"
<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" />
<androidx.emoji.widget.EmojiTextView
android:id="@+id/messageAuthor"
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">
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:textAlignment="viewStart"
android:textColor="@color/textColorMaxContrast"
android:textSize="12sp" />
<include
android:id="@+id/message_quote"
layout="@layout/item_message_quote"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<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" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<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" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:progress="50" />
<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" />
</LinearLayout>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:progress="50" />
<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" />
</LinearLayout>
<include
android:id="@+id/reactions"
layout="@layout/reactions_inside_message" />
<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"/>
<include
android:id="@+id/reactions"
layout="@layout/reactions_inside_message" />
</com.google.android.flexbox.FlexboxLayout>
</com.google.android.flexbox.FlexboxLayout>
</RelativeLayout>

View File

@ -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"

View File

@ -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"

View File

@ -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" />

View File

@ -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"

View File

@ -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"

View File

@ -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" />

View File

@ -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>

View File

@ -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"

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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 have changed in this diff Show More