mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-23 05:25:31 +03:00
Merge pull request #2217 from nextcloud/feature/250/server-theme
🎨 Server theming
This commit is contained in:
commit
ce71746461
74 changed files with 1457 additions and 369 deletions
|
@ -79,6 +79,7 @@ android {
|
|||
disable 'InvalidPackage'
|
||||
disable 'MissingTranslation'
|
||||
disable 'VectorPath'
|
||||
disable 'UnusedQuantity'
|
||||
}
|
||||
|
||||
javaCompileOptions {
|
||||
|
|
|
@ -41,8 +41,10 @@ import android.widget.Toast;
|
|||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.nextcloud.talk.R;
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||
import com.nextcloud.talk.databinding.ActivityTakePictureBinding;
|
||||
import com.nextcloud.talk.models.TakePictureViewModel;
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils;
|
||||
import com.nextcloud.talk.utils.BitmapShrinker;
|
||||
import com.nextcloud.talk.utils.FileUtils;
|
||||
|
||||
|
@ -52,6 +54,8 @@ import java.util.Date;
|
|||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.OptIn;
|
||||
|
@ -66,9 +70,11 @@ import androidx.camera.lifecycle.ProcessCameraProvider;
|
|||
import androidx.core.content.ContextCompat;
|
||||
import androidx.exifinterface.media.ExifInterface;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import autodagger.AutoInjector;
|
||||
|
||||
import static com.nextcloud.talk.utils.Mimetype.IMAGE_JPEG;
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication.class)
|
||||
public class TakePhotoActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TAG = TakePhotoActivity.class.getSimpleName();
|
||||
|
@ -86,15 +92,22 @@ public class TakePhotoActivity extends AppCompatActivity {
|
|||
|
||||
private Camera camera;
|
||||
|
||||
@Inject
|
||||
ViewThemeUtils viewThemeUtils;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
|
||||
|
||||
binding = ActivityTakePictureBinding.inflate(getLayoutInflater());
|
||||
viewModel = new ViewModelProvider(this).get(TakePictureViewModel.class);
|
||||
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
viewThemeUtils.themeFAB(binding.takePhoto);
|
||||
viewThemeUtils.colorMaterialButtonBackground(binding.send);
|
||||
|
||||
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
|
||||
cameraProviderFuture.addListener(() -> {
|
||||
try {
|
||||
|
|
|
@ -35,6 +35,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication;
|
|||
import com.nextcloud.talk.data.user.model.User;
|
||||
import com.nextcloud.talk.databinding.RvItemContactBinding;
|
||||
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;
|
||||
|
||||
|
@ -59,14 +60,17 @@ public class ContactItem extends AbstractFlexibleItem<ContactItem.ContactItemVie
|
|||
private final Participant participant;
|
||||
private final User user;
|
||||
private GenericTextHeaderItem header;
|
||||
private final ViewThemeUtils viewThemeUtils;
|
||||
public boolean isOnline = true;
|
||||
|
||||
public ContactItem(Participant participant,
|
||||
User user,
|
||||
GenericTextHeaderItem genericTextHeaderItem) {
|
||||
GenericTextHeaderItem genericTextHeaderItem,
|
||||
ViewThemeUtils viewThemeUtils) {
|
||||
this.participant = participant;
|
||||
this.user = user;
|
||||
this.header = genericTextHeaderItem;
|
||||
this.viewThemeUtils = viewThemeUtils;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -108,6 +112,7 @@ public class ContactItem extends AbstractFlexibleItem<ContactItem.ContactItemVie
|
|||
holder.binding.avatarDraweeView.setController(null);
|
||||
|
||||
if (participant.getSelected()) {
|
||||
viewThemeUtils.colorImageView(holder.binding.checkedImageView);
|
||||
holder.binding.checkedImageView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.binding.checkedImageView.setVisibility(View.GONE);
|
||||
|
|
|
@ -27,7 +27,6 @@ package com.nextcloud.talk.adapters.items;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
|
@ -46,6 +45,7 @@ import com.nextcloud.talk.models.json.chat.ChatMessage;
|
|||
import com.nextcloud.talk.models.json.conversations.Conversation;
|
||||
import com.nextcloud.talk.models.json.status.Status;
|
||||
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 com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
|
||||
|
@ -76,22 +76,22 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
|
|||
private final Context context;
|
||||
private GenericTextHeaderItem header;
|
||||
private final Status status;
|
||||
private final ViewThemeUtils viewThemeUtils;
|
||||
|
||||
|
||||
public ConversationItem(Conversation conversation, User user, Context activityContext, Status status) {
|
||||
public ConversationItem(Conversation conversation, User user, Context activityContext, Status status, final ViewThemeUtils viewThemeUtils) {
|
||||
this.conversation = conversation;
|
||||
this.user = user;
|
||||
this.context = activityContext;
|
||||
this.status = status;
|
||||
this.viewThemeUtils = viewThemeUtils;
|
||||
}
|
||||
|
||||
public ConversationItem(Conversation conversation, User user,
|
||||
Context activityContext, GenericTextHeaderItem genericTextHeaderItem, Status status) {
|
||||
this.conversation = conversation;
|
||||
this.user = user;
|
||||
this.context = activityContext;
|
||||
Context activityContext, GenericTextHeaderItem genericTextHeaderItem, Status status,
|
||||
final ViewThemeUtils viewThemeUtils) {
|
||||
this(conversation, user, activityContext, status, viewThemeUtils);
|
||||
this.header = genericTextHeaderItem;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -146,11 +146,7 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
|
|||
if (adapter.hasFilter()) {
|
||||
FlexibleUtils.highlightText(holder.binding.dialogName, conversation.getDisplayName(),
|
||||
String.valueOf(adapter.getFilter(String.class)),
|
||||
NextcloudTalkApplication
|
||||
.Companion
|
||||
.getSharedApplication()
|
||||
.getResources()
|
||||
.getColor(R.color.colorPrimary));
|
||||
viewThemeUtils.getElementColor(holder.binding.dialogName.getContext()));
|
||||
} else {
|
||||
holder.binding.dialogName.setText(conversation.getDisplayName());
|
||||
}
|
||||
|
@ -171,29 +167,18 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
|
|||
int lightBubbleTextColor = ContextCompat.getColor(
|
||||
context,
|
||||
R.color.conversation_unread_bubble_text);
|
||||
ColorStateList lightBubbleStrokeColor = ColorStateList.valueOf(
|
||||
ContextCompat.getColor(context,
|
||||
R.color.colorPrimary));
|
||||
|
||||
if (conversation.getType() == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
|
||||
holder.binding.dialogUnreadBubble.setChipBackgroundColorResource(R.color.colorPrimary);
|
||||
holder.binding.dialogUnreadBubble.setTextColor(Color.WHITE);
|
||||
viewThemeUtils.colorChipBackground(holder.binding.dialogUnreadBubble);
|
||||
} else if (conversation.getUnreadMention()) {
|
||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "direct-mention-flag")) {
|
||||
if (conversation.getUnreadMentionDirect()) {
|
||||
holder.binding.dialogUnreadBubble.setChipBackgroundColorResource(R.color.colorPrimary);
|
||||
holder.binding.dialogUnreadBubble.setTextColor(Color.WHITE);
|
||||
viewThemeUtils.colorChipBackground(holder.binding.dialogUnreadBubble);
|
||||
} else {
|
||||
holder.binding.dialogUnreadBubble.setChipBackgroundColorResource(R.color.bg_default);
|
||||
holder.binding.dialogUnreadBubble.setTextColor(ContextCompat.getColor(
|
||||
context,
|
||||
R.color.colorPrimary));
|
||||
holder.binding.dialogUnreadBubble.setChipStrokeWidth(6.0f);
|
||||
holder.binding.dialogUnreadBubble.setChipStrokeColor(lightBubbleStrokeColor);
|
||||
viewThemeUtils.colorChipOutlined(holder.binding.dialogUnreadBubble, 6.0f);
|
||||
}
|
||||
} else {
|
||||
holder.binding.dialogUnreadBubble.setChipBackgroundColorResource(R.color.colorPrimary);
|
||||
holder.binding.dialogUnreadBubble.setTextColor(Color.WHITE);
|
||||
viewThemeUtils.colorChipBackground(holder.binding.dialogUnreadBubble);
|
||||
}
|
||||
} else {
|
||||
holder.binding.dialogUnreadBubble.setChipBackgroundColor(lightBubbleFillColor);
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.view.View;
|
|||
|
||||
import com.nextcloud.talk.R;
|
||||
import com.nextcloud.talk.databinding.RvItemTitleHeaderBinding;
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -39,12 +40,14 @@ public class GenericTextHeaderItem extends AbstractHeaderItem<GenericTextHeaderI
|
|||
private static final String TAG = "GenericTextHeaderItem";
|
||||
|
||||
private final String title;
|
||||
private final ViewThemeUtils viewThemeUtils;
|
||||
|
||||
public GenericTextHeaderItem(String title) {
|
||||
public GenericTextHeaderItem(String title, ViewThemeUtils viewThemeUtils) {
|
||||
super();
|
||||
setHidden(false);
|
||||
setSelectable(false);
|
||||
this.title = title;
|
||||
this.viewThemeUtils = viewThemeUtils;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
|
@ -71,6 +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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,12 +24,12 @@ package com.nextcloud.talk.adapters.items
|
|||
import android.content.Context
|
||||
import android.text.SpannableString
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.RvItemSearchMessageBinding
|
||||
import com.nextcloud.talk.models.domain.SearchMessageEntry
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
|
@ -42,7 +42,8 @@ data class MessageResultItem constructor(
|
|||
private val context: Context,
|
||||
private val currentUser: User,
|
||||
val messageEntry: SearchMessageEntry,
|
||||
private val showHeader: Boolean = false
|
||||
private val showHeader: Boolean = false,
|
||||
private val viewThemeUtils: ViewThemeUtils
|
||||
) :
|
||||
AbstractFlexibleItem<MessageResultItem.ViewHolder>(),
|
||||
IFilterable<String>,
|
||||
|
@ -77,7 +78,7 @@ data class MessageResultItem constructor(
|
|||
|
||||
private fun bindMessageExcerpt(holder: ViewHolder) {
|
||||
val messageSpannable = SpannableString(messageEntry.messageExcerpt)
|
||||
val highlightColor = ContextCompat.getColor(context, R.color.colorPrimary)
|
||||
val highlightColor = viewThemeUtils.getElementColor(holder.binding.messageExcerpt.context)
|
||||
val highlightedSpan = DisplayUtils.searchAndColor(messageSpannable, messageEntry.searchTerm, highlightColor)
|
||||
holder.binding.messageExcerpt.text = highlightedSpan
|
||||
}
|
||||
|
@ -104,7 +105,7 @@ data class MessageResultItem constructor(
|
|||
const val VIEW_TYPE: Int = R.layout.rv_item_search_message
|
||||
}
|
||||
|
||||
override fun getHeader(): GenericTextHeaderItem = MessagesTextHeaderItem(context)
|
||||
override fun getHeader(): GenericTextHeaderItem = MessagesTextHeaderItem(context, viewThemeUtils)
|
||||
.apply {
|
||||
isHidden = showHeader // FlexibleAdapter needs this hack for some reason
|
||||
}
|
||||
|
|
|
@ -23,8 +23,10 @@ package com.nextcloud.talk.adapters.items
|
|||
|
||||
import android.content.Context
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
|
||||
class MessagesTextHeaderItem(context: Context) : GenericTextHeaderItem(context.getString(R.string.messages)) {
|
||||
class MessagesTextHeaderItem(context: Context, viewThemeUtils: ViewThemeUtils) :
|
||||
GenericTextHeaderItem(context.getString(R.string.messages), viewThemeUtils) {
|
||||
companion object {
|
||||
/**
|
||||
* "Random" value, just has to be different than other view types
|
||||
|
|
|
@ -48,6 +48,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
|
|||
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
|
||||
import com.nextcloud.talk.databinding.ItemCustomIncomingVoiceMessageBinding
|
||||
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.preferences.AppPreferences
|
||||
|
@ -66,6 +67,9 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
|
|||
@Inject
|
||||
var context: Context? = null
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
@JvmField
|
||||
@Inject
|
||||
var appPreferences: AppPreferences? = null
|
||||
|
@ -93,6 +97,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
|
|||
|
||||
updateDownloadState(message)
|
||||
binding.seekbar.max = message.voiceMessageDuration
|
||||
viewThemeUtils.themeHorizontalSeekBar(binding.seekbar)
|
||||
|
||||
if (message.isPlayingVoiceMessage) {
|
||||
showPlayButton()
|
||||
|
|
|
@ -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.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.view.ViewCompat
|
||||
import autodagger.AutoInjector
|
||||
import coil.load
|
||||
|
@ -44,22 +43,29 @@ 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 java.util.HashMap
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewHolder<ChatMessage>(itemView) {
|
||||
private val binding: ItemCustomOutcomingTextMessageBinding = ItemCustomOutcomingTextMessageBinding.bind(itemView)
|
||||
private val realView: View = itemView
|
||||
|
||||
@JvmField
|
||||
@Inject
|
||||
var context: Context? = null
|
||||
lateinit var context: Context
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
@Inject
|
||||
lateinit var serverTheme: ServerTheme
|
||||
|
||||
lateinit var reactionsInterface: ReactionsInterface
|
||||
|
||||
|
@ -69,7 +75,7 @@ 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(context!!.resources.getColor(R.color.white60))
|
||||
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)
|
||||
|
@ -89,6 +95,8 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
|
|||
binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
|
||||
binding.messageTime.layoutParams = layoutParams
|
||||
binding.messageText.text = messageString
|
||||
binding.messageText.setTextColor(serverTheme.colorText)
|
||||
binding.messageText.setLinkTextColor(serverTheme.colorText)
|
||||
|
||||
// parent message handling
|
||||
if (!message.isDeleted && message.parentMessage != null) {
|
||||
|
@ -112,8 +120,8 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
|
|||
|
||||
readStatusDrawableInt?.let { drawableInt ->
|
||||
ResourcesCompat.getDrawable(context!!.resources, drawableInt, null)?.let {
|
||||
it.setColorFilter(ContextCompat.getColor(context!!, R.color.white60), PorterDuff.Mode.SRC_ATOP)
|
||||
binding.checkMark.setImageDrawable(it)
|
||||
viewThemeUtils.colorImageViewText(binding.checkMark)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,20 +156,25 @@ 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(
|
||||
ContextCompat.getColor(context!!, R.color.nc_outcoming_text_default)
|
||||
)
|
||||
binding.messageQuote.quotedMessageAuthor.setTextColor(ContextCompat.getColor(context!!, R.color.nc_grey))
|
||||
binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText)
|
||||
|
||||
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white)
|
||||
binding.messageQuote.quotedMessageAuthor.setTextColor(
|
||||
ColorUtils.setAlphaComponent(
|
||||
serverTheme.colorText,
|
||||
ALPHA_80_INT
|
||||
)
|
||||
)
|
||||
|
||||
binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText)
|
||||
}
|
||||
|
||||
private fun setBubbleOnChatMessage(message: ChatMessage) {
|
||||
val resources = sharedApplication!!.resources
|
||||
val elementColor = viewThemeUtils.getElementColor(binding.root.context)
|
||||
val bgBubbleColor = if (message.isDeleted) {
|
||||
ResourcesCompat.getColor(resources, R.color.bg_message_list_outcoming_bubble_deleted, null)
|
||||
ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT)
|
||||
} else {
|
||||
ResourcesCompat.getColor(resources, R.color.bg_message_list_outcoming_bubble, null)
|
||||
elementColor
|
||||
}
|
||||
if (message.isGrouped) {
|
||||
val bubbleDrawable = getMessageSelector(
|
||||
|
@ -221,5 +234,8 @@ 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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,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.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.net.Uri;
|
||||
|
@ -49,6 +50,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.utils.DisplayUtils;
|
||||
import com.nextcloud.talk.utils.DrawableUtils;
|
||||
import com.nextcloud.talk.utils.FileViewerUtils;
|
||||
|
@ -91,6 +93,9 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
|
|||
@Inject
|
||||
Context context;
|
||||
|
||||
@Inject
|
||||
ServerTheme serverTheme;
|
||||
|
||||
@Inject
|
||||
OkHttpClient okHttpClient;
|
||||
|
||||
|
@ -175,6 +180,13 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
|
|||
String mimetype = message.getSelectedIndividualHashMap().get(KEY_MIMETYPE);
|
||||
int drawableResourceId = DrawableUtils.INSTANCE.getDrawableResourceIdForMimeType(mimetype);
|
||||
Drawable drawable = ContextCompat.getDrawable(context, drawableResourceId);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
image.getHierarchy().setPlaceholderImage(drawable);
|
||||
} else {
|
||||
fetchFileInformation("/" + message.getSelectedIndividualHashMap().get(KEY_PATH),
|
||||
|
|
|
@ -25,7 +25,6 @@ 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
|
||||
|
@ -35,6 +34,8 @@ 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
|
||||
|
@ -45,12 +46,15 @@ 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
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
|
||||
|
@ -68,6 +72,12 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
|
|||
@Inject
|
||||
var context: Context? = null
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
@Inject
|
||||
lateinit var serverTheme: ServerTheme
|
||||
|
||||
lateinit var reactionsInterface: ReactionsInterface
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
|
@ -76,7 +86,6 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
|
|||
sharedApplication!!.componentApplication.inject(this)
|
||||
|
||||
realView.isSelected = false
|
||||
binding.messageTime.setTextColor(context!!.resources.getColor(R.color.white60))
|
||||
val layoutParams = binding.messageTime.layoutParams as FlexboxLayout.LayoutParams
|
||||
layoutParams.isWrapBefore = false
|
||||
|
||||
|
@ -85,7 +94,11 @@ 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)
|
||||
|
@ -104,8 +117,8 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
|
|||
|
||||
readStatusDrawableInt?.let { drawableInt ->
|
||||
AppCompatResources.getDrawable(context!!, drawableInt)?.let {
|
||||
it.setColorFilter(context?.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP)
|
||||
binding.checkMark.setImageDrawable(it)
|
||||
viewThemeUtils.colorImageViewText(binding.checkMark)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,12 +213,12 @@ 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(
|
||||
context!!.resources.getColor(R.color.nc_outcoming_text_default)
|
||||
binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText)
|
||||
binding.messageQuote.quotedMessageAuthor.setTextColor(
|
||||
ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_80_INT)
|
||||
)
|
||||
binding.messageQuote.quotedMessageAuthor.setTextColor(context!!.resources.getColor(R.color.nc_grey))
|
||||
|
||||
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white)
|
||||
binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
} else {
|
||||
|
@ -215,15 +228,16 @@ 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) {
|
||||
resources.getColor(R.color.bg_message_list_outcoming_bubble_deleted)
|
||||
ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT)
|
||||
} else {
|
||||
resources.getColor(R.color.bg_message_list_outcoming_bubble)
|
||||
elementColor
|
||||
}
|
||||
if (message.isGrouped) {
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
resources.getColor(R.color.transparent),
|
||||
ResourcesCompat.getColor(resources, R.color.transparent, null),
|
||||
bgBubbleColor,
|
||||
R.drawable.shape_grouped_outcoming_message
|
||||
)
|
||||
|
@ -231,7 +245,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
|
|||
} else {
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
resources.getColor(R.color.transparent),
|
||||
ResourcesCompat.getColor(resources, R.color.transparent, null),
|
||||
bgBubbleColor,
|
||||
R.drawable.shape_outcoming_message
|
||||
)
|
||||
|
@ -261,5 +275,8 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
|
|||
|
||||
companion object {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,11 @@ package com.nextcloud.talk.adapters.messages
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
import android.content.res.ColorStateList
|
||||
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
|
||||
|
@ -38,11 +40,14 @@ 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
|
||||
|
@ -54,6 +59,12 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
|
|||
@Inject
|
||||
lateinit var context: Context
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
@Inject
|
||||
lateinit var serverTheme: ServerTheme
|
||||
|
||||
@Inject
|
||||
lateinit var appPreferences: AppPreferences
|
||||
|
||||
|
@ -73,7 +84,12 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
|
|||
colorizeMessageBubble(message)
|
||||
|
||||
itemView.isSelected = false
|
||||
binding.messageTime.setTextColor(context.resources.getColor(R.color.white60))
|
||||
binding.messageTime.setTextColor(
|
||||
ColorUtils.setAlphaComponent(
|
||||
serverTheme.colorText,
|
||||
ALPHA_60_INT
|
||||
)
|
||||
)
|
||||
|
||||
// parent message handling
|
||||
setParentMessageDataOnMessageItem(message)
|
||||
|
@ -92,8 +108,8 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
|
|||
|
||||
readStatusDrawableInt?.let { drawableInt ->
|
||||
AppCompatResources.getDrawable(context, drawableInt)?.let {
|
||||
it.setColorFilter(context.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP)
|
||||
binding.checkMark.setImageDrawable(it)
|
||||
viewThemeUtils.colorImageViewText(binding.checkMark)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,6 +142,9 @@ 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
|
||||
|
@ -165,12 +184,12 @@ 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(
|
||||
context.resources.getColor(R.color.nc_outcoming_text_default)
|
||||
binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText)
|
||||
binding.messageQuote.quotedMessageAuthor.setTextColor(
|
||||
ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_80_INT)
|
||||
)
|
||||
binding.messageQuote.quotedMessageAuthor.setTextColor(context.resources.getColor(R.color.nc_grey))
|
||||
|
||||
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white)
|
||||
binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
} else {
|
||||
|
@ -180,15 +199,16 @@ 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) {
|
||||
resources.getColor(R.color.bg_message_list_outcoming_bubble_deleted)
|
||||
ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT)
|
||||
} else {
|
||||
resources.getColor(R.color.bg_message_list_outcoming_bubble)
|
||||
elementColor
|
||||
}
|
||||
if (message.isGrouped) {
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
resources.getColor(R.color.transparent),
|
||||
ResourcesCompat.getColor(resources, R.color.transparent, null),
|
||||
bgBubbleColor,
|
||||
R.drawable.shape_grouped_outcoming_message
|
||||
)
|
||||
|
@ -196,7 +216,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
|
|||
} else {
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
resources.getColor(R.color.transparent),
|
||||
ResourcesCompat.getColor(resources, R.color.transparent, null),
|
||||
bgBubbleColor,
|
||||
R.drawable.shape_outcoming_message
|
||||
)
|
||||
|
@ -210,5 +230,8 @@ 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ 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
|
||||
|
@ -42,12 +44,15 @@ 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
|
||||
|
@ -60,6 +65,12 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
|
|||
@Inject
|
||||
var context: Context? = null
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
@Inject
|
||||
lateinit var serverTheme: ServerTheme
|
||||
|
||||
@JvmField
|
||||
@Inject
|
||||
var appPreferences: AppPreferences? = null
|
||||
|
@ -80,13 +91,19 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
|
|||
colorizeMessageBubble(message)
|
||||
|
||||
itemView.isSelected = false
|
||||
binding.messageTime.setTextColor(context!!.resources.getColor(R.color.white60))
|
||||
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)
|
||||
|
||||
handleIsPlayingVoiceMessageState(message)
|
||||
|
||||
|
@ -124,8 +141,8 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
|
|||
|
||||
readStatusDrawableInt?.let { drawableInt ->
|
||||
AppCompatResources.getDrawable(context!!, drawableInt)?.let {
|
||||
it.setColorFilter(context?.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP)
|
||||
binding.checkMark.setImageDrawable(it)
|
||||
viewThemeUtils.colorImageViewText(binding.checkMark)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,6 +165,7 @@ 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
|
||||
}
|
||||
|
@ -168,6 +186,7 @@ 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
|
||||
|
@ -175,6 +194,7 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,12 +270,15 @@ 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(
|
||||
context!!.resources.getColor(R.color.nc_outcoming_text_default)
|
||||
binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText)
|
||||
binding.messageQuote.quotedMessageAuthor.setTextColor(
|
||||
ColorUtils.setAlphaComponent(
|
||||
serverTheme.colorText,
|
||||
ALPHA_80_INT
|
||||
)
|
||||
)
|
||||
binding.messageQuote.quotedMessageAuthor.setTextColor(context!!.resources.getColor(R.color.nc_grey))
|
||||
|
||||
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white)
|
||||
binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
} else {
|
||||
|
@ -265,15 +288,16 @@ 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) {
|
||||
resources.getColor(R.color.bg_message_list_outcoming_bubble_deleted)
|
||||
ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT)
|
||||
} else {
|
||||
resources.getColor(R.color.bg_message_list_outcoming_bubble)
|
||||
elementColor
|
||||
}
|
||||
if (message.isGrouped) {
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
resources.getColor(R.color.transparent),
|
||||
ResourcesCompat.getColor(resources, R.color.transparent, null),
|
||||
bgBubbleColor,
|
||||
R.drawable.shape_grouped_outcoming_message
|
||||
)
|
||||
|
@ -281,7 +305,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
|
|||
} else {
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
resources.getColor(R.color.transparent),
|
||||
ResourcesCompat.getColor(resources, R.color.transparent, null),
|
||||
bgBubbleColor,
|
||||
R.drawable.shape_outcoming_message
|
||||
)
|
||||
|
@ -300,5 +324,8 @@ 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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ import com.nextcloud.talk.dagger.modules.ViewModelModule
|
|||
import com.nextcloud.talk.jobs.AccountRemovalWorker
|
||||
import com.nextcloud.talk.jobs.CapabilitiesWorker
|
||||
import com.nextcloud.talk.jobs.SignalingSettingsWorker
|
||||
import com.nextcloud.talk.ui.theme.ThemeModule
|
||||
import com.nextcloud.talk.utils.ClosedInterfaceImpl
|
||||
import com.nextcloud.talk.utils.DeviceUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
|
@ -96,7 +97,8 @@ import javax.inject.Singleton
|
|||
ArbitraryStorageModule::class,
|
||||
ViewModelModule::class,
|
||||
RepositoryModule::class,
|
||||
UtilsModule::class
|
||||
UtilsModule::class,
|
||||
ThemeModule::class
|
||||
]
|
||||
)
|
||||
@Singleton
|
||||
|
@ -120,6 +122,7 @@ class NextcloudTalkApplication : MultiDexApplication(), LifecycleObserver {
|
|||
override fun preKey(database: SQLiteDatabase) {
|
||||
// unused atm
|
||||
}
|
||||
|
||||
override fun postKey(database: SQLiteDatabase) {
|
||||
Log.i("TalkApplication", "DB cipher_migrate START")
|
||||
database.rawExecSQL("PRAGMA cipher_migrate;")
|
||||
|
|
|
@ -154,6 +154,8 @@ 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
|
||||
|
@ -235,6 +237,12 @@ 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
|
||||
|
@ -872,6 +880,8 @@ class ChatController(args: Bundle) :
|
|||
.nc_description_send_message_button
|
||||
)
|
||||
|
||||
viewThemeUtils.colorImageView(binding.messageInputView.button)
|
||||
|
||||
if (currentConversation != null && currentConversation?.roomId != null) {
|
||||
loadAvatarForStatusBar()
|
||||
setTitle()
|
||||
|
@ -2675,7 +2685,8 @@ class ChatController(args: Bundle) :
|
|||
chatMessage,
|
||||
conversationUser,
|
||||
hasChatPermission,
|
||||
ncApi!!
|
||||
ncApi!!,
|
||||
serverTheme
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ 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
|
||||
|
@ -103,6 +104,9 @@ 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
|
||||
|
@ -492,13 +496,14 @@ class ContactsController(args: Bundle) :
|
|||
val headerTitle = getHeaderTitle(participant)
|
||||
var genericTextHeaderItem: GenericTextHeaderItem
|
||||
if (!userHeaderItems.containsKey(headerTitle)) {
|
||||
genericTextHeaderItem = GenericTextHeaderItem(headerTitle)
|
||||
genericTextHeaderItem = GenericTextHeaderItem(headerTitle, viewThemeUtils)
|
||||
userHeaderItems.put(headerTitle, genericTextHeaderItem)
|
||||
}
|
||||
val newContactItem = ContactItem(
|
||||
participant,
|
||||
currentUser,
|
||||
userHeaderItems[headerTitle]
|
||||
userHeaderItems[headerTitle],
|
||||
viewThemeUtils
|
||||
)
|
||||
if (!contactItems!!.contains(newContactItem)) {
|
||||
newUserItemList.add(newContactItem)
|
||||
|
@ -618,21 +623,16 @@ class ContactsController(args: Bundle) :
|
|||
binding.controllerGenericRv.recyclerView.setHasFixedSize(true)
|
||||
binding.controllerGenericRv.recyclerView.adapter = adapter
|
||||
binding.controllerGenericRv.swipeRefreshLayout.setOnRefreshListener { fetchData() }
|
||||
binding.controllerGenericRv.swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary)
|
||||
binding.controllerGenericRv.swipeRefreshLayout
|
||||
.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background)
|
||||
|
||||
viewThemeUtils.themeSwipeRefreshLayout(binding.controllerGenericRv.swipeRefreshLayout)
|
||||
|
||||
binding.joinConversationViaLink.joinConversationViaLinkImageView
|
||||
.background
|
||||
.setColorFilter(
|
||||
ResourcesCompat.getColor(resources!!, R.color.colorBackgroundDarker, null),
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.conversationPrivacyToggle.publicCallLink
|
||||
.background
|
||||
.setColorFilter(
|
||||
ResourcesCompat.getColor(resources!!, R.color.colorPrimary, null),
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
viewThemeUtils.colorImageViewButton(binding.conversationPrivacyToggle.publicCallLink)
|
||||
disengageProgressBar()
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ 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
|
||||
|
@ -112,6 +113,9 @@ 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
|
||||
|
@ -181,6 +185,34 @@ class ConversationInfoController(args: Bundle) :
|
|||
}
|
||||
|
||||
fetchRoomInfo()
|
||||
|
||||
themeCategories()
|
||||
themeSwitchPreferences()
|
||||
}
|
||||
|
||||
private fun themeSwitchPreferences() {
|
||||
binding.run {
|
||||
listOf(
|
||||
binding.webinarInfoView.conversationInfoLobby,
|
||||
binding.notificationSettingsView.callNotifications,
|
||||
binding.notificationSettingsView.conversationInfoPriorityConversation
|
||||
).forEach(viewThemeUtils::colorSwitchPreference)
|
||||
}
|
||||
}
|
||||
|
||||
private fun themeCategories() {
|
||||
binding.run {
|
||||
listOf(
|
||||
conversationInfoName,
|
||||
conversationDescription,
|
||||
otherRoomOptions,
|
||||
participantsListCategory,
|
||||
ownOptions,
|
||||
categorySharedItems,
|
||||
binding.webinarInfoView.conversationInfoWebinar,
|
||||
binding.notificationSettingsView.notificationSettingsCategory
|
||||
).forEach(viewThemeUtils::colorPreferenceCategory)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showSharedItems() {
|
||||
|
@ -299,7 +331,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
|
||||
ncApi?.setLobbyForConversation(
|
||||
ncApi.setLobbyForConversation(
|
||||
ApiUtils.getCredentials(conversationUser!!.username, conversationUser.token),
|
||||
ApiUtils.getUrlForRoomWebinaryLobby(apiVersion, conversationUser.baseUrl, conversation!!.token),
|
||||
state,
|
||||
|
@ -343,7 +375,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
|
||||
override fun onDetach(view: View) {
|
||||
super.onDetach(view)
|
||||
eventBus?.unregister(this)
|
||||
eventBus.unregister(this)
|
||||
}
|
||||
|
||||
private fun showDeleteConversationDialog(savedInstanceState: Bundle?) {
|
||||
|
@ -352,11 +384,11 @@ class ConversationInfoController(args: Bundle) :
|
|||
.setTopColorRes(R.color.nc_darkRed)
|
||||
.setIcon(
|
||||
DisplayUtils.getTintedDrawable(
|
||||
context!!.resources,
|
||||
context.resources,
|
||||
R.drawable.ic_delete_black_24dp, R.color.bg_default
|
||||
)
|
||||
)
|
||||
.setPositiveButtonColor(context!!.resources.getColor(R.color.nc_darkRed))
|
||||
.setPositiveButtonColor(context.resources.getColor(R.color.nc_darkRed))
|
||||
.setTitle(R.string.nc_delete_call)
|
||||
.setMessage(R.string.nc_delete_conversation_more)
|
||||
.setPositiveButton(R.string.nc_delete) { deleteConversation() }
|
||||
|
@ -409,7 +441,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
if (participant.sessionId != null) {
|
||||
userItem.isOnline = !participant.sessionId.equals("0")
|
||||
} else {
|
||||
userItem.isOnline = !participant.sessionIds!!.isEmpty()
|
||||
userItem.isOnline = !participant.sessionIds.isEmpty()
|
||||
}
|
||||
|
||||
if (participant.calculatedActorType == USERS &&
|
||||
|
@ -453,7 +485,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
val fieldMap = HashMap<String, Boolean>()
|
||||
fieldMap["includeStatus"] = true
|
||||
|
||||
ncApi?.getPeersForCall(
|
||||
ncApi.getPeersForCall(
|
||||
credentials,
|
||||
ApiUtils.getUrlForParticipants(
|
||||
apiVersion,
|
||||
|
@ -504,7 +536,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
bundle.putStringArrayList(BundleKeys.KEY_EXISTING_PARTICIPANTS, existingParticipantsId)
|
||||
bundle.putString(BundleKeys.KEY_TOKEN, conversation!!.token)
|
||||
|
||||
getRouter().pushController(
|
||||
router.pushController(
|
||||
(
|
||||
RouterTransaction.with(
|
||||
ContactsController(bundle)
|
||||
|
@ -537,11 +569,11 @@ class ConversationInfoController(args: Bundle) :
|
|||
.setTopColorRes(R.color.nc_darkRed)
|
||||
.setIcon(
|
||||
DisplayUtils.getTintedDrawable(
|
||||
context!!.resources,
|
||||
context.resources,
|
||||
R.drawable.ic_delete_black_24dp, R.color.bg_default
|
||||
)
|
||||
)
|
||||
.setPositiveButtonColor(context!!.resources.getColor(R.color.nc_darkRed))
|
||||
.setPositiveButtonColor(context.resources.getColor(R.color.nc_darkRed))
|
||||
.setTitle(R.string.nc_clear_history)
|
||||
.setMessage(R.string.nc_clear_history_warning)
|
||||
.setPositiveButton(R.string.nc_delete_all) { clearHistory() }
|
||||
|
@ -555,7 +587,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
private fun clearHistory() {
|
||||
val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
|
||||
|
||||
ncApi?.clearChatHistory(
|
||||
ncApi.clearChatHistory(
|
||||
credentials,
|
||||
ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl, conversationToken)
|
||||
)
|
||||
|
@ -567,7 +599,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
}
|
||||
|
||||
override fun onNext(genericOverall: GenericOverall) {
|
||||
Toast.makeText(context, context?.getString(R.string.nc_clear_history_success), Toast.LENGTH_LONG)
|
||||
Toast.makeText(context, context.getString(R.string.nc_clear_history_success), Toast.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
|
||||
|
@ -606,7 +638,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
}
|
||||
|
||||
ncApi?.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser!!.baseUrl, conversationToken))
|
||||
ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser!!.baseUrl, conversationToken))
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : Observer<RoomOverall> {
|
||||
|
@ -765,8 +797,8 @@ class ConversationInfoController(args: Bundle) :
|
|||
)
|
||||
Conversation.ConversationType.ROOM_SYSTEM -> {
|
||||
val layers = arrayOfNulls<Drawable>(2)
|
||||
layers[0] = ContextCompat.getDrawable(context!!, R.drawable.ic_launcher_background)
|
||||
layers[1] = ContextCompat.getDrawable(context!!, R.drawable.ic_launcher_foreground)
|
||||
layers[0] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_background)
|
||||
layers[1] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_foreground)
|
||||
val layerDrawable = LayerDrawable(layers)
|
||||
binding.avatarImage.hierarchy.setPlaceholderImage(DisplayUtils.getRoundedDrawable(layerDrawable))
|
||||
}
|
||||
|
@ -800,7 +832,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
if (participant.type == Participant.ParticipantType.MODERATOR ||
|
||||
participant.type == Participant.ParticipantType.GUEST_MODERATOR
|
||||
) {
|
||||
ncApi?.demoteAttendeeFromModerator(
|
||||
ncApi.demoteAttendeeFromModerator(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomModerators(
|
||||
apiVersion,
|
||||
|
@ -815,7 +847,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
} else if (participant.type == Participant.ParticipantType.USER ||
|
||||
participant.type == Participant.ParticipantType.GUEST
|
||||
) {
|
||||
ncApi?.promoteAttendeeToModerator(
|
||||
ncApi.promoteAttendeeToModerator(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomModerators(
|
||||
apiVersion,
|
||||
|
@ -851,7 +883,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
}
|
||||
|
||||
if (participant.type == Participant.ParticipantType.MODERATOR) {
|
||||
ncApi?.demoteModeratorToUser(
|
||||
ncApi.demoteModeratorToUser(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomModerators(
|
||||
apiVersion,
|
||||
|
@ -864,7 +896,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(subscriber)
|
||||
} else if (participant.type == Participant.ParticipantType.USER) {
|
||||
ncApi?.promoteUserToModerator(
|
||||
ncApi.promoteUserToModerator(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoomModerators(
|
||||
apiVersion,
|
||||
|
@ -881,7 +913,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
|
||||
fun removeAttendeeFromConversation(apiVersion: Int, participant: Participant) {
|
||||
if (apiVersion >= ApiUtils.APIv4) {
|
||||
ncApi?.removeAttendeeFromConversation(
|
||||
ncApi.removeAttendeeFromConversation(
|
||||
credentials,
|
||||
ApiUtils.getUrlForAttendees(
|
||||
apiVersion,
|
||||
|
@ -914,7 +946,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
if (participant.type == Participant.ParticipantType.GUEST ||
|
||||
participant.type == Participant.ParticipantType.USER_FOLLOWING_LINK
|
||||
) {
|
||||
ncApi?.removeParticipantFromConversation(
|
||||
ncApi.removeParticipantFromConversation(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRemovingParticipantFromConversation(
|
||||
conversationUser!!.baseUrl,
|
||||
|
@ -944,7 +976,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
}
|
||||
})
|
||||
} else {
|
||||
ncApi?.removeParticipantFromConversation(
|
||||
ncApi.removeParticipantFromConversation(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRemovingParticipantFromConversation(
|
||||
conversationUser!!.baseUrl,
|
||||
|
@ -987,12 +1019,12 @@ class ConversationInfoController(args: Bundle) :
|
|||
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||
|
||||
if (participant.calculatedActorType == USERS && participant.calculatedActorId == conversationUser!!.userId) {
|
||||
if (participant.calculatedActorType == USERS && participant.calculatedActorId == conversationUser.userId) {
|
||||
if (participant.attendeePin?.isNotEmpty() == true) {
|
||||
val items = mutableListOf(
|
||||
BasicListItemWithImage(
|
||||
R.drawable.ic_lock_grey600_24px,
|
||||
context!!.getString(R.string.nc_attendee_pin, participant.attendeePin)
|
||||
context.getString(R.string.nc_attendee_pin, participant.attendeePin)
|
||||
)
|
||||
)
|
||||
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
|
||||
|
@ -1018,7 +1050,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
val items = mutableListOf(
|
||||
BasicListItemWithImage(
|
||||
R.drawable.ic_delete_grey600_24dp,
|
||||
context!!.getString(R.string.nc_remove_group_and_members)
|
||||
context.getString(R.string.nc_remove_group_and_members)
|
||||
)
|
||||
)
|
||||
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
|
||||
|
@ -1038,7 +1070,7 @@ class ConversationInfoController(args: Bundle) :
|
|||
val items = mutableListOf(
|
||||
BasicListItemWithImage(
|
||||
R.drawable.ic_delete_grey600_24dp,
|
||||
context!!.getString(R.string.nc_remove_circle_and_members)
|
||||
context.getString(R.string.nc_remove_circle_and_members)
|
||||
)
|
||||
)
|
||||
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
|
||||
|
@ -1057,19 +1089,19 @@ class ConversationInfoController(args: Bundle) :
|
|||
val items = mutableListOf(
|
||||
BasicListItemWithImage(
|
||||
R.drawable.ic_lock_grey600_24px,
|
||||
context!!.getString(R.string.nc_attendee_pin, participant.attendeePin)
|
||||
context.getString(R.string.nc_attendee_pin, participant.attendeePin)
|
||||
),
|
||||
BasicListItemWithImage(
|
||||
R.drawable.ic_pencil_grey600_24dp,
|
||||
context!!.getString(R.string.nc_promote)
|
||||
context.getString(R.string.nc_promote)
|
||||
),
|
||||
BasicListItemWithImage(
|
||||
R.drawable.ic_pencil_grey600_24dp,
|
||||
context!!.getString(R.string.nc_demote)
|
||||
context.getString(R.string.nc_demote)
|
||||
),
|
||||
BasicListItemWithImage(
|
||||
R.drawable.ic_delete_grey600_24dp,
|
||||
context!!.getString(R.string.nc_remove_participant)
|
||||
context.getString(R.string.nc_remove_participant)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -1167,8 +1199,8 @@ class ConversationInfoController(args: Bundle) :
|
|||
return 1
|
||||
}
|
||||
|
||||
return left.model.displayName!!.toLowerCase(Locale.ROOT).compareTo(
|
||||
right.model.displayName!!.toLowerCase(Locale.ROOT)
|
||||
return left.model.displayName!!.lowercase(Locale.ROOT).compareTo(
|
||||
right.model.displayName!!.lowercase(Locale.ROOT)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ import com.nextcloud.talk.models.json.statuses.StatusesOverall;
|
|||
import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository;
|
||||
import com.nextcloud.talk.ui.dialog.ChooseAccountDialogFragment;
|
||||
import com.nextcloud.talk.ui.dialog.ConversationsListBottomDialog;
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils;
|
||||
import com.nextcloud.talk.users.UserManager;
|
||||
import com.nextcloud.talk.utils.ApiUtils;
|
||||
import com.nextcloud.talk.utils.AttendeePermissionsUtil;
|
||||
|
@ -181,6 +182,9 @@ public class ConversationsListController extends BaseController implements Flexi
|
|||
@Inject
|
||||
UnifiedSearchRepository unifiedSearchRepository;
|
||||
|
||||
@Inject
|
||||
ViewThemeUtils viewThemeUtils;
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
|
@ -618,7 +622,7 @@ public class ConversationsListController extends BaseController implements Flexi
|
|||
|
||||
GenericTextHeaderItem genericTextHeaderItem;
|
||||
if (!callHeaderItems.containsKey(headerTitle)) {
|
||||
genericTextHeaderItem = new GenericTextHeaderItem(headerTitle);
|
||||
genericTextHeaderItem = new GenericTextHeaderItem(headerTitle, viewThemeUtils);
|
||||
callHeaderItems.put(headerTitle, genericTextHeaderItem);
|
||||
}
|
||||
|
||||
|
@ -627,7 +631,8 @@ public class ConversationsListController extends BaseController implements Flexi
|
|||
conversation,
|
||||
currentUser,
|
||||
getActivity(),
|
||||
userStatuses.get(conversation.getName()));
|
||||
userStatuses.get(conversation.getName()),
|
||||
viewThemeUtils);
|
||||
conversationItems.add(conversationItem);
|
||||
|
||||
ConversationItem conversationItemWithHeader = new ConversationItem(
|
||||
|
@ -635,7 +640,8 @@ public class ConversationsListController extends BaseController implements Flexi
|
|||
currentUser,
|
||||
getActivity(),
|
||||
callHeaderItems.get(headerTitle),
|
||||
userStatuses.get(conversation.getName()));
|
||||
userStatuses.get(conversation.getName()),
|
||||
viewThemeUtils);
|
||||
conversationItemsWithHeader.add(conversationItemWithHeader);
|
||||
}
|
||||
}
|
||||
|
@ -699,7 +705,7 @@ public class ConversationsListController extends BaseController implements Flexi
|
|||
|
||||
GenericTextHeaderItem genericTextHeaderItem;
|
||||
if (!callHeaderItems.containsKey(headerTitle)) {
|
||||
genericTextHeaderItem = new GenericTextHeaderItem(headerTitle);
|
||||
genericTextHeaderItem = new GenericTextHeaderItem(headerTitle, viewThemeUtils);
|
||||
callHeaderItems.put(headerTitle, genericTextHeaderItem);
|
||||
}
|
||||
|
||||
|
@ -708,7 +714,8 @@ public class ConversationsListController extends BaseController implements Flexi
|
|||
currentUser,
|
||||
getActivity(),
|
||||
callHeaderItems.get(headerTitle),
|
||||
userStatuses.get(conversation.getName()));
|
||||
userStatuses.get(conversation.getName()),
|
||||
viewThemeUtils);
|
||||
|
||||
openConversationItems.add(conversationItem);
|
||||
}
|
||||
|
@ -776,8 +783,7 @@ public class ConversationsListController extends BaseController implements Flexi
|
|||
});
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> fetchData());
|
||||
swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
|
||||
swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background);
|
||||
viewThemeUtils.themeSwipeRefreshLayout(swipeRefreshLayout);
|
||||
|
||||
emptyLayoutView.setOnClickListener(v -> showNewConversationsScreen());
|
||||
floatingActionButton.setOnClickListener(v -> {
|
||||
|
@ -785,6 +791,8 @@ public class ConversationsListController extends BaseController implements Flexi
|
|||
showNewConversationsScreen();
|
||||
});
|
||||
|
||||
viewThemeUtils.themeFAB(floatingActionButton);
|
||||
|
||||
if (getActivity() != null && getActivity() instanceof MainActivity) {
|
||||
MainActivity activity = (MainActivity) getActivity();
|
||||
|
||||
|
@ -1409,7 +1417,7 @@ public class ConversationsListController extends BaseController implements Flexi
|
|||
List<AbstractFlexibleItem> adapterItems = new ArrayList<>(entries.size() + 1);
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
final boolean showHeader = i == 0;
|
||||
adapterItems.add(new MessageResultItem(context, currentUser, entries.get(i), showHeader));
|
||||
adapterItems.add(new MessageResultItem(context, currentUser, entries.get(i), showHeader, viewThemeUtils));
|
||||
}
|
||||
if (results.getHasMore()) {
|
||||
adapterItems.add(LoadMoreResultsItem.INSTANCE);
|
||||
|
|
|
@ -24,10 +24,8 @@ package com.nextcloud.talk.controllers
|
|||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
|
@ -43,7 +41,6 @@ import android.view.ViewGroup
|
|||
import android.widget.Toast
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
@ -69,6 +66,7 @@ import com.nextcloud.talk.models.json.userprofile.UserProfileFieldsOverall
|
|||
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
|
||||
import com.nextcloud.talk.remotefilebrowser.activities.RemoteFileBrowserActivity
|
||||
import com.nextcloud.talk.ui.dialog.ScopeDialog
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
|
@ -110,6 +108,9 @@ 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
|
||||
|
@ -196,7 +197,7 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
|
|||
|
||||
override fun onAttach(view: View) {
|
||||
super.onAttach(view)
|
||||
adapter = UserInfoAdapter(null, activity!!.resources.getColor(R.color.colorPrimary), this)
|
||||
adapter = UserInfoAdapter(null, viewThemeUtils.getElementColor(activity!!), this)
|
||||
binding.userinfoList.adapter = adapter
|
||||
binding.userinfoList.setItemViewCacheSize(DEFAULT_CACHE_SIZE)
|
||||
currentUser = userManager.currentUser.blockingGet()
|
||||
|
@ -260,6 +261,13 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
|
|||
// unused atm
|
||||
}
|
||||
})
|
||||
|
||||
colorIcons()
|
||||
}
|
||||
|
||||
private fun colorIcons() {
|
||||
viewThemeUtils.colorImageView(binding.avatarChoose)
|
||||
viewThemeUtils.colorImageView(binding.avatarCamera)
|
||||
}
|
||||
|
||||
private fun isAllEmpty(items: Array<String?>): Boolean {
|
||||
|
@ -301,7 +309,8 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
|
|||
binding.emptyList.root.visibility = View.VISIBLE
|
||||
setErrorMessageForMultiList(
|
||||
activity!!.getString(R.string.userinfo_no_info_headline),
|
||||
activity!!.getString(R.string.userinfo_no_info_text), R.drawable.ic_user
|
||||
activity!!.getString(R.string.userinfo_no_info_text),
|
||||
R.drawable.ic_user
|
||||
)
|
||||
} else {
|
||||
binding.emptyList.root.visibility = View.GONE
|
||||
|
@ -616,11 +625,13 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
|
|||
val builder = MultipartBody.Builder()
|
||||
builder.setType(MultipartBody.FORM)
|
||||
builder.addFormDataPart(
|
||||
"files[]", file!!.name,
|
||||
"files[]",
|
||||
file!!.name,
|
||||
file.asRequestBody(IMAGE_PREFIX_GENERIC.toMediaTypeOrNull())
|
||||
)
|
||||
val filePart: MultipartBody.Part = MultipartBody.Part.createFormData(
|
||||
"files[]", file.name,
|
||||
"files[]",
|
||||
file.name,
|
||||
file.asRequestBody(IMAGE_JPG.toMediaTypeOrNull())
|
||||
)
|
||||
|
||||
|
@ -643,7 +654,8 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
|
|||
|
||||
override fun onError(e: Throwable) {
|
||||
Toast.makeText(
|
||||
applicationContext, context.getString(R.string.default_error_msg),
|
||||
applicationContext,
|
||||
context.getString(R.string.default_error_msg),
|
||||
Toast
|
||||
.LENGTH_LONG
|
||||
).show()
|
||||
|
@ -688,7 +700,8 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
|
|||
}
|
||||
|
||||
class UserInfoDetailsItem(
|
||||
@field:DrawableRes @param:DrawableRes var icon: Int,
|
||||
@field:DrawableRes @param:DrawableRes
|
||||
var icon: Int,
|
||||
var text: String?,
|
||||
var hint: String,
|
||||
val field: Field,
|
||||
|
@ -748,22 +761,14 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
|
|||
DrawableCompat.setTint(holder.binding.icon.drawable, mTintColor)
|
||||
if (!TextUtils.isEmpty(item.text) || controller.edit) {
|
||||
holder.binding.userInfoDetailContainer.visibility = View.VISIBLE
|
||||
if (controller.activity != null) {
|
||||
holder.binding.userInfoEditText.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
controller.activity!!,
|
||||
R.color.conversation_item_header
|
||||
)
|
||||
)
|
||||
}
|
||||
controller.viewThemeUtils.colorTextInputLayout(holder.binding.userInfoInputLayout)
|
||||
if (controller.edit &&
|
||||
controller.editableFields.contains(item.field.toString().lowercase())
|
||||
) {
|
||||
holder.binding.userInfoEditText.isEnabled = true
|
||||
holder.binding.userInfoEditText.isFocusableInTouchMode = true
|
||||
holder.binding.userInfoEditText.isEnabled = true
|
||||
holder.binding.userInfoEditText.isCursorVisible = true
|
||||
holder.binding.userInfoEditText.backgroundTintList = ColorStateList.valueOf(mTintColor)
|
||||
holder.binding.userInfoEditTextEdit.isEnabled = true
|
||||
holder.binding.userInfoEditTextEdit.isFocusableInTouchMode = true
|
||||
holder.binding.userInfoEditTextEdit.isEnabled = true
|
||||
holder.binding.userInfoEditTextEdit.isCursorVisible = true
|
||||
holder.binding.scope.setOnClickListener {
|
||||
ScopeDialog(
|
||||
controller.activity!!,
|
||||
|
@ -774,11 +779,10 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
|
|||
}
|
||||
holder.binding.scope.alpha = HIGH_EMPHASIS_ALPHA
|
||||
} else {
|
||||
holder.binding.userInfoEditText.isEnabled = false
|
||||
holder.binding.userInfoEditText.isFocusableInTouchMode = false
|
||||
holder.binding.userInfoEditText.isEnabled = false
|
||||
holder.binding.userInfoEditText.isCursorVisible = false
|
||||
holder.binding.userInfoEditText.backgroundTintList = ColorStateList.valueOf(Color.TRANSPARENT)
|
||||
holder.binding.userInfoEditTextEdit.isEnabled = false
|
||||
holder.binding.userInfoEditTextEdit.isFocusableInTouchMode = false
|
||||
holder.binding.userInfoEditTextEdit.isEnabled = false
|
||||
holder.binding.userInfoEditTextEdit.isCursorVisible = false
|
||||
holder.binding.scope.setOnClickListener(null)
|
||||
holder.binding.scope.alpha = MEDIUM_EMPHASIS_ALPHA
|
||||
}
|
||||
|
@ -791,19 +795,19 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
|
|||
holder: ViewHolder,
|
||||
item: UserInfoDetailsItem
|
||||
) {
|
||||
holder.binding.userInfoEditText.setText(item.text)
|
||||
holder.binding.userInfoEditText.hint = item.hint
|
||||
holder.binding.userInfoEditText.addTextChangedListener(object : TextWatcher {
|
||||
holder.binding.userInfoEditTextEdit.setText(item.text)
|
||||
holder.binding.userInfoInputLayout.hint = item.hint
|
||||
holder.binding.userInfoEditTextEdit.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||
// unused atm
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||
if (controller.edit) {
|
||||
displayList!![holder.adapterPosition].text = holder.binding.userInfoEditText.text.toString()
|
||||
displayList!![holder.adapterPosition].text = holder.binding.userInfoEditTextEdit.text.toString()
|
||||
} else {
|
||||
filteredDisplayList[holder.adapterPosition].text =
|
||||
holder.binding.userInfoEditText.text.toString()
|
||||
holder.binding.userInfoEditTextEdit.text.toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ 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
|
||||
|
@ -118,6 +119,9 @@ 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
|
||||
|
@ -402,7 +406,8 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
|
|||
.setIcon(
|
||||
DisplayUtils.getTintedDrawable(
|
||||
resources,
|
||||
R.drawable.ic_delete_black_24dp, R.color.bg_default
|
||||
R.drawable.ic_delete_black_24dp,
|
||||
R.color.bg_default
|
||||
)
|
||||
)
|
||||
.setPositiveButtonColor(context!!.resources.getColor(R.color.nc_darkRed))
|
||||
|
@ -511,6 +516,34 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
|
|||
|
||||
)
|
||||
}
|
||||
|
||||
themeCategories()
|
||||
themeSwitchPreferences()
|
||||
}
|
||||
|
||||
private fun themeSwitchPreferences() {
|
||||
binding.run {
|
||||
listOf(
|
||||
settingsScreenLock,
|
||||
settingsScreenSecurity,
|
||||
settingsIncognitoKeyboard,
|
||||
settingsPhoneBookIntegration,
|
||||
settingsReadPrivacy,
|
||||
settingsProxyUseCredentials
|
||||
).forEach(viewThemeUtils::colorSwitchPreference)
|
||||
}
|
||||
}
|
||||
|
||||
private fun themeCategories() {
|
||||
binding.run {
|
||||
listOf(
|
||||
settingsNotificationsCategory,
|
||||
settingsAboutCategory,
|
||||
settingsAdvancedCategory,
|
||||
settingsAppearanceCategory,
|
||||
settingsPrivacyCategory
|
||||
).forEach(viewThemeUtils::colorPreferenceCategory)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupProxyTypeSettings() {
|
||||
|
@ -952,7 +985,9 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
|
|||
val phoneNumber = textInputLayout.editText!!.text.toString()
|
||||
ncApi.setUserData(
|
||||
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
|
||||
ApiUtils.getUrlForUserData(currentUser!!.baseUrl, currentUser!!.userId), "phone", phoneNumber
|
||||
ApiUtils.getUrlForUserData(currentUser!!.baseUrl, currentUser!!.userId),
|
||||
"phone",
|
||||
phoneNumber
|
||||
).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Observer<GenericOverall> {
|
||||
|
|
|
@ -25,7 +25,7 @@ package com.nextcloud.talk.controllers.bottomsheet
|
|||
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.graphics.PorterDuff
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.text.Editable
|
||||
|
@ -34,6 +34,7 @@ import android.text.TextUtils
|
|||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import autodagger.AutoInjector
|
||||
import com.bluelinelabs.conductor.RouterTransaction
|
||||
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
|
||||
|
@ -45,6 +46,8 @@ 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
|
||||
|
@ -71,6 +74,12 @@ 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
|
||||
|
@ -125,17 +134,11 @@ class EntryMenuController(args: Bundle) :
|
|||
rootView = view,
|
||||
editText = binding.textEdit,
|
||||
onEmojiPopupShownListener = {
|
||||
if (resources != null) {
|
||||
binding.smileyButton.setColorFilter(
|
||||
resources!!.getColor(R.color.colorPrimary),
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
viewThemeUtils.colorImageView(binding.smileyButton)
|
||||
},
|
||||
onEmojiPopupDismissListener = {
|
||||
binding.smileyButton.setColorFilter(
|
||||
resources!!.getColor(R.color.emoji_icons),
|
||||
PorterDuff.Mode.SRC_IN
|
||||
binding.smileyButton.imageTintList = ColorStateList.valueOf(
|
||||
ResourcesCompat.getColor(resources!!, R.color.medium_emphasis_text, context.theme)
|
||||
)
|
||||
},
|
||||
onEmojiClickListener = {
|
||||
|
@ -171,6 +174,9 @@ class EntryMenuController(args: Bundle) :
|
|||
binding.textInputLayout.endIconMode = TextInputLayout.END_ICON_NONE
|
||||
}
|
||||
|
||||
viewThemeUtils.colorTextInputLayout(binding.textInputLayout)
|
||||
viewThemeUtils.colorMaterialButtonText(binding.okButton)
|
||||
|
||||
binding.textInputLayout.hint = labelText
|
||||
binding.textInputLayout.requestFocus()
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import androidx.room.Transaction
|
|||
import androidx.room.Update
|
||||
import com.nextcloud.talk.data.user.model.UserEntity
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
|
||||
@Dao
|
||||
|
@ -41,6 +42,10 @@ abstract class UsersDao {
|
|||
@Query("SELECT * FROM User where current = 1")
|
||||
abstract fun getActiveUser(): Maybe<UserEntity>
|
||||
|
||||
// get active user
|
||||
@Query("SELECT * FROM User where current = 1")
|
||||
abstract fun getActiveUserObservable(): Observable<UserEntity>
|
||||
|
||||
@Query("SELECT * FROM User where current = 1")
|
||||
abstract fun getActiveUserSynchronously(): UserEntity?
|
||||
|
||||
|
|
|
@ -24,11 +24,13 @@ package com.nextcloud.talk.data.user
|
|||
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
interface UsersRepository {
|
||||
fun getActiveUser(): Maybe<User>
|
||||
fun getActiveUserObservable(): Observable<User>
|
||||
fun getUsers(): Single<List<User>>
|
||||
fun getUserWithId(id: Long): Maybe<User>
|
||||
fun getUserWithIdNotScheduledForDeletion(id: Long): Maybe<User>
|
||||
|
|
|
@ -24,6 +24,7 @@ package com.nextcloud.talk.data.user
|
|||
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
|
@ -33,6 +34,10 @@ class UsersRepositoryImpl(private val usersDao: UsersDao) : UsersRepository {
|
|||
return usersDao.getActiveUser().map { UserMapper.toModel(it) }
|
||||
}
|
||||
|
||||
override fun getActiveUserObservable(): Observable<User> {
|
||||
return usersDao.getActiveUserObservable().map { UserMapper.toModel(it) }
|
||||
}
|
||||
|
||||
override fun getUsers(): Single<List<User>> {
|
||||
return usersDao.getUsers().map { UserMapper.toModel(it) }
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ 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
|
||||
|
@ -64,6 +65,9 @@ class MessageSearchActivity : BaseActivity() {
|
|||
@Inject
|
||||
lateinit var userProvider: CurrentUserProviderNew
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
private lateinit var binding: ActivityMessageSearchBinding
|
||||
private lateinit var searchView: SearchView
|
||||
|
||||
|
@ -105,7 +109,9 @@ class MessageSearchActivity : BaseActivity() {
|
|||
DisplayUtils.applyColorToStatusBar(
|
||||
this,
|
||||
ResourcesCompat.getColor(
|
||||
resources, R.color.appbar, null
|
||||
resources,
|
||||
R.color.appbar,
|
||||
null
|
||||
)
|
||||
)
|
||||
DisplayUtils.applyColorToNavigationBar(
|
||||
|
@ -154,7 +160,7 @@ class MessageSearchActivity : BaseActivity() {
|
|||
emptyList()
|
||||
}
|
||||
val newItems =
|
||||
state.results.map { MessageResultItem(this, user, it) } + loadMoreItems
|
||||
state.results.map { MessageResultItem(this, user, it, false, viewThemeUtils) } + loadMoreItems
|
||||
|
||||
if (adapter != null) {
|
||||
adapter!!.updateDataSet(newItems)
|
||||
|
|
|
@ -43,6 +43,10 @@ data class ThemingCapability(
|
|||
var colorText: String?,
|
||||
@JsonField(name = ["color-element"])
|
||||
var colorElement: String?,
|
||||
@JsonField(name = ["color-element-bright"])
|
||||
var colorElementBright: String?,
|
||||
@JsonField(name = ["color-element-dark"])
|
||||
var colorElementDark: String?,
|
||||
@JsonField(name = ["logo"])
|
||||
var logo: String?,
|
||||
@JsonField(name = ["background"])
|
||||
|
@ -53,5 +57,5 @@ data class ThemingCapability(
|
|||
var backgroundDefault: Boolean?
|
||||
) : Parcelable {
|
||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
||||
constructor() : this(null, null, null, null, null, null, null, null, null, null)
|
||||
constructor() : this(null, null, null, null, null, null, null, null, null, null, null, null)
|
||||
}
|
||||
|
|
|
@ -26,10 +26,12 @@ import android.text.TextWatcher
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.databinding.PollCreateOptionsItemBinding
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.EmojiTextInputEditText
|
||||
|
||||
class PollCreateOptionViewHolder(
|
||||
private val binding: PollCreateOptionsItemBinding
|
||||
private val binding: PollCreateOptionsItemBinding,
|
||||
private val viewThemeUtils: ViewThemeUtils
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
lateinit var optionText: EmojiTextInputEditText
|
||||
|
@ -48,6 +50,7 @@ class PollCreateOptionViewHolder(
|
|||
}
|
||||
|
||||
binding.pollOptionTextEdit.setText(pollCreateOptionItem.pollOption)
|
||||
viewThemeUtils.colorEditText(binding.pollOptionTextEdit)
|
||||
|
||||
if (focus) {
|
||||
itemsListener.requestFocus(binding.pollOptionTextEdit)
|
||||
|
|
|
@ -24,9 +24,11 @@ import android.view.LayoutInflater
|
|||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nextcloud.talk.databinding.PollCreateOptionsItemBinding
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
|
||||
class PollCreateOptionsAdapter(
|
||||
private val clickListener: PollCreateOptionsItemListener
|
||||
private val clickListener: PollCreateOptionsItemListener,
|
||||
private val viewThemeUtils: ViewThemeUtils
|
||||
) : RecyclerView.Adapter<PollCreateOptionViewHolder>() {
|
||||
|
||||
internal var list: ArrayList<PollCreateOptionItem> = ArrayList()
|
||||
|
@ -34,7 +36,7 @@ class PollCreateOptionsAdapter(
|
|||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PollCreateOptionViewHolder {
|
||||
val itemBinding = PollCreateOptionsItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
|
||||
return PollCreateOptionViewHolder(itemBinding)
|
||||
return PollCreateOptionViewHolder(itemBinding, viewThemeUtils)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: PollCreateOptionViewHolder, position: Int) {
|
||||
|
|
|
@ -23,15 +23,19 @@ package com.nextcloud.talk.polls.adapters
|
|||
import android.annotation.SuppressLint
|
||||
import android.graphics.Typeface
|
||||
import com.nextcloud.talk.databinding.PollResultHeaderItemBinding
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
|
||||
class PollResultHeaderViewHolder(
|
||||
override val binding: PollResultHeaderItemBinding
|
||||
override val binding: PollResultHeaderItemBinding,
|
||||
private val viewThemeUtils: ViewThemeUtils
|
||||
) : PollResultViewHolder(binding) {
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun bind(pollResultItem: PollResultItem, clickListener: PollResultItemClickListener) {
|
||||
val item = pollResultItem as PollResultHeaderItem
|
||||
|
||||
viewThemeUtils.colorProgressBar(binding.pollOptionBar)
|
||||
|
||||
binding.root.setOnClickListener { clickListener.onClick() }
|
||||
|
||||
binding.pollOptionText.text = item.name
|
||||
|
|
|
@ -27,10 +27,12 @@ import com.nextcloud.talk.data.user.model.User
|
|||
import com.nextcloud.talk.databinding.PollResultHeaderItemBinding
|
||||
import com.nextcloud.talk.databinding.PollResultVoterItemBinding
|
||||
import com.nextcloud.talk.databinding.PollResultVotersOverviewItemBinding
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
|
||||
class PollResultsAdapter(
|
||||
private val user: User,
|
||||
private val clickListener: PollResultItemClickListener,
|
||||
private val viewThemeUtils: ViewThemeUtils
|
||||
) : RecyclerView.Adapter<PollResultViewHolder>() {
|
||||
internal var list: MutableList<PollResultItem> = ArrayList()
|
||||
|
||||
|
@ -43,7 +45,7 @@ class PollResultsAdapter(
|
|||
LayoutInflater.from(parent.context), parent,
|
||||
false
|
||||
)
|
||||
viewHolder = PollResultHeaderViewHolder(itemBinding)
|
||||
viewHolder = PollResultHeaderViewHolder(itemBinding, viewThemeUtils)
|
||||
}
|
||||
PollResultVoterItem.VIEW_TYPE -> {
|
||||
val itemBinding = PollResultVoterItemBinding.inflate(
|
||||
|
|
|
@ -43,6 +43,7 @@ import com.nextcloud.talk.polls.adapters.PollCreateOptionItem
|
|||
import com.nextcloud.talk.polls.adapters.PollCreateOptionsAdapter
|
||||
import com.nextcloud.talk.polls.adapters.PollCreateOptionsItemListener
|
||||
import com.nextcloud.talk.polls.viewmodels.PollCreateViewModel
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
|
@ -51,6 +52,9 @@ class PollCreateDialogFragment : DialogFragment(), PollCreateOptionsItemListener
|
|||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
private lateinit var binding: DialogPollCreateBinding
|
||||
private lateinit var viewModel: PollCreateViewModel
|
||||
|
||||
|
@ -85,13 +89,31 @@ class PollCreateDialogFragment : DialogFragment(), PollCreateOptionsItemListener
|
|||
|
||||
binding.pollCreateOptionsList.layoutManager = LinearLayoutManager(context)
|
||||
|
||||
adapter = PollCreateOptionsAdapter(this)
|
||||
adapter = PollCreateOptionsAdapter(this, viewThemeUtils)
|
||||
binding.pollCreateOptionsList.adapter = adapter
|
||||
|
||||
themeDialog()
|
||||
|
||||
setupListeners()
|
||||
setupStateObserver()
|
||||
}
|
||||
|
||||
private fun themeDialog() {
|
||||
viewThemeUtils.colorTextViewText(binding.pollQuestion)
|
||||
viewThemeUtils.colorTextViewText(binding.pollOptions)
|
||||
viewThemeUtils.colorTextViewText(binding.pollSettings)
|
||||
|
||||
viewThemeUtils.colorEditText(binding.pollCreateQuestionTextEdit)
|
||||
|
||||
viewThemeUtils.colorMaterialButtonText(binding.pollAddOptionsItem)
|
||||
// TODO button also needs a disabled state handling for colors
|
||||
viewThemeUtils.colorMaterialButtonText(binding.pollDismiss)
|
||||
viewThemeUtils.colorMaterialButtonBackground(binding.pollCreateButton)
|
||||
|
||||
viewThemeUtils.themeCheckbox(binding.pollPrivatePollCheckbox)
|
||||
viewThemeUtils.themeCheckbox(binding.pollMultipleAnswersCheckbox)
|
||||
}
|
||||
|
||||
private fun setupListeners() {
|
||||
binding.pollAddOptionsItem.setOnClickListener {
|
||||
viewModel.addOption()
|
||||
|
|
|
@ -38,6 +38,7 @@ import com.nextcloud.talk.polls.adapters.PollResultItemClickListener
|
|||
import com.nextcloud.talk.polls.adapters.PollResultsAdapter
|
||||
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||
import com.nextcloud.talk.polls.viewmodels.PollResultsViewModel
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
|
@ -46,6 +47,9 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener {
|
|||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
private lateinit var parentViewModel: PollMainViewModel
|
||||
lateinit var viewModel: PollResultsViewModel
|
||||
|
||||
|
@ -82,17 +86,24 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener {
|
|||
}
|
||||
|
||||
viewModel.items.observe(viewLifecycleOwner) {
|
||||
val adapter = PollResultsAdapter(parentViewModel.user, this).apply {
|
||||
val adapter = PollResultsAdapter(parentViewModel.user, this, viewThemeUtils).apply {
|
||||
if (it != null) {
|
||||
list = it
|
||||
}
|
||||
}
|
||||
binding.pollResultsList.adapter = adapter
|
||||
}
|
||||
|
||||
themeDialog()
|
||||
}
|
||||
|
||||
private fun themeDialog() {
|
||||
viewThemeUtils.colorMaterialButtonBackground(binding.editVoteButton)
|
||||
viewThemeUtils.colorMaterialButtonText(binding.pollResultsEndPollButton)
|
||||
}
|
||||
|
||||
private fun initAdapter() {
|
||||
adapter = PollResultsAdapter(parentViewModel.user, this)
|
||||
adapter = PollResultsAdapter(parentViewModel.user, this, viewThemeUtils)
|
||||
binding.pollResultsList.adapter = adapter
|
||||
binding.pollResultsList.layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import com.nextcloud.talk.databinding.DialogPollVoteBinding
|
|||
import com.nextcloud.talk.polls.model.Poll
|
||||
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||
import com.nextcloud.talk.polls.viewmodels.PollVoteViewModel
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
|
@ -51,6 +52,9 @@ class PollVoteFragment : Fragment() {
|
|||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
private lateinit var parentViewModel: PollMainViewModel
|
||||
lateinit var viewModel: PollVoteViewModel
|
||||
|
||||
|
@ -117,6 +121,14 @@ class PollVoteFragment : Fragment() {
|
|||
binding.pollVoteEditDismiss.setOnClickListener {
|
||||
parentViewModel.dismissEditVotes()
|
||||
}
|
||||
|
||||
themeDialog()
|
||||
}
|
||||
|
||||
private fun themeDialog() {
|
||||
viewThemeUtils.colorMaterialButtonBackground(binding.pollVoteSubmitButton)
|
||||
viewThemeUtils.colorMaterialButtonText(binding.pollVoteEndPollButton)
|
||||
viewThemeUtils.colorMaterialButtonText(binding.pollVoteEditDismiss)
|
||||
}
|
||||
|
||||
private fun updateDismissEditButton(showDismissEditButton: Boolean) {
|
||||
|
@ -136,6 +148,7 @@ class PollVoteFragment : Fragment() {
|
|||
RadioButton(context).apply { text = option }
|
||||
}?.forEachIndexed { index, radioButton ->
|
||||
radioButton.id = index
|
||||
viewThemeUtils.themeRadioButton(radioButton)
|
||||
makeOptionBoldIfSelfVoted(radioButton, poll, index)
|
||||
binding.pollVoteRadioGroup.addView(radioButton)
|
||||
|
||||
|
@ -156,6 +169,7 @@ class PollVoteFragment : Fragment() {
|
|||
setLayoutParams(layoutParams)
|
||||
}
|
||||
}?.forEachIndexed { index, checkBox ->
|
||||
viewThemeUtils.themeCheckbox(checkBox)
|
||||
checkBox.id = index
|
||||
makeOptionBoldIfSelfVoted(checkBox, poll, index)
|
||||
binding.voteOptionsCheckboxesWrapper.addView(checkBox)
|
||||
|
|
|
@ -44,6 +44,7 @@ import com.nextcloud.talk.remotefilebrowser.SelectionInterface
|
|||
import com.nextcloud.talk.remotefilebrowser.adapters.RemoteFileBrowserItemsAdapter
|
||||
import com.nextcloud.talk.remotefilebrowser.viewmodels.RemoteFileBrowserItemsViewModel
|
||||
import com.nextcloud.talk.ui.dialog.SortingOrderDialogFragment
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.FileSortOrder
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_MIME_TYPE_FILTER
|
||||
|
@ -59,6 +60,9 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||
@Inject
|
||||
lateinit var currentUserProvider: CurrentUserProviderNew
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
private lateinit var binding: ActivityRemoteFileBrowserBinding
|
||||
private lateinit var viewModel: RemoteFileBrowserItemsViewModel
|
||||
|
||||
|
@ -91,8 +95,7 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||
initViewModel(mimeTypeSelectionFilter)
|
||||
|
||||
binding.swipeRefreshList.setOnRefreshListener(this)
|
||||
binding.swipeRefreshList.setColorSchemeResources(R.color.colorPrimary)
|
||||
binding.swipeRefreshList.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background)
|
||||
viewThemeUtils.themeSwipeRefreshLayout(binding.swipeRefreshList)
|
||||
|
||||
binding.pathNavigationBackButton.setOnClickListener { viewModel.navigateUp() }
|
||||
binding.sortButton.setOnClickListener { changeSorting() }
|
||||
|
@ -160,6 +163,7 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||
mimeTypeSelectionFilter = mimeTypeSelectionFilter,
|
||||
user = currentUserProvider.currentUser.blockingGet(),
|
||||
selectionInterface = this,
|
||||
viewThemeUtils = viewThemeUtils,
|
||||
onItemClicked = viewModel::onItemClicked
|
||||
)
|
||||
adapter.items = remoteFileBrowserItems
|
||||
|
|
|
@ -28,19 +28,20 @@ import com.nextcloud.talk.data.user.model.User
|
|||
import com.nextcloud.talk.databinding.RvItemBrowserFileBinding
|
||||
import com.nextcloud.talk.remotefilebrowser.SelectionInterface
|
||||
import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
|
||||
class RemoteFileBrowserItemsAdapter(
|
||||
private val showGrid: Boolean = false,
|
||||
private val mimeTypeSelectionFilter: String? = null,
|
||||
private val user: User,
|
||||
private val selectionInterface: SelectionInterface,
|
||||
private val viewThemeUtils: ViewThemeUtils,
|
||||
private val onItemClicked: (RemoteFileBrowserItem) -> Unit
|
||||
) : RecyclerView.Adapter<RemoteFileBrowserItemsViewHolder>() {
|
||||
|
||||
var items: List<RemoteFileBrowserItem> = emptyList()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RemoteFileBrowserItemsViewHolder {
|
||||
|
||||
return if (showGrid) {
|
||||
RemoteFileBrowserItemsListViewHolder(
|
||||
RvItemBrowserFileBinding.inflate(
|
||||
|
@ -50,7 +51,8 @@ class RemoteFileBrowserItemsAdapter(
|
|||
),
|
||||
mimeTypeSelectionFilter,
|
||||
user,
|
||||
selectionInterface
|
||||
selectionInterface,
|
||||
viewThemeUtils
|
||||
) {
|
||||
onItemClicked(items[it])
|
||||
}
|
||||
|
@ -63,7 +65,8 @@ class RemoteFileBrowserItemsAdapter(
|
|||
),
|
||||
mimeTypeSelectionFilter,
|
||||
user,
|
||||
selectionInterface
|
||||
selectionInterface,
|
||||
viewThemeUtils
|
||||
) {
|
||||
onItemClicked(items[it])
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ package com.nextcloud.talk.remotefilebrowser.adapters
|
|||
|
||||
import android.text.format.Formatter
|
||||
import android.view.View
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import autodagger.AutoInjector
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.drawee.interfaces.DraweeController
|
||||
|
@ -33,10 +32,10 @@ import com.nextcloud.talk.data.user.model.User
|
|||
import com.nextcloud.talk.databinding.RvItemBrowserFileBinding
|
||||
import com.nextcloud.talk.remotefilebrowser.SelectionInterface
|
||||
import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.DateUtils.getLocalDateTimeStringFromTimestamp
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.DrawableUtils.getDrawableResourceIdForMimeType
|
||||
import com.nextcloud.talk.utils.Mimetype.FOLDER
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
|
@ -45,6 +44,7 @@ class RemoteFileBrowserItemsListViewHolder(
|
|||
mimeTypeSelectionFilter: String?,
|
||||
currentUser: User,
|
||||
selectionInterface: SelectionInterface,
|
||||
private val viewThemeUtils: ViewThemeUtils,
|
||||
onItemClicked: (Int) -> Unit
|
||||
) : RemoteFileBrowserItemsViewHolder(binding, mimeTypeSelectionFilter, currentUser, selectionInterface) {
|
||||
|
||||
|
@ -66,7 +66,6 @@ class RemoteFileBrowserItemsListViewHolder(
|
|||
}
|
||||
|
||||
override fun onBind(item: RemoteFileBrowserItem) {
|
||||
|
||||
super.onBind(item)
|
||||
|
||||
binding.fileIcon.controller = null
|
||||
|
@ -99,9 +98,7 @@ class RemoteFileBrowserItemsListViewHolder(
|
|||
binding.fileIcon
|
||||
.hierarchy
|
||||
.setPlaceholderImage(
|
||||
AppCompatResources.getDrawable(
|
||||
binding.fileIcon.context, getDrawableResourceIdForMimeType(item.mimeType)
|
||||
)
|
||||
viewThemeUtils.getPlaceholderImage(binding.root.context, item.mimeType)
|
||||
)
|
||||
|
||||
if (item.hasPreview) {
|
||||
|
@ -132,6 +129,7 @@ class RemoteFileBrowserItemsListViewHolder(
|
|||
private fun setSelectability() {
|
||||
if (selectable) {
|
||||
binding.selectFileCheckbox.visibility = View.VISIBLE
|
||||
viewThemeUtils.themeCheckbox(binding.selectFileCheckbox)
|
||||
} else {
|
||||
binding.selectFileCheckbox.visibility = View.GONE
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import com.nextcloud.talk.databinding.ActivitySharedItemsBinding
|
|||
import com.nextcloud.talk.shareditems.adapters.SharedItemsAdapter
|
||||
import com.nextcloud.talk.shareditems.model.SharedItemType
|
||||
import com.nextcloud.talk.shareditems.viewmodels.SharedItemsViewModel
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
|
@ -53,6 +54,9 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
private lateinit var binding: ActivitySharedItemsBinding
|
||||
private lateinit var viewModel: SharedItemsViewModel
|
||||
|
||||
|
@ -72,7 +76,9 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||
DisplayUtils.applyColorToStatusBar(
|
||||
this,
|
||||
ResourcesCompat.getColor(
|
||||
resources, R.color.appbar, null
|
||||
resources,
|
||||
R.color.appbar,
|
||||
null
|
||||
)
|
||||
)
|
||||
DisplayUtils.applyColorToNavigationBar(
|
||||
|
@ -130,7 +136,8 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||
showGrid,
|
||||
user,
|
||||
roomToken,
|
||||
isUserConversationOwnerOrModerator
|
||||
isUserConversationOwnerOrModerator,
|
||||
viewThemeUtils
|
||||
).apply {
|
||||
items = sharedMediaItems.items
|
||||
}
|
||||
|
@ -142,6 +149,8 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||
}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
viewThemeUtils.colorTabLayout(binding.sharedItemsTabs)
|
||||
}
|
||||
|
||||
private fun clearEmptyLoading() {
|
||||
|
@ -161,7 +170,6 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun initTabs(sharedItemTypes: Set<SharedItemType>) {
|
||||
|
||||
binding.sharedItemsTabs.removeAllTabs()
|
||||
|
||||
if (sharedItemTypes.contains(SharedItemType.MEDIA)) {
|
||||
|
|
|
@ -37,18 +37,19 @@ import com.nextcloud.talk.shareditems.model.SharedItem
|
|||
import com.nextcloud.talk.shareditems.model.SharedLocationItem
|
||||
import com.nextcloud.talk.shareditems.model.SharedOtherItem
|
||||
import com.nextcloud.talk.shareditems.model.SharedPollItem
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
|
||||
class SharedItemsAdapter(
|
||||
private val showGrid: Boolean,
|
||||
private val user: User,
|
||||
private val roomToken: String,
|
||||
private val isUserConversationOwnerOrModerator: Boolean
|
||||
private val isUserConversationOwnerOrModerator: Boolean,
|
||||
private val viewThemeUtils: ViewThemeUtils
|
||||
) : RecyclerView.Adapter<SharedItemsViewHolder>() {
|
||||
|
||||
var items: List<SharedItem> = emptyList()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SharedItemsViewHolder {
|
||||
|
||||
return if (showGrid) {
|
||||
SharedItemsGridViewHolder(
|
||||
SharedItemGridBinding.inflate(
|
||||
|
@ -56,7 +57,8 @@ class SharedItemsAdapter(
|
|||
parent,
|
||||
false
|
||||
),
|
||||
user
|
||||
user,
|
||||
viewThemeUtils
|
||||
)
|
||||
} else {
|
||||
SharedItemsListViewHolder(
|
||||
|
@ -65,7 +67,8 @@ class SharedItemsAdapter(
|
|||
parent,
|
||||
false
|
||||
),
|
||||
user
|
||||
user,
|
||||
viewThemeUtils
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,11 +27,13 @@ import android.widget.ProgressBar
|
|||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.SharedItemGridBinding
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
|
||||
class SharedItemsGridViewHolder(
|
||||
override val binding: SharedItemGridBinding,
|
||||
user: User
|
||||
) : SharedItemsViewHolder(binding, user) {
|
||||
user: User,
|
||||
viewThemeUtils: ViewThemeUtils
|
||||
) : SharedItemsViewHolder(binding, user, viewThemeUtils) {
|
||||
|
||||
override val image: SimpleDraweeView
|
||||
get() = binding.image
|
||||
|
|
|
@ -38,11 +38,13 @@ import com.nextcloud.talk.shareditems.model.SharedItem
|
|||
import com.nextcloud.talk.shareditems.model.SharedLocationItem
|
||||
import com.nextcloud.talk.shareditems.model.SharedOtherItem
|
||||
import com.nextcloud.talk.shareditems.model.SharedPollItem
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
|
||||
class SharedItemsListViewHolder(
|
||||
override val binding: SharedItemListBinding,
|
||||
user: User
|
||||
) : SharedItemsViewHolder(binding, user) {
|
||||
user: User,
|
||||
viewThemeUtils: ViewThemeUtils
|
||||
) : SharedItemsViewHolder(binding, user, viewThemeUtils) {
|
||||
|
||||
override val image: SimpleDraweeView
|
||||
get() = binding.fileImage
|
||||
|
@ -52,7 +54,6 @@ class SharedItemsListViewHolder(
|
|||
get() = binding.progressBar
|
||||
|
||||
override fun onBind(item: SharedFileItem) {
|
||||
|
||||
super.onBind(item)
|
||||
|
||||
binding.fileName.text = item.name
|
||||
|
|
|
@ -23,12 +23,10 @@
|
|||
package com.nextcloud.talk.shareditems.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.ProgressBar
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
|
@ -43,16 +41,17 @@ import com.nextcloud.talk.data.user.model.User
|
|||
import com.nextcloud.talk.shareditems.model.SharedDeckCardItem
|
||||
import com.nextcloud.talk.shareditems.model.SharedFileItem
|
||||
import com.nextcloud.talk.shareditems.model.SharedItem
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.shareditems.model.SharedLocationItem
|
||||
import com.nextcloud.talk.shareditems.model.SharedOtherItem
|
||||
import com.nextcloud.talk.shareditems.model.SharedPollItem
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.DrawableUtils
|
||||
import com.nextcloud.talk.utils.FileViewerUtils
|
||||
|
||||
abstract class SharedItemsViewHolder(
|
||||
open val binding: ViewBinding,
|
||||
internal val user: User
|
||||
internal val user: User,
|
||||
private val viewThemeUtils: ViewThemeUtils
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
companion object {
|
||||
|
@ -71,7 +70,7 @@ abstract class SharedItemsViewHolder(
|
|||
)
|
||||
|
||||
open fun onBind(item: SharedFileItem) {
|
||||
image.hierarchy.setPlaceholderImage(staticImage(item.mimeType, image))
|
||||
image.hierarchy.setPlaceholderImage(viewThemeUtils.getPlaceholderImage(image.context, item.mimeType))
|
||||
if (item.previewAvailable) {
|
||||
image.controller = configurePreview(item)
|
||||
}
|
||||
|
@ -107,7 +106,6 @@ abstract class SharedItemsViewHolder(
|
|||
}
|
||||
|
||||
private fun configurePreview(item: SharedFileItem): DraweeController {
|
||||
|
||||
val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(item.previewLink))
|
||||
.setProgressiveRenderingEnabled(true)
|
||||
.setRotationOptions(RotationOptions.autoRotate())
|
||||
|
@ -136,12 +134,4 @@ abstract class SharedItemsViewHolder(
|
|||
open fun onBind(item: SharedOtherItem) {}
|
||||
|
||||
open fun onBind(item: SharedDeckCardItem) {}
|
||||
|
||||
private fun staticImage(
|
||||
mimeType: String?,
|
||||
image: SimpleDraweeView
|
||||
): Drawable {
|
||||
val drawableResourceId = DrawableUtils.getDrawableResourceIdForMimeType(mimeType)
|
||||
return ContextCompat.getDrawable(image.context, drawableResourceId)!!
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,18 +24,33 @@ import android.os.Bundle
|
|||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
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.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
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(callActivity) {
|
||||
|
||||
@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)
|
||||
dialogAudioOutputBinding = DialogAudioOutputBinding.inflate(layoutInflater)
|
||||
|
@ -82,55 +97,23 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call
|
|||
private fun highlightActiveOutputChannel() {
|
||||
when (callActivity.audioManager?.currentAudioDevice) {
|
||||
WebRtcAudioManager.AudioDevice.BLUETOOTH -> {
|
||||
dialogAudioOutputBinding.audioOutputBluetoothIcon.setColorFilter(
|
||||
ContextCompat.getColor(
|
||||
context,
|
||||
R.color.colorPrimary
|
||||
),
|
||||
android.graphics.PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
dialogAudioOutputBinding.audioOutputBluetoothText.setTextColor(
|
||||
callActivity.resources.getColor(R.color.colorPrimary)
|
||||
)
|
||||
viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputBluetoothIcon)
|
||||
dialogAudioOutputBinding.audioOutputBluetoothText.setTextColor(serverTheme.primaryColor)
|
||||
}
|
||||
|
||||
WebRtcAudioManager.AudioDevice.SPEAKER_PHONE -> {
|
||||
dialogAudioOutputBinding.audioOutputSpeakerIcon.setColorFilter(
|
||||
ContextCompat.getColor(
|
||||
context,
|
||||
R.color.colorPrimary
|
||||
),
|
||||
android.graphics.PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
dialogAudioOutputBinding.audioOutputSpeakerText.setTextColor(
|
||||
callActivity.resources.getColor(R.color.colorPrimary)
|
||||
)
|
||||
viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputSpeakerIcon)
|
||||
dialogAudioOutputBinding.audioOutputSpeakerText.setTextColor(serverTheme.primaryColor)
|
||||
}
|
||||
|
||||
WebRtcAudioManager.AudioDevice.EARPIECE -> {
|
||||
dialogAudioOutputBinding.audioOutputEarspeakerIcon.setColorFilter(
|
||||
ContextCompat.getColor(
|
||||
context,
|
||||
R.color.colorPrimary
|
||||
),
|
||||
android.graphics.PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
dialogAudioOutputBinding.audioOutputEarspeakerText.setTextColor(
|
||||
callActivity.resources.getColor(R.color.colorPrimary)
|
||||
)
|
||||
viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputEarspeakerIcon)
|
||||
dialogAudioOutputBinding.audioOutputEarspeakerText.setTextColor(serverTheme.primaryColor)
|
||||
}
|
||||
|
||||
WebRtcAudioManager.AudioDevice.WIRED_HEADSET -> {
|
||||
dialogAudioOutputBinding.audioOutputWiredHeadsetIcon.setColorFilter(
|
||||
ContextCompat.getColor(
|
||||
context,
|
||||
R.color.colorPrimary
|
||||
),
|
||||
android.graphics.PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
dialogAudioOutputBinding.audioOutputWiredHeadsetText.setTextColor(
|
||||
callActivity.resources.getColor(R.color.colorPrimary)
|
||||
)
|
||||
viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputWiredHeadsetIcon)
|
||||
dialogAudioOutputBinding.audioOutputWiredHeadsetText.setTextColor(serverTheme.primaryColor)
|
||||
}
|
||||
|
||||
else -> Log.d(TAG, "AudioOutputDialog doesn't know this AudioDevice")
|
||||
|
|
|
@ -51,6 +51,7 @@ import com.nextcloud.talk.models.json.status.Status;
|
|||
import com.nextcloud.talk.models.json.status.StatusOverall;
|
||||
import com.nextcloud.talk.ui.StatusDrawable;
|
||||
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.database.user.CapabilitiesUtilNew;
|
||||
|
@ -87,6 +88,9 @@ public class ChooseAccountDialogFragment extends DialogFragment {
|
|||
@Inject
|
||||
NcApi ncApi;
|
||||
|
||||
@Inject
|
||||
ViewThemeUtils viewThemeUtils;
|
||||
|
||||
private DialogChooseAccountBinding binding;
|
||||
private View dialogView;
|
||||
|
||||
|
@ -120,6 +124,9 @@ public class ChooseAccountDialogFragment extends DialogFragment {
|
|||
binding.currentAccount.ticker.setVisibility(View.GONE);
|
||||
binding.currentAccount.account.setText((Uri.parse(user.getBaseUrl()).getHost()));
|
||||
|
||||
viewThemeUtils.colorImageView(binding.currentAccount.accountMenu);
|
||||
|
||||
|
||||
if (user.getBaseUrl() != null &&
|
||||
(user.getBaseUrl().startsWith("http://") || user.getBaseUrl().startsWith("https://"))) {
|
||||
binding.currentAccount.userIcon.setVisibility(View.VISIBLE);
|
||||
|
|
|
@ -34,12 +34,15 @@ import android.view.inputmethod.InputMethodManager
|
|||
import android.widget.AdapterView
|
||||
import android.widget.AdapterView.OnItemSelectedListener
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.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.nextcloud.talk.R
|
||||
import com.nextcloud.talk.adapters.PredefinedStatusClickListener
|
||||
import com.nextcloud.talk.adapters.PredefinedStatusListAdapter
|
||||
|
@ -53,6 +56,7 @@ import com.nextcloud.talk.models.json.status.Status
|
|||
import com.nextcloud.talk.models.json.status.StatusType
|
||||
import com.nextcloud.talk.models.json.status.predefined.PredefinedStatus
|
||||
import com.nextcloud.talk.models.json.status.predefined.PredefinedStatusOverall
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.vanniktech.emoji.EmojiPopup
|
||||
|
@ -105,6 +109,9 @@ class SetStatusDialogFragment :
|
|||
@Inject
|
||||
lateinit var ncApi: NcApi
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
lateinit var credentials: String
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -234,8 +241,8 @@ class SetStatusDialogFragment :
|
|||
}
|
||||
}
|
||||
|
||||
binding.clearStatus.setTextColor(resources.getColor(R.color.colorPrimary))
|
||||
binding.setStatus.setBackgroundColor(resources.getColor(R.color.colorPrimary))
|
||||
viewThemeUtils.colorMaterialButtonText(binding.clearStatus)
|
||||
viewThemeUtils.colorMaterialButtonBackground(binding.setStatus)
|
||||
|
||||
binding.customStatusInput.highlightColor = resources.getColor(R.color.colorPrimary)
|
||||
|
||||
|
@ -258,7 +265,6 @@ class SetStatusDialogFragment :
|
|||
|
||||
@Suppress("ComplexMethod")
|
||||
private fun setClearStatusAfterValue(item: Int) {
|
||||
|
||||
val currentTime = System.currentTimeMillis() / ONE_SECOND_IN_MILLIS
|
||||
|
||||
when (item) {
|
||||
|
@ -310,7 +316,6 @@ class SetStatusDialogFragment :
|
|||
}
|
||||
|
||||
private fun clearAtToUnixTime(clearAt: ClearAt?): Long {
|
||||
|
||||
var returnValue = -1L
|
||||
|
||||
if (clearAt != null) {
|
||||
|
@ -400,25 +405,18 @@ class SetStatusDialogFragment :
|
|||
|
||||
private fun visualizeStatus(statusType: StatusType) {
|
||||
clearTopStatus()
|
||||
when (statusType) {
|
||||
StatusType.ONLINE -> {
|
||||
binding.onlineStatus.setCardBackgroundColor(resources.getColor(R.color.colorPrimary))
|
||||
binding.onlineHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text_dark_background))
|
||||
val views: Triple<MaterialCardView, TextView, ImageView> = when (statusType) {
|
||||
StatusType.ONLINE -> Triple(binding.onlineStatus, binding.onlineHeadline, binding.onlineIcon)
|
||||
StatusType.AWAY -> Triple(binding.awayStatus, binding.awayHeadline, binding.awayIcon)
|
||||
StatusType.DND -> Triple(binding.dndStatus, binding.dndHeadline, binding.dndIcon)
|
||||
StatusType.INVISIBLE -> Triple(binding.invisibleStatus, binding.invisibleHeadline, binding.invisibleIcon)
|
||||
else -> {
|
||||
Log.d(TAG, "unknown status")
|
||||
return
|
||||
}
|
||||
StatusType.AWAY -> {
|
||||
binding.awayStatus.setCardBackgroundColor(resources.getColor(R.color.colorPrimary))
|
||||
binding.awayHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text_dark_background))
|
||||
}
|
||||
StatusType.DND -> {
|
||||
binding.dndStatus.setCardBackgroundColor(resources.getColor(R.color.colorPrimary))
|
||||
binding.dndHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text_dark_background))
|
||||
}
|
||||
StatusType.INVISIBLE -> {
|
||||
binding.invisibleStatus.setCardBackgroundColor(resources.getColor(R.color.colorPrimary))
|
||||
binding.invisibleHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text_dark_background))
|
||||
}
|
||||
else -> Log.d(TAG, "unknown status")
|
||||
}
|
||||
viewThemeUtils.colorCardViewBackground(views.first)
|
||||
viewThemeUtils.colorTextViewText(views.second)
|
||||
}
|
||||
|
||||
private fun clearTopStatus() {
|
||||
|
@ -433,11 +431,15 @@ class SetStatusDialogFragment :
|
|||
binding.awayHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text))
|
||||
binding.dndHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text))
|
||||
binding.invisibleHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text))
|
||||
|
||||
binding.onlineIcon.imageTintList = null
|
||||
binding.awayIcon.imageTintList = null
|
||||
binding.dndIcon.imageTintList = null
|
||||
binding.invisibleIcon.imageTintList = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun setStatusMessage() {
|
||||
|
||||
val inputText = binding.customStatusInput.text.toString().ifEmpty { "" }
|
||||
// The endpoint '/message/custom' expects a valid emoji as string or null
|
||||
val statusIcon = binding.emoji.text.toString().ifEmpty { null }
|
||||
|
@ -446,7 +448,6 @@ class SetStatusDialogFragment :
|
|||
selectedPredefinedStatus!!.message != inputText ||
|
||||
selectedPredefinedStatus!!.icon != binding.emoji.text.toString()
|
||||
) {
|
||||
|
||||
ncApi.setCustomStatusMessage(
|
||||
credentials,
|
||||
ApiUtils.getUrlForSetCustomStatus(currentUser?.baseUrl),
|
||||
|
@ -476,12 +477,13 @@ class SetStatusDialogFragment :
|
|||
}
|
||||
})
|
||||
} else {
|
||||
|
||||
val clearAt = clearAtToUnixTime(selectedPredefinedStatus!!.clearAt)
|
||||
|
||||
ncApi.setPredefinedStatusMessage(
|
||||
credentials, ApiUtils.getUrlForSetPredefinedStatus(currentUser?.baseUrl),
|
||||
selectedPredefinedStatus!!.id, if (clearAt == -1L) null else clearAt
|
||||
credentials,
|
||||
ApiUtils.getUrlForSetPredefinedStatus(currentUser?.baseUrl),
|
||||
selectedPredefinedStatus!!.id,
|
||||
if (clearAt == -1L) null else clearAt
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())?.subscribe(object : Observer<GenericOverall> {
|
||||
|
@ -506,7 +508,6 @@ class SetStatusDialogFragment :
|
|||
}
|
||||
|
||||
override fun onClick(predefinedStatus: PredefinedStatus) {
|
||||
|
||||
selectedPredefinedStatus = predefinedStatus
|
||||
|
||||
clearAt = clearAtToUnixTime(predefinedStatus.clearAt)
|
||||
|
|
|
@ -51,6 +51,7 @@ 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.utils.ApiUtils
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
|
@ -65,7 +66,8 @@ class ShowReactionsDialog(
|
|||
private val chatMessage: ChatMessage,
|
||||
private val user: User?,
|
||||
private val hasChatPermission: Boolean,
|
||||
private val ncApi: NcApi
|
||||
private val ncApi: NcApi,
|
||||
private val serverTheme: ServerTheme
|
||||
) : BottomSheetDialog(activity), ReactionItemClickListener {
|
||||
|
||||
private lateinit var binding: DialogMessageReactionsBinding
|
||||
|
@ -96,6 +98,7 @@ 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"
|
||||
|
|
|
@ -33,9 +33,9 @@ import android.widget.TextView;
|
|||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.nextcloud.talk.R;
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||
import com.nextcloud.talk.databinding.SortingOrderFragmentBinding;
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils;
|
||||
import com.nextcloud.talk.utils.FileSortOrder;
|
||||
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
||||
|
||||
|
@ -46,7 +46,6 @@ import javax.inject.Inject;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import autodagger.AutoInjector;
|
||||
import kotlin.jvm.JvmField;
|
||||
|
||||
/**
|
||||
* Dialog to show and choose the sorting order for the file listing.
|
||||
|
@ -60,9 +59,11 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O
|
|||
private static final String KEY_SORT_ORDER = "SORT_ORDER";
|
||||
|
||||
@Inject
|
||||
@JvmField
|
||||
AppPreferences appPreferences;
|
||||
|
||||
@Inject
|
||||
ViewThemeUtils viewThemeUtils;
|
||||
|
||||
private SortingOrderFragmentBinding binding;
|
||||
private View dialogView;
|
||||
|
||||
|
@ -119,7 +120,7 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O
|
|||
* find all relevant UI elements and set their values.
|
||||
*/
|
||||
private void setupDialogElements() {
|
||||
binding.cancel.setTextColor(getResources().getColor(R.color.colorPrimary));
|
||||
viewThemeUtils.colorMaterialButtonText(binding.cancel);
|
||||
|
||||
taggedViews = new View[12];
|
||||
taggedViews[0] = binding.sortByNameAscending;
|
||||
|
@ -154,7 +155,6 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O
|
|||
* tints the icon reflecting the actual sorting choice in the apps primary color.
|
||||
*/
|
||||
private void setupActiveOrderSelection() {
|
||||
final int color = getResources().getColor(R.color.colorPrimary);
|
||||
Log.i("SortOrder", "currentSortOrderName=" + currentSortOrderName);
|
||||
for (View view : taggedViews) {
|
||||
Log.i("SortOrder", ((FileSortOrder) view.getTag()).getName());
|
||||
|
@ -162,10 +162,10 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O
|
|||
continue;
|
||||
}
|
||||
if (view instanceof MaterialButton) {
|
||||
((MaterialButton) view).setIconTintResource(R.color.colorPrimary);
|
||||
viewThemeUtils.colorMaterialButtonText((MaterialButton) view);
|
||||
}
|
||||
if (view instanceof TextView) {
|
||||
((TextView) view).setTextColor(color);
|
||||
viewThemeUtils.colorTextViewElement((TextView) view);
|
||||
((TextView) view).setTypeface(Typeface.DEFAULT_BOLD);
|
||||
}
|
||||
}
|
||||
|
|
53
app/src/main/java/com/nextcloud/talk/ui/theme/ServerTheme.kt
Normal file
53
app/src/main/java/com/nextcloud/talk/ui/theme/ServerTheme.kt
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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 androidx.annotation.ColorInt
|
||||
|
||||
interface ServerTheme {
|
||||
@get:ColorInt
|
||||
val primaryColor: Int
|
||||
|
||||
/**
|
||||
* Default element color
|
||||
*/
|
||||
@get:ColorInt
|
||||
val colorElement: Int
|
||||
|
||||
/**
|
||||
* Element color for bright backgrounds
|
||||
*/
|
||||
@get:ColorInt
|
||||
val colorElementBright: Int
|
||||
|
||||
/**
|
||||
* Element color for dark backgrounds
|
||||
*/
|
||||
@get:ColorInt
|
||||
val colorElementDark: Int
|
||||
|
||||
/**
|
||||
* Text color for elements
|
||||
*/
|
||||
@get:ColorInt
|
||||
val colorText: Int
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* @author Andy Scherzinger
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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 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 {
|
||||
|
||||
override val primaryColor: Int
|
||||
override val colorElement: Int
|
||||
override val colorElementBright: Int
|
||||
override val colorElementDark: Int
|
||||
override val colorText: Int
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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 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
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* @author Andy Scherzinger
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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 com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.models.json.capabilities.Capabilities
|
||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||
import com.nextcloud.talk.utils.ui.ColorUtil
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class ServerThemeProviderImpl @Inject constructor(
|
||||
private val userProvider: CurrentUserProviderNew,
|
||||
private val colorUtil: ColorUtil
|
||||
) : ServerThemeProvider {
|
||||
|
||||
private val themeCache: ConcurrentHashMap<String, ServerTheme> = ConcurrentHashMap()
|
||||
|
||||
override fun getServerThemeForUser(user: User?): ServerTheme {
|
||||
val url: String = if (user?.baseUrl != null) {
|
||||
user.baseUrl!!
|
||||
} else {
|
||||
FALLBACK_URL
|
||||
}
|
||||
|
||||
if (!themeCache.containsKey(url)) {
|
||||
themeCache[url] = getServerThemeForCapabilities(user?.capabilities)
|
||||
}
|
||||
|
||||
return themeCache[url]!!
|
||||
}
|
||||
|
||||
override fun getServerThemeForCurrentUser(): ServerTheme {
|
||||
return getServerThemeForUser(userProvider.currentUser.blockingGet())
|
||||
}
|
||||
|
||||
override fun getServerThemeForCapabilities(capabilities: Capabilities?): ServerTheme {
|
||||
return ServerThemeImpl(capabilities?.themingCapability, colorUtil)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val FALLBACK_URL = "NULL"
|
||||
}
|
||||
}
|
44
app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt
Normal file
44
app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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 com.nextcloud.talk.dagger.modules.ContextModule
|
||||
import com.nextcloud.talk.utils.database.user.UserModule
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.Reusable
|
||||
|
||||
@Module(includes = [ContextModule::class, UserModule::class])
|
||||
internal abstract class ThemeModule {
|
||||
|
||||
@Binds
|
||||
@Reusable
|
||||
abstract fun bindServerThemeProvider(provider: ServerThemeProviderImpl): ServerThemeProvider
|
||||
|
||||
companion object {
|
||||
@Provides
|
||||
fun provideCurrentServerTheme(themeProvider: ServerThemeProvider): ServerTheme {
|
||||
return themeProvider.getServerThemeForCurrentUser()
|
||||
}
|
||||
}
|
||||
}
|
364
app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt
Normal file
364
app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt
Normal file
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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 android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.widget.CheckBox
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.RadioButton
|
||||
import android.widget.SeekBar
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
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.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.utils.DrawableUtils
|
||||
import com.nextcloud.talk.utils.ui.ColorUtil
|
||||
import com.nextcloud.talk.utils.ui.PlatformThemeUtil.isDarkMode
|
||||
import com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
import com.yarolegovich.mp.MaterialSwitchPreference
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
class ViewThemeUtils @Inject constructor(private val theme: ServerTheme, private val colorUtil: ColorUtil) {
|
||||
|
||||
/**
|
||||
* Color for painting elements
|
||||
*/
|
||||
fun getElementColor(context: Context): Int = when {
|
||||
isDarkMode(context) -> theme.colorElementDark
|
||||
else -> theme.colorElementBright
|
||||
}
|
||||
|
||||
private fun withElementColor(view: View, block: (Int) -> Unit) {
|
||||
block(getElementColor(view.context))
|
||||
}
|
||||
|
||||
fun themeFAB(fab: FloatingActionButton) {
|
||||
withElementColor(fab) { color ->
|
||||
fab.backgroundTintList = ColorStateList.valueOf(color)
|
||||
fab.imageTintList = ColorStateList.valueOf(theme.colorText)
|
||||
}
|
||||
}
|
||||
|
||||
fun themeHorizontalSeekBar(seekBar: SeekBar) {
|
||||
withElementColor(seekBar) { color ->
|
||||
themeHorizontalSeekBar(seekBar, color)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
progressBar.progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorTextViewElement(textView: TextView) {
|
||||
withElementColor(textView) { color ->
|
||||
textView.setTextColor(color)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorTextViewText(textView: TextView) {
|
||||
textView.setTextColor(theme.colorText)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tints the image with element color
|
||||
*/
|
||||
fun colorImageView(imageView: ImageView) {
|
||||
withElementColor(imageView) { color ->
|
||||
imageView.imageTintList = ColorStateList.valueOf(color)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tints the image with text color
|
||||
*/
|
||||
fun colorImageViewText(imageView: ImageView) {
|
||||
imageView.imageTintList = ColorStateList.valueOf(theme.colorText)
|
||||
}
|
||||
|
||||
fun colorMaterialButtonText(button: MaterialButton) {
|
||||
withElementColor(button) { color ->
|
||||
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)
|
||||
)
|
||||
button.setTextColor(colorStateList)
|
||||
button.iconTint = colorStateList
|
||||
}
|
||||
}
|
||||
|
||||
fun colorMaterialButtonBackground(button: MaterialButton) {
|
||||
withElementColor(button) { color ->
|
||||
button.setBackgroundColor(color)
|
||||
|
||||
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(theme.colorText, disabledColor)
|
||||
)
|
||||
|
||||
button.setTextColor(colorStateList)
|
||||
button.iconTint = colorStateList
|
||||
}
|
||||
}
|
||||
|
||||
fun colorCardViewBackground(card: MaterialCardView) {
|
||||
withElementColor(card) { color ->
|
||||
card.setCardBackgroundColor(color)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO split this util into classes depending on framework views vs library views
|
||||
fun colorPreferenceCategory(category: MaterialPreferenceCategory) {
|
||||
withElementColor(category) { color ->
|
||||
category.setTitleColor(color)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorSwitchPreference(preference: MaterialSwitchPreference) {
|
||||
val children = preference.children
|
||||
val switch = children.find { it is SwitchCompat }
|
||||
if (switch != null) {
|
||||
val switchCompat = (switch as SwitchCompat)
|
||||
colorSwitchCompat(switchCompat)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorSwitchCompat(switchCompat: SwitchCompat) {
|
||||
withElementColor(switchCompat) { color ->
|
||||
|
||||
val context = switchCompat.context
|
||||
|
||||
val thumbUncheckedColor = ResourcesCompat.getColor(
|
||||
context.resources,
|
||||
R.color.switch_thumb_color_unchecked,
|
||||
context.theme
|
||||
)
|
||||
val trackUncheckedColor = ResourcesCompat.getColor(
|
||||
context.resources,
|
||||
R.color.switch_track_color_unchecked,
|
||||
context.theme
|
||||
)
|
||||
|
||||
val trackColor =
|
||||
Color.argb(SWITCHCOMPAT_TRACK_ALPHA, Color.red(color), Color.green(color), Color.blue(color))
|
||||
switchCompat.thumbTintList = ColorStateList(
|
||||
arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()),
|
||||
intArrayOf(color, thumbUncheckedColor)
|
||||
)
|
||||
|
||||
switchCompat.trackTintList = ColorStateList(
|
||||
arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()),
|
||||
intArrayOf(trackColor, trackUncheckedColor)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorDrawable(context: Context, drawable: Drawable) {
|
||||
val color = getElementColor(context)
|
||||
drawable.setTint(color)
|
||||
}
|
||||
|
||||
fun themeCheckbox(checkbox: CheckBox) {
|
||||
withElementColor(checkbox) { color ->
|
||||
checkbox.buttonTintList = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_checked),
|
||||
intArrayOf(android.R.attr.state_checked)
|
||||
),
|
||||
intArrayOf(Color.GRAY, color)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun themeRadioButton(radioButton: RadioButton) {
|
||||
withElementColor(radioButton) { color ->
|
||||
radioButton.buttonTintList = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_checked),
|
||||
intArrayOf(android.R.attr.state_checked)
|
||||
),
|
||||
intArrayOf(Color.GRAY, color)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun themeSwipeRefreshLayout(swipeRefreshLayout: SwipeRefreshLayout) {
|
||||
withElementColor(swipeRefreshLayout) { color ->
|
||||
swipeRefreshLayout.setColorSchemeColors(color)
|
||||
swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorProgressBar(progressIndicator: LinearProgressIndicator) {
|
||||
withElementColor(progressIndicator) { color ->
|
||||
progressIndicator.setIndicatorColor(progressColor(progressIndicator.context, color))
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
// TODO check API-level compatibility
|
||||
// editText.background.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
|
||||
editText.backgroundTintList = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_focused),
|
||||
intArrayOf(android.R.attr.state_focused)
|
||||
),
|
||||
intArrayOf(
|
||||
Color.GRAY,
|
||||
color
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorTextInputLayout(textInputLayout: TextInputLayout) {
|
||||
withElementColor(textInputLayout) { color ->
|
||||
val errorColor = Color.GRAY
|
||||
|
||||
val errorColorStateList = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_focused),
|
||||
intArrayOf(android.R.attr.state_focused)
|
||||
),
|
||||
intArrayOf(
|
||||
errorColor,
|
||||
errorColor
|
||||
)
|
||||
)
|
||||
val coloredColorStateList = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_focused),
|
||||
intArrayOf(android.R.attr.state_focused)
|
||||
),
|
||||
intArrayOf(
|
||||
Color.GRAY,
|
||||
color
|
||||
)
|
||||
)
|
||||
|
||||
textInputLayout.setBoxStrokeColorStateList(coloredColorStateList)
|
||||
textInputLayout.setErrorIconTintList(errorColorStateList)
|
||||
textInputLayout.setErrorTextColor(errorColorStateList)
|
||||
textInputLayout.boxStrokeErrorColor = errorColorStateList
|
||||
textInputLayout.defaultHintTextColor = coloredColorStateList
|
||||
}
|
||||
}
|
||||
|
||||
fun colorTabLayout(tabLayout: TabLayout) {
|
||||
withElementColor(tabLayout) { color ->
|
||||
tabLayout.setSelectedTabIndicatorColor(color)
|
||||
}
|
||||
}
|
||||
|
||||
fun getPlaceholderImage(context: Context, mimetype: String?): Drawable? {
|
||||
val drawableResourceId = DrawableUtils.getDrawableResourceIdForMimeType(mimetype)
|
||||
val drawable = AppCompatResources.getDrawable(
|
||||
context,
|
||||
drawableResourceId
|
||||
)
|
||||
if (drawable != null && THEMEABLE_PLACEHOLDER_IDS.contains(drawableResourceId)) {
|
||||
colorDrawable(context, drawable)
|
||||
}
|
||||
return drawable
|
||||
}
|
||||
|
||||
fun colorChipBackground(chip: Chip) {
|
||||
withElementColor(chip) { color ->
|
||||
chip.chipBackgroundColor = ColorStateList.valueOf(color)
|
||||
chip.setTextColor(theme.colorText)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorChipOutlined(chip: Chip, strokeWidth: Float) {
|
||||
withElementColor(chip) { color ->
|
||||
chip.chipBackgroundColor = ColorStateList.valueOf(Color.TRANSPARENT)
|
||||
chip.chipStrokeWidth = strokeWidth
|
||||
chip.chipStrokeColor = ColorStateList.valueOf(color)
|
||||
chip.setTextColor(color)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -28,23 +28,28 @@ import com.nextcloud.talk.data.user.model.User
|
|||
import com.nextcloud.talk.models.ExternalSignalingServer
|
||||
import com.nextcloud.talk.models.json.capabilities.Capabilities
|
||||
import com.nextcloud.talk.models.json.push.PushConfigurationState
|
||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
class UserManager internal constructor(private val userRepository: UsersRepository) : CurrentUserProviderNew {
|
||||
class UserManager internal constructor(private val userRepository: UsersRepository) {
|
||||
val users: Single<List<User>>
|
||||
get() = userRepository.getUsers()
|
||||
|
||||
val usersScheduledForDeletion: Single<List<User>>
|
||||
get() = userRepository.getUsersScheduledForDeletion()
|
||||
|
||||
override val currentUser: Maybe<User>
|
||||
val currentUser: Maybe<User>
|
||||
get() {
|
||||
return userRepository.getActiveUser()
|
||||
}
|
||||
|
||||
val currentUserObservable: Observable<User>
|
||||
get() {
|
||||
return userRepository.getActiveUserObservable()
|
||||
}
|
||||
|
||||
fun deleteUser(internalId: Long): Int {
|
||||
return userRepository.deleteUser(userRepository.getUserWithId(internalId).blockingGet())
|
||||
}
|
||||
|
|
|
@ -148,33 +148,23 @@ object DrawableUtils {
|
|||
drawableMap["unknown"] = R.drawable.ic_mimetype_file
|
||||
drawableMap["application/pdf"] = R.drawable.ic_mimetype_application_pdf
|
||||
|
||||
if (localMimetype.isNullOrEmpty()) {
|
||||
return drawableMap["unknown"]!!
|
||||
}
|
||||
|
||||
if ("DIR" == localMimetype) {
|
||||
return if (localMimetype.isNullOrEmpty()) {
|
||||
drawableMap["unknown"]!!
|
||||
} else if ("DIR" == localMimetype) {
|
||||
localMimetype = FOLDER
|
||||
return drawableMap[localMimetype]!!
|
||||
}
|
||||
|
||||
if (drawableMap.containsKey(localMimetype)) {
|
||||
return drawableMap[localMimetype]!!
|
||||
}
|
||||
|
||||
if (localMimetype.startsWith(IMAGE_PREFIX)) {
|
||||
return R.drawable.ic_mimetype_image
|
||||
}
|
||||
|
||||
if (localMimetype.startsWith(VIDEO_PREFIX)) {
|
||||
return R.drawable.ic_mimetype_video
|
||||
}
|
||||
|
||||
if (localMimetype.startsWith(TEXT_PREFIX)) {
|
||||
return R.drawable.ic_mimetype_text
|
||||
}
|
||||
|
||||
return if (localMimetype.startsWith(AUDIO_PREFIX)) {
|
||||
drawableMap[localMimetype]!!
|
||||
} else if (drawableMap.containsKey(localMimetype)) {
|
||||
drawableMap[localMimetype]!!
|
||||
} else if (localMimetype.startsWith(IMAGE_PREFIX)) {
|
||||
R.drawable.ic_mimetype_image
|
||||
} else if (localMimetype.startsWith(VIDEO_PREFIX)) {
|
||||
R.drawable.ic_mimetype_video
|
||||
} else if (localMimetype.startsWith(TEXT_PREFIX)) {
|
||||
R.drawable.ic_mimetype_text
|
||||
} else if (localMimetype.startsWith(AUDIO_PREFIX)) {
|
||||
R.drawable.ic_mimetype_audio
|
||||
} else drawableMap["unknown"]!!
|
||||
} else {
|
||||
drawableMap["unknown"]!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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.utils.database.user
|
||||
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.disposables.Disposable
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Listens to changes in the database and provides the current user without needing to query the database everytime.
|
||||
*/
|
||||
class CurrentUserProviderImpl @Inject constructor(private val userManager: UserManager) : CurrentUserProviderNew {
|
||||
private var _currentUser: User? = null
|
||||
private var currentUserObserver: Disposable? = null
|
||||
|
||||
override val currentUser: Maybe<User>
|
||||
get() {
|
||||
if (_currentUser == null) {
|
||||
// immediately get a result synchronously
|
||||
_currentUser = userManager.currentUser.blockingGet()
|
||||
if (currentUserObserver == null) {
|
||||
// start observable for auto-updates
|
||||
currentUserObserver = userManager.currentUserObservable.subscribe { _currentUser = it }
|
||||
}
|
||||
}
|
||||
return _currentUser?.let { Maybe.just(it) } ?: Maybe.empty()
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@ import dagger.Provides
|
|||
abstract class UserModule {
|
||||
|
||||
@Binds
|
||||
abstract fun bindCurrentUserProviderNew(userManager: UserManager): CurrentUserProviderNew
|
||||
abstract fun bindCurrentUserProviderNew(currentUserProviderImpl: CurrentUserProviderImpl): CurrentUserProviderNew
|
||||
|
||||
companion object {
|
||||
@Provides
|
||||
|
|
81
app/src/main/java/com/nextcloud/talk/utils/ui/ColorUtil.kt
Normal file
81
app/src/main/java/com/nextcloud/talk/utils/ui/ColorUtil.kt
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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.utils.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import com.nextcloud.talk.R
|
||||
import javax.inject.Inject
|
||||
|
||||
class ColorUtil @Inject constructor(private val context: Context) {
|
||||
|
||||
@ColorInt
|
||||
fun getNullSafeColor(color: String?, @ColorInt fallbackColor: Int): Int {
|
||||
return color.parseColorOrFallback { fallbackColor }
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun getNullSafeColorWithFallbackRes(color: String?, @ColorRes fallbackColorRes: Int): Int {
|
||||
return color.parseColorOrFallback { ContextCompat.getColor(context, fallbackColorRes) }
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun getTextColor(colorText: String?, @ColorInt backgroundColor: Int): Int {
|
||||
return colorText.parseColorOrFallback { getForegroundColorForBackgroundColor(backgroundColor) }
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun getForegroundColorForBackgroundColor(@ColorInt color: Int): Int {
|
||||
val hsl = FloatArray(HSL_SIZE)
|
||||
ColorUtils.RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), hsl)
|
||||
|
||||
return if (hsl[INDEX_LIGHTNESS] < LIGHTNESS_DARK_THRESHOLD) {
|
||||
Color.WHITE
|
||||
} else {
|
||||
ContextCompat.getColor(context, R.color.grey_900)
|
||||
}
|
||||
}
|
||||
|
||||
fun setLightness(@ColorInt color: Int, lightness: Float): Int {
|
||||
require(lightness in 0.0..1.0) { "Lightness must be between 0 and 1" }
|
||||
val hsl = FloatArray(HSL_SIZE)
|
||||
ColorUtils.RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), hsl)
|
||||
|
||||
hsl[INDEX_LIGHTNESS] = lightness
|
||||
|
||||
return ColorUtils.HSLToColor(hsl)
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
private fun String?.parseColorOrFallback(fallback: () -> Int): Int {
|
||||
return this?.let { Color.parseColor(this) } ?: fallback()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val HSL_SIZE: Int = 3
|
||||
private const val INDEX_LIGHTNESS: Int = 2
|
||||
private const val LIGHTNESS_DARK_THRESHOLD: Float = 0.6f
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* 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.utils.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
|
||||
object PlatformThemeUtil {
|
||||
fun isDarkMode(context: Context): Boolean =
|
||||
when (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
|
||||
Configuration.UI_MODE_NIGHT_YES -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
|
@ -222,6 +222,7 @@
|
|||
android:theme="@style/Button.Primary"
|
||||
android:tint="@android:color/white"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
app:backgroundTint="@color/colorPrimary"
|
||||
app:cornerRadius="48dp"
|
||||
app:elevation="0dp"
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:apc="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:background="@color/white"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
@ -76,6 +77,7 @@
|
|||
android:layout_width="@dimen/avatar_size_big"
|
||||
android:layout_height="@dimen/avatar_size_big"
|
||||
android:layout_centerHorizontal="true"
|
||||
tools:background="@color/hwSecurityRed"
|
||||
apc:roundAsCircle="true" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -115,11 +115,11 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="16dp"
|
||||
android:backgroundTint="@color/colorPrimary"
|
||||
android:contentDescription="@string/nc_new_conversation"
|
||||
app:borderWidth="0dp"
|
||||
app:srcCompat="@drawable/ic_add_white_24px"
|
||||
app:tint="@color/white" />
|
||||
app:tint="@color/white"
|
||||
app:backgroundTint="@color/colorPrimary"/>
|
||||
|
||||
<com.nextcloud.ui.popupbubble.PopupBubble
|
||||
android:id="@+id/newMentionPopupBubble"
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
android:inputType="textUri"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/colorPrimary" />
|
||||
android:textColor="@color/high_emphasis_text" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
@ -78,7 +78,7 @@
|
|||
android:contentDescription="@string/nc_add_emojis"
|
||||
android:src="@drawable/ic_insert_emoticon_black_24dp"
|
||||
android:visibility="gone"
|
||||
app:tint="@color/emoji_icons"
|
||||
app:tint="@color/medium_emphasis_text"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
<RelativeLayout
|
||||
android:id="@+id/avatarContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="@dimen/standard_padding">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:id="@+id/avatar_image"
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:fresco="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:background="@color/white"
|
||||
android:id="@+id/settings_screen"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
@ -43,6 +44,7 @@
|
|||
android:id="@+id/message_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:text="This is a test message"
|
||||
android:gravity="center" />
|
||||
</com.yarolegovich.mp.MaterialPreferenceCategory>
|
||||
|
||||
|
@ -105,10 +107,10 @@
|
|||
android:id="@+id/server_age_warning_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_toEndOf="@id/server_age_warning_icon"
|
||||
android:paddingStart="@dimen/standard_padding"
|
||||
android:paddingEnd="0dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/nc_darkRed"
|
||||
tools:text="@string/nc_settings_server_almost_eol" />
|
||||
|
@ -142,6 +144,7 @@
|
|||
<com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/settings_appearance_category"
|
||||
android:animateLayoutChanges="true"
|
||||
apc:cardBackgroundColor="@color/bg_default"
|
||||
apc:cardElevation="0dp"
|
||||
|
@ -186,6 +189,7 @@
|
|||
</com.yarolegovich.mp.MaterialPreferenceCategory>
|
||||
|
||||
<com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
android:id="@+id/settings_privacy_category"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
|
@ -249,6 +253,7 @@
|
|||
</com.yarolegovich.mp.MaterialPreferenceCategory>
|
||||
|
||||
<com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
android:id="@+id/settings_advanced_category"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
|
@ -323,6 +328,7 @@
|
|||
</com.yarolegovich.mp.MaterialPreferenceCategory>
|
||||
|
||||
<com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
android:id="@+id/settings_about_category"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
app:cardElevation="0dp">
|
||||
|
||||
<RelativeLayout
|
||||
tools:background="@color/white"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<androidx.constraintlayout.widget.ConstraintLayout 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"
|
||||
tools:background="@color/white"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
android:paddingTop="@dimen/dialog_padding_top_bottom">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/poll_question"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/dialog_padding"
|
||||
|
@ -73,6 +74,7 @@
|
|||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/poll_options"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/standard_padding"
|
||||
|
@ -102,6 +104,7 @@
|
|||
app:icon="@drawable/ic_add_grey600_24px" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/poll_settings"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/standard_margin"
|
||||
|
|
|
@ -77,8 +77,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/messageTime"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_alignSelf="center"
|
||||
android:contentDescription="@null" />
|
||||
android:contentDescription="@null"
|
||||
app:layout_alignSelf="center" />
|
||||
|
||||
<include
|
||||
android:id="@+id/reactions"
|
||||
|
|
|
@ -63,8 +63,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="viewStart"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/nc_outcoming_text_default"
|
||||
android:textStyle="bold"
|
||||
tools:text="This is the poll title?" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -83,8 +83,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/messageText"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_alignSelf="center"
|
||||
android:textColor="@color/nc_outcoming_text_default"
|
||||
app:layout_alignSelf="center"
|
||||
tools:text="10:35" />
|
||||
|
||||
<ImageView
|
||||
|
@ -93,9 +93,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/messageTime"
|
||||
android:layout_marginStart="8dp"
|
||||
android:contentDescription="@null"
|
||||
android:textColor="@color/nc_outcoming_text_default"
|
||||
app:layout_alignSelf="center"
|
||||
android:contentDescription="@null" />
|
||||
app:layout_alignSelf="center" />
|
||||
|
||||
<include
|
||||
android:id="@+id/reactions"
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
android:layout_height="wrap_content">
|
||||
|
||||
<com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
android:id="@+id/notification_settings_category"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Nextcloud Android client application
|
||||
|
||||
Copyright (C) 2018-2021 Andy Scherzinger
|
||||
Copyright (C) 2018-2022 Andy Scherzinger
|
||||
Copyright (C) 2018 Nextcloud
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
|
@ -22,8 +22,10 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/user_info_detail_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/iconized_single_line_item_layout_height"
|
||||
android:orientation="horizontal">
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/min_size_clickable_area"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/standard_padding">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
|
@ -36,34 +38,44 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@drawable/ic_phone" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/user_info_edit_text"
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/user_info_input_layout"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="@dimen/standard_double_margin"
|
||||
android:layout_marginEnd="@dimen/standard_margin"
|
||||
android:autofillHints="none"
|
||||
android:ellipsize="end"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:textSize="@dimen/two_line_primary_text_size"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/standard_margin"
|
||||
android:minHeight="@dimen/min_size_clickable_area"
|
||||
app:boxStrokeColor="@color/colorPrimary"
|
||||
app:errorTextAppearance="@style/ErrorAppearance"
|
||||
app:hintTextColor="@color/colorPrimary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/scope"
|
||||
app:layout_constraintStart_toEndOf="@id/icon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="LabelFor"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.nextcloud.talk.utils.EmojiTextInputEditText
|
||||
android:id="@+id/user_info_edit_text_edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="text"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="+49 123 456 789 12" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/scope"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:padding="12dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_width="@dimen/min_size_clickable_area"
|
||||
android:layout_height="@dimen/min_size_clickable_area"
|
||||
android:layout_marginStart="@dimen/standard_quarter_margin"
|
||||
android:layout_marginEnd="@dimen/standard_quarter_margin"
|
||||
android:contentDescription="@string/scope_toggle"
|
||||
android:padding="@dimen/scope_padding"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/user_info_edit_text"
|
||||
app:layout_constraintStart_toEndOf="@id/user_info_input_layout"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@drawable/ic_link" />
|
||||
|
||||
|
|
|
@ -76,4 +76,8 @@
|
|||
|
||||
<color name="dialog_background">#353535</color>
|
||||
<color name="vote_dialog_background">#424242</color>
|
||||
|
||||
<color name="switch_thumb_color_unchecked">#cbcbcb</color>
|
||||
<color name="switch_track_color_unchecked">#5a5a5a</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -63,15 +63,13 @@
|
|||
<color name="nc_darkGreen">#006400</color>
|
||||
<color name="controller_chat_separator">#E8E8E8</color>
|
||||
<color name="grey_600">#757575</color>
|
||||
<color name="grey_900">#212121</color>
|
||||
<color name="nc_grey">#D5D5D5</color>
|
||||
<color name="controller_call_incomingCallTextView">#E9FFFFFF</color>
|
||||
<color name="grey950">#111111</color>
|
||||
<color name="textColorMaxContrast">#767676</color>
|
||||
<color name="colorBackgroundDarker">#DBDBDB</color>
|
||||
|
||||
<!-- Emoji list in chat window -->
|
||||
<color name="emoji_icons">#61000000</color>
|
||||
|
||||
<color name="fg_default">#666666</color>
|
||||
<color name="fg_inverse">#FFFFFF</color>
|
||||
|
||||
|
@ -82,8 +80,6 @@
|
|||
|
||||
<color name="bg_message_list_incoming_bubble">#EFEFEF</color>
|
||||
<color name="bg_message_list_incoming_bubble_deleted">#66EFEFEF</color>
|
||||
<color name="bg_message_list_outcoming_bubble">@color/colorPrimary</color>
|
||||
<color name="bg_message_list_outcoming_bubble_deleted">#800082C9</color>
|
||||
|
||||
<color name="bg_bottom_sheet">#FFFFFF</color>
|
||||
<color name="bg_call_screen_dialog">#121212</color>
|
||||
|
@ -111,4 +107,7 @@
|
|||
<color name="dialog_background">#FFFFFF</color>
|
||||
<color name="vote_dialog_background">#FFFFFF</color>
|
||||
|
||||
<color name="switch_thumb_color_unchecked">#ececec</color>
|
||||
<color name="switch_track_color_unchecked">#b2b2b2</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
<dimen name="activity_row_layout_height">48dp</dimen>
|
||||
<dimen name="reaction_bottom_sheet_layout_size">40dp</dimen>
|
||||
<dimen name="standard_eighth_margin">2dp</dimen>
|
||||
<dimen name="scope_padding">12dp</dimen>
|
||||
|
||||
<dimen name="default_checkbox_dialog_start_margin">18dp</dimen>
|
||||
|
||||
|
|
Loading…
Reference in a new issue