From 5f16051cf727c57329e60c37565c5b95a6d5b703 Mon Sep 17 00:00:00 2001 From: kosyak Date: Mon, 1 Jan 2024 23:36:07 +0100 Subject: [PATCH] group conversation by tags --- .../ui/ConversationsOverviewFragment.java | 63 +++- .../conversations/ui/ShareWithActivity.java | 2 +- .../ui/StartConversationActivity.java | 11 +- .../ui/adapter/ConversationAdapter.java | 335 +++++++++++++++++- src/main/res/drawable/ic_expand_more.xml | 9 + .../res/drawable/ic_expand_more_white.xml | 9 + src/main/res/drawable/strings.xml | 46 --- src/main/res/layout/contact_account.xml | 12 +- src/main/res/layout/contact_group.xml | 9 + src/main/res/values/attrs.xml | 1 + src/main/res/values/defaults.xml | 1 + src/main/res/values/strings.xml | 2 + src/main/res/values/themes.xml | 2 + src/main/res/xml/preferences.xml | 5 + 14 files changed, 435 insertions(+), 72 deletions(-) create mode 100644 src/main/res/drawable/ic_expand_more.xml create mode 100644 src/main/res/drawable/ic_expand_more_white.xml delete mode 100644 src/main/res/drawable/strings.xml diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java index 80df3c3dc..2527167aa 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java @@ -57,16 +57,23 @@ import com.google.common.base.Optional; import com.google.common.collect.Collections2; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.databinding.FragmentConversationsOverviewBinding; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversational; +import eu.siacs.conversations.entities.ListItem; +import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.ui.adapter.ConversationAdapter; import eu.siacs.conversations.ui.interfaces.OnConversationArchived; @@ -90,6 +97,8 @@ public class ConversationsOverviewFragment extends XmppFragment { private static final String STATE_SCROLL_POSITION = ConversationsOverviewFragment.class.getName()+".scroll_state"; private final List conversations = new ArrayList<>(); + private final List tags = new ArrayList<>(); + private final PendingItem swipedConversation = new PendingItem<>(); private final PendingItem pendingScrollState = new PendingItem<>(); private FragmentConversationsOverviewBinding binding; @@ -296,7 +305,7 @@ public class ConversationsOverviewFragment extends XmppFragment { this.binding = DataBindingUtil.inflate(inflater, R.layout.fragment_conversations_overview, container, false); this.binding.fab.setOnClickListener((view) -> StartConversationActivity.launch(getActivity())); - this.conversationsAdapter = new ConversationAdapter(this.activity, this.conversations); + this.conversationsAdapter = new ConversationAdapter(this.activity, this.conversations, this.tags); this.conversationsAdapter.setConversationClickListener((view, conversation) -> { if (activity instanceof OnConversationSelected) { ((OnConversationSelected) activity).onConversationSelected(conversation); @@ -487,6 +496,8 @@ public class ConversationsOverviewFragment extends XmppFragment { pendingActionHelper.execute(); } } + + refreshTags(); this.conversationsAdapter.notifyDataSetChanged(); ScrollState scrollState = pendingScrollState.pop(); if (scrollState != null) { @@ -494,6 +505,56 @@ public class ConversationsOverviewFragment extends XmppFragment { } } + private void refreshTags() { + this.conversationsAdapter.setGroupingEnabled(activity.xmppConnectionService.getPreferences().getBoolean("conversationsGroupByTags", false)); + + if (conversationsAdapter.isGroupingEnabled()) { + List tags = new ArrayList<>(); + final List accounts = activity.xmppConnectionService.getAccounts(); + for (final Account account : accounts) { + if (account.isEnabled()) { + for (Contact contact : account.getRoster().getContacts()) { + if (contact.showInContactList()) { + tags.addAll(contact.getTags(activity)); + } + } + + for (Bookmark bookmark : account.getBookmarks()) { + tags.addAll(bookmark.getTags(activity)); + } + } + } + + Comparator> sortTagsBy = Map.Entry.comparingByValue(Comparator.reverseOrder()); + sortTagsBy = sortTagsBy.thenComparing(entry -> entry.getKey().getName()); + + this.tags.clear(); + this.tags.addAll( + tags.stream() + .collect(Collectors.toMap((x) -> x, (t) -> 1, (c1, c2) -> c1 + c2)) + .entrySet().stream() + .sorted(sortTagsBy) + .map(e -> e.getKey()).collect(Collectors.toList()) + ); + + ListItem.Tag channelTag = null; + int channelTagIndex = 0; + + for (ListItem.Tag tag : this.tags) { + if (tag.getName().equals("Channel")) { + channelTag = tag; + break; + } + channelTagIndex++; + } + + if (channelTag != null) { + this.tags.remove(channelTagIndex); + this.tags.add(0, channelTag); + } + } + } + private void setScrollPosition(ScrollState scrollPosition) { if (scrollPosition != null) { LinearLayoutManager layoutManager = (LinearLayoutManager) binding.list.getLayoutManager(); diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java index 185a15e11..9f3a35c18 100644 --- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java @@ -95,7 +95,7 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer setTitle(getString(R.string.title_activity_sharewith)); RecyclerView mListView = findViewById(R.id.choose_conversation_list); - mAdapter = new ConversationAdapter(this, this.mConversations); + mAdapter = new ConversationAdapter(this, this.mConversations, new ArrayList<>()); mListView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); mListView.setAdapter(mAdapter); mAdapter.setConversationClickListener((view, conversation) -> share(conversation)); diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index 7465201da..82b6d9bb8 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -13,6 +13,7 @@ import android.content.res.Resources; import android.database.DataSetObserver; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -24,6 +25,7 @@ import android.text.method.LinkMovementMethod; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; +import android.util.TypedValue; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.KeyEvent; @@ -1308,6 +1310,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne FixedExpandableListView lv = new FixedExpandableListView(view.getContext()); lv.setId(android.R.id.list); lv.setDrawSelectorOnTop(false); + lv.setGroupIndicator(null); ListView oldList = view.findViewById(android.R.id.list); ViewGroup oldListParent = (ViewGroup) oldList.getParent(); @@ -1682,8 +1685,6 @@ public class StartConversationActivity extends XmppActivity implements XmppConne List group = groupedItems.computeIfAbsent(itemTag, tag -> new ArrayList<>()); group.add(item); - - android.util.Log.e("27fd add", group.size() + " " + itemTag.getName()); } } } @@ -1743,6 +1744,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne v = activity.getLayoutInflater().inflate(R.layout.contact_group, parent, false); + v.findViewById(R.id.arrow).setRotation(isExpanded ? 180 : 0); + TextView tv = v.findViewById(R.id.text); tv.setText(activity.getString(R.string.contact_tag_with_total, tag.getName(), getChildrenCount(groupPosition))); tv.setBackgroundColor(tag.getColor()); @@ -1751,8 +1754,10 @@ public class StartConversationActivity extends XmppActivity implements XmppConne v = activity.getLayoutInflater().inflate(R.layout.contact_account, parent, false); + v.findViewById(R.id.arrow).setRotation(isExpanded ? 180 : 0); + TextView tv = v.findViewById(R.id.text); - tv.setText(acc.getJid().toString()); + tv.setText(acc.getJid().asBareJid().toString()); if (acc.isOnlineAndConnected()) { tv.setBackgroundColor(StyledAttributes.getColor(activity, R.attr.TextColorOnline)); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index a874dc035..3deb49146 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -1,28 +1,44 @@ package eu.siacs.conversations.ui.adapter; +import android.content.Context; import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.database.DataSetObserver; import android.graphics.Typeface; import android.preference.PreferenceManager; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.databinding.DataBindingUtil; import androidx.recyclerview.widget.RecyclerView; import com.google.common.base.Optional; import com.google.common.base.Strings; +import org.checkerframework.checker.units.qual.C; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import eu.siacs.conversations.R; import eu.siacs.conversations.databinding.ConversationListRowBinding; +import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversational; +import eu.siacs.conversations.entities.ListItem; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.ui.ConversationFragment; +import eu.siacs.conversations.ui.StartConversationActivity; import eu.siacs.conversations.ui.XmppActivity; import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.StyledAttributes; @@ -33,36 +49,251 @@ import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession; public class ConversationAdapter - extends RecyclerView.Adapter { + extends RecyclerView.Adapter { + + private static final int VIEW_TYPE_ACCOUNT = 0; + private static final int VIEW_TYPE_TAG = 1; + private static final int VIEW_TYPE_CONVERSATION = 2; private final XmppActivity activity; private final List conversations; private OnConversationClickListener listener; - private boolean allowRelativeTimestamps = true; + private boolean allowRelativeTimestamps; - public ConversationAdapter(XmppActivity activity, List conversations) { + private ListItem.Tag generalTag; + + private List items = new ArrayList<>(); + private Map> expandedItems = new HashMap<>(); + + private Map>> groupedItems = new HashMap<>(); + + private boolean groupingEnabled = false; + + SharedPreferences prefs; + + public ConversationAdapter(XmppActivity activity, List conversations, List tags) { this.activity = activity; this.conversations = conversations; + /*prefs = activity.getSharedPreferences("expansionPrefs", Context.MODE_PRIVATE); + Set expandedAccounts = prefs.getStringSet("expandedAccounts", Collections.emptySet()); + for (String id : expandedAccounts) { + Set tags = prefs.getStringSet("expandedTags" + id, Collections.emptySet()); + Account account = activity.xmppConnectionService.findAccountByUuid(id); + + }*/ + + final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(activity); allowRelativeTimestamps = !p.getBoolean("always_full_timestamps", activity.getResources().getBoolean(R.bool.always_full_timestamps)); + + String generalTagName = activity.getString(R.string.contact_tag_general); + generalTag = new ListItem.Tag(generalTagName, UIHelper.getColorForName(generalTagName, true)); + + registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { + @Override + public void onChanged() { + if (groupingEnabled) { + items.clear(); + groupedItems.clear(); + + List accounts = activity.xmppConnectionService.getAccounts(); + + for (Account account : accounts) { + if (accounts.size() > 1) { + items.add(account); + } + + boolean accountExpanded = accounts.size() == 1 || expandedItems.containsKey(account); + + boolean generalTagAdded = false; + int initialPosition = items.size(); + + Set expandedTags = expandedItems.getOrDefault(account, Collections.emptySet()); + + Map> groupedItems = new HashMap<>(); + + Map> tagsToConversationCache = new HashMap<>(); + + for (int i = 0; i < conversations.size(); i++) { + Conversation item = conversations.get(i); + + if (item.getAccount() != account) continue; + + List itemTags = item.getContact().getTags(activity); + + if (item.getBookmark() != null) { + itemTags.addAll(item.getBookmark().getTags(activity)); + } + + tagsToConversationCache.put(item, itemTags); + + if (itemTags.size() == 0 || (itemTags.size() == 1 && UIHelper.isStatusTag(activity, itemTags.get(0)))) { + if (accountExpanded && !generalTagAdded) { + items.add(initialPosition, generalTag); + generalTagAdded = true; + } + + if (accountExpanded && expandedTags.contains(generalTag)) { + items.add(item); + } + + Set group = groupedItems.computeIfAbsent(generalTag, t -> new HashSet<>()); + group.add(item); + } + } + + for (ListItem.Tag tag : tags) { + if (UIHelper.isStatusTag(activity, tag)) { + continue; + } + + if (accountExpanded) { + items.add(tag); + } + + for (int i = 0; i < conversations.size(); i++) { + Conversation item = conversations.get(i); + + if (item.getAccount() != account) continue; + + List itemTags = tagsToConversationCache.get(item); + + if (itemTags.contains(tag)) { + if (accountExpanded && expandedTags.contains(tag)) { + items.add(item); + } + + Set group = groupedItems.computeIfAbsent(tag, t -> new HashSet<>()); + + group.add(item); + } + } + + if (accountExpanded && groupedItems.get(tag) == null) { + items.remove(items.size() - 1); + } + } + + ConversationAdapter.this.groupedItems.put(account, groupedItems); + } + } + } + }); + } + + public boolean isGroupingEnabled() { + return groupingEnabled; + } + + public void setGroupingEnabled(boolean groupingEnabled) { + if (groupingEnabled != this.groupingEnabled) { + this.groupingEnabled = groupingEnabled; + notifyDataSetChanged(); + } + } + + @Override + public int getItemViewType(int position) { + if (!groupingEnabled) { + return VIEW_TYPE_CONVERSATION; + } else { + Object item = items.get(position); + + if (item instanceof Account) { + return VIEW_TYPE_ACCOUNT; + } else if (item instanceof ListItem.Tag) { + return VIEW_TYPE_TAG; + } else { + return VIEW_TYPE_CONVERSATION; + } + } } @NonNull @Override - public ConversationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new ConversationViewHolder( - DataBindingUtil.inflate( - LayoutInflater.from(parent.getContext()), - R.layout.conversation_list_row, - parent, - false)); + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_ACCOUNT) { + return new AccountViewHolder(parent); + } else if (viewType == VIEW_TYPE_TAG) { + return new TagViewHolder(parent); + } else { + return new ConversationViewHolder( + DataBindingUtil.inflate( + LayoutInflater.from(parent.getContext()), + R.layout.conversation_list_row, + parent, + false)); + } } @Override - public void onBindViewHolder(@NonNull ConversationViewHolder viewHolder, int position) { - Conversation conversation = conversations.get(position); + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { + if (groupingEnabled) { + if (viewHolder instanceof ConversationViewHolder) { + bindConversation((ConversationViewHolder) viewHolder, (Conversation) items.get(position)); + } else if (viewHolder instanceof TagViewHolder) { + bindTag((TagViewHolder) viewHolder, (ListItem.Tag) items.get(position), position); + } else { + bindAccount((AccountViewHolder) viewHolder, (Account) items.get(position)); + } + } else { + bindConversation((ConversationViewHolder) viewHolder, (Conversation) conversations.get(position)); + } + } + + @Override + public int getItemCount() { + if (groupingEnabled) { + return items.size(); + } else { + return conversations.size(); + } + } + + private void bindAccount(AccountViewHolder viewHolder, Account account) { + viewHolder.text.setText(activity.getString(R.string.contact_tag_with_total, account.getJid().asBareJid().toString(), getChildCount(account, null))); + + if (account.isOnlineAndConnected()) { + viewHolder.itemView.setBackgroundColor(StyledAttributes.getColor(activity, R.attr.TextColorOnline)); + } else { + viewHolder.itemView.setBackgroundColor(StyledAttributes.getColor(activity, android.R.attr.textColorSecondary)); + } + + viewHolder.arrow.setRotation(expandedItems.containsKey(account) ? 180 : 0); + + viewHolder.itemView.setOnClickListener(v -> { + if (expandedItems.containsKey(account)) { + expandedItems.remove(account); + } else { + expandedItems.put(account, new HashSet<>()); + } + + notifyDataSetChanged(); + }); + } + + private void bindTag(TagViewHolder viewHolder, ListItem.Tag tag, int position) { + Account account = findAccountForTag(position); + viewHolder.text.setText(activity.getString(R.string.contact_tag_with_total, tag.getName(), getChildCount(account, tag))); + viewHolder.text.setBackgroundColor(tag.getColor()); + + viewHolder.arrow.setRotation(expandedItems.computeIfAbsent(account, a -> new HashSet<>()).contains(tag) ? 180 : 0); + + viewHolder.itemView.setOnClickListener(v -> { + Set expandedTags = expandedItems.computeIfAbsent(account, a -> new HashSet<>()); + if (expandedTags.contains(tag)) { + expandedTags.remove(tag); + } else { + expandedTags.add(tag); + } + + notifyDataSetChanged(); + }); + } + + private void bindConversation(ConversationViewHolder viewHolder, Conversation conversation) { if (conversation == null) { return; } @@ -120,8 +351,8 @@ public class ConversationAdapter final boolean showPreviewText; if (fileAvailable && (message.isFileOrImage() - || message.treatAsDownloadable() - || message.isGeoUri())) { + || message.treatAsDownloadable() + || message.isGeoUri())) { final int imageResource; if (message.isGeoUri()) { imageResource = @@ -299,11 +530,6 @@ public class ConversationAdapter viewHolder.itemView.setOnClickListener(v -> listener.onConversationClick(v, conversation)); } - @Override - public int getItemCount() { - return conversations.size(); - } - public void setConversationClickListener(OnConversationClickListener listener) { this.listener = listener; } @@ -318,6 +544,55 @@ public class ConversationAdapter notifyItemRemoved(position); } + @Nullable + private Account findAccountForTag(int position) { + Account account = null; + + if (activity.xmppConnectionService.getAccounts().size() == 1) { + return activity.xmppConnectionService.getAccounts().get(0); + } + + for (int i = position; i >= 0; i--) { + Object prev = items.get(i); + if (prev instanceof Account) { + account = (Account) prev; + break; + } + } + + return account; + } + + private int getChildCount(Account account, @Nullable ListItem.Tag tag) { + if (tag == null) { + int res = 0; + + for (Conversation c : conversations) { + if (c.getAccount() == account) { + res++; + } + } + + return res; + } else { + if (account == null) { + return 0; + } + + Map> childTags = groupedItems.get(account); + if (childTags == null) { + return 0; + } + + Set childConversations = childTags.get(tag); + if (childConversations == null) { + return 0; + } + + return childConversations.size(); + } + } + public interface OnConversationClickListener { void onConversationClick(View view, Conversation conversation); } @@ -331,4 +606,26 @@ public class ConversationAdapter binding.getRoot().setLongClickable(true); } } + + static class AccountViewHolder extends RecyclerView.ViewHolder { + private TextView text; + private View arrow; + + private AccountViewHolder(ViewGroup parent) { + super(LayoutInflater.from(parent.getContext()).inflate(R.layout.contact_account, parent, false)); + text = itemView.findViewById(R.id.text); + arrow = itemView.findViewById(R.id.arrow); + } + } + + static class TagViewHolder extends RecyclerView.ViewHolder { + private TextView text; + private View arrow; + + private TagViewHolder(ViewGroup parent) { + super(LayoutInflater.from(parent.getContext()).inflate(R.layout.contact_group, parent, false)); + text = itemView.findViewById(R.id.text); + arrow = itemView.findViewById(R.id.arrow); + } + } } diff --git a/src/main/res/drawable/ic_expand_more.xml b/src/main/res/drawable/ic_expand_more.xml new file mode 100644 index 000000000..224158ce3 --- /dev/null +++ b/src/main/res/drawable/ic_expand_more.xml @@ -0,0 +1,9 @@ + + + diff --git a/src/main/res/drawable/ic_expand_more_white.xml b/src/main/res/drawable/ic_expand_more_white.xml new file mode 100644 index 000000000..2aa4dd23e --- /dev/null +++ b/src/main/res/drawable/ic_expand_more_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/src/main/res/drawable/strings.xml b/src/main/res/drawable/strings.xml deleted file mode 100644 index b8c5b90d2..000000000 --- a/src/main/res/drawable/strings.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - Simple Gallery - Gallery - - OK - Cancel - Custom - - Resize selection and save - Width - Height - Keep aspect ratio - Please enter a valid resolution - - Editor - Basic Editor - Rotate - Invalid image path - Image editing failed - Unknown file location - Transform - Crop - Draw - Flip horizontally - Flip vertically - Free - Other - - Thumbnails - saving - out_of_memory_error - none - file_saved - error - simple_commons - value_copied_to_clipboard_show - default_color - unknown_error_occurred - undo - change_color - resize - filter - could_not_create_file - - diff --git a/src/main/res/layout/contact_account.xml b/src/main/res/layout/contact_account.xml index 7d5943ea0..32ef24ad6 100644 --- a/src/main/res/layout/contact_account.xml +++ b/src/main/res/layout/contact_account.xml @@ -3,14 +3,22 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + + diff --git a/src/main/res/layout/contact_group.xml b/src/main/res/layout/contact_group.xml index 50b385358..272a6b044 100644 --- a/src/main/res/layout/contact_group.xml +++ b/src/main/res/layout/contact_group.xml @@ -3,12 +3,21 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + + + diff --git a/src/main/res/values/defaults.xml b/src/main/res/values/defaults.xml index 0047d32e7..55a8feb29 100644 --- a/src/main/res/values/defaults.xml +++ b/src/main/res/values/defaults.xml @@ -22,6 +22,7 @@ recent false false + false true 0 false diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index eeac29200..aef093a96 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -361,6 +361,8 @@ Allow organizing with tags Group by Dynamic Tags Allow to grouping contacts by their tags + Group Conversations by Dynamic Tags + Allow to grouping conversations list by their tags Enable notifications No group chat server found Could not create group chat diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml index f546caf68..b99a853a5 100644 --- a/src/main/res/values/themes.xml +++ b/src/main/res/values/themes.xml @@ -104,6 +104,7 @@ @drawable/ic_backup_black_48dp @drawable/ic_help_black_48dp + @drawable/ic_expand_more @drawable/ic_group_add_white_24dp @drawable/ic_person_add_white_24dp @drawable/ic_cancel_black_24dp @@ -230,6 +231,7 @@ @drawable/ic_attach_location_white @drawable/ic_attach_photo_white @drawable/ic_attach_record_white + @drawable/ic_expand_more_white @drawable/message_bubble_received_grey diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index 795636027..cff63c834 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -181,6 +181,11 @@ android:key="groupByTags" android:summary="@string/pref_group_by_tags_summary" android:title="@string/pref_group_by_tags" /> +