group conversation by tags
This commit is contained in:
parent
c4c5aaa6d6
commit
5f16051cf7
|
@ -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<Conversation> conversations = new ArrayList<>();
|
||||
private final List<ListItem.Tag> tags = new ArrayList<>();
|
||||
|
||||
private final PendingItem<Conversation> swipedConversation = new PendingItem<>();
|
||||
private final PendingItem<ScrollState> 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<ListItem.Tag> tags = new ArrayList<>();
|
||||
final List<Account> 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<Map.Entry<ListItem.Tag, Integer>> 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();
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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<ListItem> 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));
|
||||
|
|
|
@ -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,25 +49,176 @@ import eu.siacs.conversations.xmpp.Jid;
|
|||
import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession;
|
||||
|
||||
public class ConversationAdapter
|
||||
extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> {
|
||||
extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
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<Conversation> conversations;
|
||||
private OnConversationClickListener listener;
|
||||
|
||||
private boolean allowRelativeTimestamps = true;
|
||||
private boolean allowRelativeTimestamps;
|
||||
|
||||
public ConversationAdapter(XmppActivity activity, List<Conversation> conversations) {
|
||||
private ListItem.Tag generalTag;
|
||||
|
||||
private List<Object> items = new ArrayList<>();
|
||||
private Map<Account, Set<ListItem.Tag>> expandedItems = new HashMap<>();
|
||||
|
||||
private Map<Account, Map<ListItem.Tag, Set<Conversation>>> groupedItems = new HashMap<>();
|
||||
|
||||
private boolean groupingEnabled = false;
|
||||
|
||||
SharedPreferences prefs;
|
||||
|
||||
public ConversationAdapter(XmppActivity activity, List<Conversation> conversations, List<ListItem.Tag> tags) {
|
||||
this.activity = activity;
|
||||
this.conversations = conversations;
|
||||
|
||||
/*prefs = activity.getSharedPreferences("expansionPrefs", Context.MODE_PRIVATE);
|
||||
Set<String> expandedAccounts = prefs.getStringSet("expandedAccounts", Collections.emptySet());
|
||||
for (String id : expandedAccounts) {
|
||||
Set<String> 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<Account> 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<ListItem.Tag> expandedTags = expandedItems.getOrDefault(account, Collections.emptySet());
|
||||
|
||||
Map<ListItem.Tag, Set<Conversation>> groupedItems = new HashMap<>();
|
||||
|
||||
Map<Conversation, List<ListItem.Tag>> tagsToConversationCache = new HashMap<>();
|
||||
|
||||
for (int i = 0; i < conversations.size(); i++) {
|
||||
Conversation item = conversations.get(i);
|
||||
|
||||
if (item.getAccount() != account) continue;
|
||||
|
||||
List<ListItem.Tag> 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<Conversation> 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<ListItem.Tag> itemTags = tagsToConversationCache.get(item);
|
||||
|
||||
if (itemTags.contains(tag)) {
|
||||
if (accountExpanded && expandedTags.contains(tag)) {
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
Set<Conversation> 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) {
|
||||
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()),
|
||||
|
@ -59,10 +226,74 @@ public class ConversationAdapter
|
|||
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<ListItem.Tag> 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;
|
||||
}
|
||||
|
@ -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<ListItem.Tag, Set<Conversation>> childTags = groupedItems.get(account);
|
||||
if (childTags == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Set<Conversation> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
9
src/main/res/drawable/ic_expand_more.xml
Normal file
9
src/main/res/drawable/ic_expand_more.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/black"
|
||||
android:pathData="M480,615L240,375L296,319L480,503L664,319L720,375L480,615Z"/>
|
||||
</vector>
|
9
src/main/res/drawable/ic_expand_more_white.xml
Normal file
9
src/main/res/drawable/ic_expand_more_white.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,615L240,375L296,319L480,503L664,319L720,375L480,615Z"/>
|
||||
</vector>
|
|
@ -1,46 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Simple Gallery</string>
|
||||
<string name="app_launcher_name">Gallery</string>
|
||||
|
||||
<string name="ok">OK</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="custom">Custom</string>
|
||||
|
||||
<string name="resize_and_save">Resize selection and save</string>
|
||||
<string name="width">Width</string>
|
||||
<string name="height">Height</string>
|
||||
<string name="keep_aspect_ratio">Keep aspect ratio</string>
|
||||
<string name="invalid_values">Please enter a valid resolution</string>
|
||||
|
||||
<string name="editor">Editor</string>
|
||||
<string name="basic_editor">Basic Editor</string>
|
||||
<string name="rotate">Rotate</string>
|
||||
<string name="invalid_image_path">Invalid image path</string>
|
||||
<string name="image_editing_failed">Image editing failed</string>
|
||||
<string name="unknown_file_location">Unknown file location</string>
|
||||
<string name="transform">Transform</string>
|
||||
<string name="crop">Crop</string>
|
||||
<string name="draw">Draw</string>
|
||||
<string name="flip_horizontally">Flip horizontally</string>
|
||||
<string name="flip_vertically">Flip vertically</string>
|
||||
<string name="free_aspect_ratio">Free</string>
|
||||
<string name="other_aspect_ratio">Other</string>
|
||||
|
||||
<string name="thumbnails">Thumbnails</string>
|
||||
<string name="saving">saving</string>
|
||||
<string name="out_of_memory_error">out_of_memory_error</string>
|
||||
<string name="none">none</string>
|
||||
<string name="file_saved">file_saved</string>
|
||||
<string name="error">error</string>
|
||||
<string name="simple_commons">simple_commons</string>
|
||||
<string name="value_copied_to_clipboard_show">value_copied_to_clipboard_show</string>
|
||||
<string name="default_color">default_color</string>
|
||||
<string name="unknown_error_occurred">unknown_error_occurred</string>
|
||||
<string name="undo">undo</string>
|
||||
<string name="change_color">change_color</string>
|
||||
<string name="resize">resize</string>
|
||||
<string name="filter">filter</string>
|
||||
<string name="could_not_create_file">could_not_create_file</string>
|
||||
|
||||
</resources>
|
|
@ -3,14 +3,22 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/arrow"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="?attr/icon_expand_more"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_gravity="center_vertical" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="8dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:layout_marginStart="40dp"
|
||||
android:layout_marginEnd="16dp" />
|
||||
|
||||
|
|
|
@ -3,12 +3,21 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/arrow"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="?attr/icon_expand_more"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_gravity="center_vertical" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="8dp"
|
||||
android:textAllCaps="true"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:layout_marginStart="40dp"
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
<attr name="media_preview_unknown" format="reference" />
|
||||
|
||||
|
||||
<attr name="icon_expand_more" format="reference" />
|
||||
<attr name="icon_add_group" format="reference" />
|
||||
<attr name="icon_add_person" format="reference" />
|
||||
<attr name="icon_cancel" format="reference" />
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
<string name="quick_action">recent</string>
|
||||
<bool name="show_dynamic_tags">false</bool>
|
||||
<bool name="group_by_tags">false</bool>
|
||||
<bool name="conversations_group_by_tags">false</bool>
|
||||
<bool name="btbv">true</bool>
|
||||
<integer name="automatic_message_deletion">0</integer>
|
||||
<bool name="dont_trust_system_cas">false</bool>
|
||||
|
|
|
@ -361,6 +361,8 @@
|
|||
<string name="pref_show_dynamic_tags_summary">Allow organizing with tags</string>
|
||||
<string name="pref_group_by_tags">Group by Dynamic Tags</string>
|
||||
<string name="pref_group_by_tags_summary">Allow to grouping contacts by their tags</string>
|
||||
<string name="pref_group_conversations_by_tags">Group Conversations by Dynamic Tags</string>
|
||||
<string name="pref_group_conversations_by_tags_summary">Allow to grouping conversations list by their tags</string>
|
||||
<string name="enable_notifications">Enable notifications</string>
|
||||
<string name="no_conference_server_found">No group chat server found</string>
|
||||
<string name="conference_creation_failed">Could not create group chat</string>
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
<item name="media_preview_backup" type="reference">@drawable/ic_backup_black_48dp</item>
|
||||
<item name="media_preview_unknown" type="reference">@drawable/ic_help_black_48dp</item>
|
||||
|
||||
<item name="icon_expand_more" type="reference">@drawable/ic_expand_more</item>
|
||||
<item name="icon_add_group" type="reference">@drawable/ic_group_add_white_24dp</item>
|
||||
<item name="icon_add_person" type="reference">@drawable/ic_person_add_white_24dp</item>
|
||||
<item name="icon_cancel" type="reference">@drawable/ic_cancel_black_24dp</item>
|
||||
|
@ -230,6 +231,7 @@
|
|||
<item name="ic_attach_location" type="reference">@drawable/ic_attach_location_white</item>
|
||||
<item name="ic_attach_photo" type="reference">@drawable/ic_attach_photo_white</item>
|
||||
<item name="ic_attach_record" type="reference">@drawable/ic_attach_record_white</item>
|
||||
<item name="icon_expand_more" type="reference">@drawable/ic_expand_more_white</item>
|
||||
|
||||
<item name="message_bubble_received_monochrome" type="reference">
|
||||
@drawable/message_bubble_received_grey
|
||||
|
|
|
@ -181,6 +181,11 @@
|
|||
android:key="groupByTags"
|
||||
android:summary="@string/pref_group_by_tags_summary"
|
||||
android:title="@string/pref_group_by_tags" />
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="@bool/conversations_group_by_tags"
|
||||
android:key="conversationsGroupByTags"
|
||||
android:summary="@string/pref_group_conversations_by_tags_summary"
|
||||
android:title="@string/pref_group_conversations_by_tags" />
|
||||
<ListPreference
|
||||
android:defaultValue="@string/theme"
|
||||
android:entries="@array/themes"
|
||||
|
|
Loading…
Reference in a new issue