diff --git a/CHANGELOG.md b/CHANGELOG.md
index abc858022..cc57f3942 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
## Unreleased
+* Profiles focus on recognizing contacts
+* See the number of media directly in the profile, no need to tap around
* Clearer app lists by removing redundant "App" subtitle
* New button for quick access to the apps sent in current chat
* New icon for the in-chat apps button
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 2473b9b9c..0573786d7 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -288,6 +288,10 @@
android:theme="@style/TextSecure.LightNoActionBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
+
+
tabs = new ArrayList<>();
+ private Toolbar toolbar;
+ private TabLayout tabLayout;
+ private ViewPager viewPager;
+
+ @Override
+ protected void onPreCreate() {
+ dynamicTheme = new DynamicNoActionBarTheme();
+ super.onPreCreate();
+ dcContext = DcHelper.getContext(this);
+ }
+
+ @Override
+ protected void onCreate(Bundle bundle, boolean ready) {
+ tabs.add(new TabData(R.string.webxdc_apps, DcMsg.DC_MSG_WEBXDC, 0, 0));
+ tabs.add(new TabData(R.string.tab_gallery, DcMsg.DC_MSG_IMAGE, DcMsg.DC_MSG_GIF, DcMsg.DC_MSG_VIDEO));
+ tabs.add(new TabData(R.string.files, DcMsg.DC_MSG_FILE, 0, 0));
+ tabs.add(new TabData(R.string.audio, DcMsg.DC_MSG_AUDIO, DcMsg.DC_MSG_VOICE, 0));
+
+ setContentView(R.layout.all_media_activity);
+
+ initializeResources();
+
+ setSupportActionBar(this.toolbar);
+ ActionBar supportActionBar = getSupportActionBar();
+ if (supportActionBar != null) {
+ supportActionBar.setDisplayHomeAsUpEnabled(true);
+ supportActionBar.setTitle(isGlobalGallery() ? R.string.menu_all_media : R.string.apps_and_media);
+ }
+
+ this.tabLayout.setupWithViewPager(viewPager);
+ this.viewPager.setAdapter(new AllMediaPagerAdapter(getSupportFragmentManager()));
+ if (getIntent().getBooleanExtra(FORCE_GALLERY, false)) {
+ this.viewPager.setCurrentItem(1, false);
+ }
+
+ DcEventCenter eventCenter = DcHelper.getEventCenter(this);
+ eventCenter.addObserver(DcContext.DC_EVENT_CHAT_MODIFIED, this);
+ eventCenter.addObserver(DcContext.DC_EVENT_CONTACTS_CHANGED, this);
+ }
+
+ @Override
+ public void onDestroy() {
+ DcHelper.getEventCenter(this).removeObservers(this);
+ super.onDestroy();
+ }
+
+ @Override
+ public void handleEvent(@NonNull DcEvent event) {
+ }
+
+ private void initializeResources() {
+ chatId = getIntent().getIntExtra(CHAT_ID_EXTRA, 0);
+ contactId = getIntent().getIntExtra(CONTACT_ID_EXTRA, 0);
+
+ if (contactId!=0) {
+ chatId = dcContext.getChatIdByContactId(contactId);
+ }
+
+ if(chatId!=0) {
+ DcChat dcChat = dcContext.getChat(chatId);
+ if(!dcChat.isMultiUser()) {
+ final int[] members = dcContext.getChatContacts(chatId);
+ contactId = members.length>=1? members[0] : 0;
+ }
+ }
+
+ this.viewPager = ViewUtil.findById(this, R.id.pager);
+ this.toolbar = ViewUtil.findById(this, R.id.toolbar);
+ this.tabLayout = ViewUtil.findById(this, R.id.tab_layout);
+ }
+
+ private boolean isGlobalGallery() {
+ return contactId==0 && chatId==0;
+ }
+
+ private class AllMediaPagerAdapter extends FragmentStatePagerAdapter {
+ private Object currentFragment = null;
+
+ AllMediaPagerAdapter(FragmentManager fragmentManager) {
+ super(fragmentManager);
+ }
+
+ @Override
+ public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ super.setPrimaryItem(container, position, object);
+ if (currentFragment != null && currentFragment != object) {
+ ActionMode action = null;
+ if (currentFragment instanceof MessageSelectorFragment) {
+ action = ((MessageSelectorFragment) currentFragment).getActionMode();
+ }
+ if (action != null) {
+ action.finish();
+ }
+ }
+ currentFragment = object;
+ }
+
+ @NonNull
+ @Override
+ public Fragment getItem(int position) {
+ TabData data = tabs.get(position);
+ Fragment fragment;
+ Bundle args = new Bundle();
+
+ if (data.type1 == DcMsg.DC_MSG_IMAGE) {
+ fragment = new AllMediaGalleryFragment();
+ args.putInt(AllMediaGalleryFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalGallery())? -1 : chatId);
+ } else {
+ fragment = new AllMediaDocumentsFragment();
+ args.putInt(AllMediaDocumentsFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalGallery())? -1 : chatId);
+ args.putInt(AllMediaDocumentsFragment.VIEWTYPE1, data.type1);
+ args.putInt(AllMediaDocumentsFragment.VIEWTYPE2, data.type2);
+ }
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public int getCount() {
+ return tabs.size();
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return getString(tabs.get(position).title);
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ super.onOptionsItemSelected(item);
+
+ int itemId = item.getItemId();
+ if (itemId == android.R.id.home) {
+ finish();
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileDocumentsAdapter.java b/src/main/java/org/thoughtcrime/securesms/AllMediaDocumentsAdapter.java
similarity index 96%
rename from src/main/java/org/thoughtcrime/securesms/ProfileDocumentsAdapter.java
rename to src/main/java/org/thoughtcrime/securesms/AllMediaDocumentsAdapter.java
index 424547412..c582c7288 100644
--- a/src/main/java/org/thoughtcrime/securesms/ProfileDocumentsAdapter.java
+++ b/src/main/java/org/thoughtcrime/securesms/AllMediaDocumentsAdapter.java
@@ -25,7 +25,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
-class ProfileDocumentsAdapter extends StickyHeaderGridAdapter {
+class AllMediaDocumentsAdapter extends StickyHeaderGridAdapter {
private final Context context;
private final ItemClickListener itemClickListener;
@@ -57,9 +57,9 @@ class ProfileDocumentsAdapter extends StickyHeaderGridAdapter {
}
}
- ProfileDocumentsAdapter(@NonNull Context context,
- BucketedThreadMedia media,
- ItemClickListener clickListener)
+ AllMediaDocumentsAdapter(@NonNull Context context,
+ BucketedThreadMedia media,
+ ItemClickListener clickListener)
{
this.context = context;
this.media = media;
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileDocumentsFragment.java b/src/main/java/org/thoughtcrime/securesms/AllMediaDocumentsFragment.java
similarity index 84%
rename from src/main/java/org/thoughtcrime/securesms/ProfileDocumentsFragment.java
rename to src/main/java/org/thoughtcrime/securesms/AllMediaDocumentsFragment.java
index 1f2e2688e..32b8acdcd 100644
--- a/src/main/java/org/thoughtcrime/securesms/ProfileDocumentsFragment.java
+++ b/src/main/java/org/thoughtcrime/securesms/AllMediaDocumentsFragment.java
@@ -33,21 +33,21 @@ import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.Set;
-public class ProfileDocumentsFragment
+public class AllMediaDocumentsFragment
extends MessageSelectorFragment
implements LoaderManager.LoaderCallbacks,
- ProfileDocumentsAdapter.ItemClickListener
+ AllMediaDocumentsAdapter.ItemClickListener
{
public static final String CHAT_ID_EXTRA = "chat_id";
- public static final String SHOW_AUDIO_EXTRA = "show_audio";
- public static final String SHOW_WEBXDC_EXTRA = "show_webxdc";
+ public static final String VIEWTYPE1 = "viewtype1";
+ public static final String VIEWTYPE2 = "viewtype2";
protected TextView noMedia;
protected RecyclerView recyclerView;
private StickyHeaderGridLayoutManager gridManager;
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
- private boolean showAudio;
- private boolean showWebxdc;
+ private int viewtype1;
+ private int viewtype2;
protected int chatId;
@@ -57,8 +57,8 @@ public class ProfileDocumentsFragment
dcContext = DcHelper.getContext(getContext());
chatId = getArguments().getInt(CHAT_ID_EXTRA, -1);
- showAudio = getArguments().getBoolean(SHOW_AUDIO_EXTRA, false);
- showWebxdc = getArguments().getBoolean(SHOW_WEBXDC_EXTRA, false);
+ viewtype1 = getArguments().getInt(VIEWTYPE1, 0);
+ viewtype2 = getArguments().getInt(VIEWTYPE2, 0);
getLoaderManager().initLoader(0, null, this);
}
@@ -71,7 +71,7 @@ public class ProfileDocumentsFragment
this.noMedia = ViewUtil.findById(view, R.id.no_documents);
this.gridManager = new StickyHeaderGridLayoutManager(1);
- this.recyclerView.setAdapter(new ProfileDocumentsAdapter(getContext(),
+ this.recyclerView.setAdapter(new AllMediaDocumentsAdapter(getContext(),
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
this));
this.recyclerView.setLayoutManager(gridManager);
@@ -105,32 +105,26 @@ public class ProfileDocumentsFragment
@Override
public Loader onCreateLoader(int i, Bundle bundle) {
- if (showAudio) {
- return new BucketedThreadMediaLoader(getContext(), chatId, DcMsg.DC_MSG_AUDIO, DcMsg.DC_MSG_VOICE, 0);
- } else if (showWebxdc) {
- return new BucketedThreadMediaLoader(getContext(), chatId, DcMsg.DC_MSG_WEBXDC, 0, 0);
- } else {
- return new BucketedThreadMediaLoader(getContext(), chatId, DcMsg.DC_MSG_FILE, 0, 0);
- }
+ return new BucketedThreadMediaLoader(getContext(), chatId, viewtype1, viewtype2, 0);
}
@Override
public void onLoadFinished(Loader loader, BucketedThreadMediaLoader.BucketedThreadMedia bucketedThreadMedia) {
- ((ProfileDocumentsAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
- ((ProfileDocumentsAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
+ ((AllMediaDocumentsAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
+ ((AllMediaDocumentsAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
if (chatId == DC_CHAT_NO_CHAT) {
- if (showWebxdc) {
+ if (viewtype1 == DcMsg.DC_MSG_WEBXDC) {
noMedia.setText(R.string.all_apps_empty_hint);
- } else if (!showAudio){
+ } else if (viewtype1 == DcMsg.DC_MSG_FILE){
noMedia.setText(R.string.all_files_empty_hint);
} else {
noMedia.setText(R.string.tab_all_media_empty_hint);
}
- } else if (showAudio) {
+ } else if (viewtype1 == DcMsg.DC_MSG_AUDIO) {
noMedia.setText(R.string.tab_audio_empty_hint);
- } else if (showWebxdc) {
+ } else if (viewtype1 == DcMsg.DC_MSG_WEBXDC) {
noMedia.setText(R.string.tab_webxdc_empty_hint);
}
getActivity().invalidateOptionsMenu();
@@ -138,7 +132,7 @@ public class ProfileDocumentsFragment
@Override
public void onLoaderReset(Loader cursorLoader) {
- ((ProfileDocumentsAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
+ ((AllMediaDocumentsAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
}
@Override
@@ -156,7 +150,7 @@ public class ProfileDocumentsFragment
}
private void handleMediaMultiSelectClick(@NonNull DcMsg mediaRecord) {
- ProfileDocumentsAdapter adapter = getListAdapter();
+ AllMediaDocumentsAdapter adapter = getListAdapter();
adapter.toggleSelection(mediaRecord);
if (adapter.getSelectedMediaCount() == 0) {
@@ -188,7 +182,7 @@ public class ProfileDocumentsFragment
@Override
public void onMediaLongClicked(DcMsg mediaRecord) {
if (actionMode == null) {
- ((ProfileDocumentsAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
+ ((AllMediaDocumentsAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
}
@@ -221,8 +215,8 @@ public class ProfileDocumentsFragment
menu.findItem(R.id.menu_add_to_home_screen).setVisible(webxdcApp);
}
- private ProfileDocumentsAdapter getListAdapter() {
- return (ProfileDocumentsAdapter) recyclerView.getAdapter();
+ private AllMediaDocumentsAdapter getListAdapter() {
+ return (AllMediaDocumentsAdapter) recyclerView.getAdapter();
}
private class ActionModeCallback implements ActionMode.Callback {
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileGalleryAdapter.java b/src/main/java/org/thoughtcrime/securesms/AllMediaGalleryAdapter.java
similarity index 93%
rename from src/main/java/org/thoughtcrime/securesms/ProfileGalleryAdapter.java
rename to src/main/java/org/thoughtcrime/securesms/AllMediaGalleryAdapter.java
index 1efa30457..85d940625 100644
--- a/src/main/java/org/thoughtcrime/securesms/ProfileGalleryAdapter.java
+++ b/src/main/java/org/thoughtcrime/securesms/AllMediaGalleryAdapter.java
@@ -21,7 +21,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
-class ProfileGalleryAdapter extends StickyHeaderGridAdapter {
+class AllMediaGalleryAdapter extends StickyHeaderGridAdapter {
private final Context context;
private final GlideRequests glideRequests;
@@ -50,10 +50,10 @@ class ProfileGalleryAdapter extends StickyHeaderGridAdapter {
}
}
- ProfileGalleryAdapter(@NonNull Context context,
- @NonNull GlideRequests glideRequests,
- BucketedThreadMedia media,
- ItemClickListener clickListener)
+ AllMediaGalleryAdapter(@NonNull Context context,
+ @NonNull GlideRequests glideRequests,
+ BucketedThreadMedia media,
+ ItemClickListener clickListener)
{
this.context = context;
this.glideRequests = glideRequests;
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileGalleryFragment.java b/src/main/java/org/thoughtcrime/securesms/AllMediaGalleryFragment.java
similarity index 92%
rename from src/main/java/org/thoughtcrime/securesms/ProfileGalleryFragment.java
rename to src/main/java/org/thoughtcrime/securesms/AllMediaGalleryFragment.java
index 97ad4471e..a3c742027 100644
--- a/src/main/java/org/thoughtcrime/securesms/ProfileGalleryFragment.java
+++ b/src/main/java/org/thoughtcrime/securesms/AllMediaGalleryFragment.java
@@ -35,10 +35,10 @@ import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.Set;
-public class ProfileGalleryFragment
+public class AllMediaGalleryFragment
extends MessageSelectorFragment
implements LoaderManager.LoaderCallbacks,
- ProfileGalleryAdapter.ItemClickListener
+ AllMediaGalleryAdapter.ItemClickListener
{
public static final String CHAT_ID_EXTRA = "chat_id";
@@ -67,7 +67,7 @@ public class ProfileGalleryFragment
this.noMedia = ViewUtil.findById(view, R.id.no_images);
this.gridManager = new StickyHeaderGridLayoutManager(getCols());
- this.recyclerView.setAdapter(new ProfileGalleryAdapter(getContext(),
+ this.recyclerView.setAdapter(new AllMediaGalleryAdapter(getContext(),
GlideApp.with(this),
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
this));
@@ -112,8 +112,8 @@ public class ProfileGalleryFragment
@Override
public void onLoadFinished(Loader loader, BucketedThreadMediaLoader.BucketedThreadMedia bucketedThreadMedia) {
- ((ProfileGalleryAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
- ((ProfileGalleryAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
+ ((AllMediaGalleryAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
+ ((AllMediaGalleryAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
if (chatId == DC_CHAT_NO_CHAT) {
@@ -124,7 +124,7 @@ public class ProfileGalleryFragment
@Override
public void onLoaderReset(Loader cursorLoader) {
- ((ProfileGalleryAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
+ ((AllMediaGalleryAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
}
@Override
@@ -142,7 +142,7 @@ public class ProfileGalleryFragment
}
private void handleMediaMultiSelectClick(@NonNull DcMsg mediaRecord) {
- ProfileGalleryAdapter adapter = getListAdapter();
+ AllMediaGalleryAdapter adapter = getListAdapter();
adapter.toggleSelection(mediaRecord);
if (adapter.getSelectedMediaCount() == 0) {
@@ -175,7 +175,7 @@ public class ProfileGalleryFragment
@Override
public void onMediaLongClicked(DcMsg mediaRecord) {
if (actionMode == null) {
- ((ProfileGalleryAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
+ ((AllMediaGalleryAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
recyclerView.getAdapter().notifyDataSetChanged();
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
@@ -206,8 +206,8 @@ public class ProfileGalleryFragment
menu.findItem(R.id.menu_resend).setVisible(canResend);
}
- private ProfileGalleryAdapter getListAdapter() {
- return (ProfileGalleryAdapter) recyclerView.getAdapter();
+ private AllMediaGalleryAdapter getListAdapter() {
+ return (AllMediaGalleryAdapter) recyclerView.getAdapter();
}
private class ActionModeCallback implements ActionMode.Callback {
diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java
index 4544064de..ecea1e968 100644
--- a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java
+++ b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java
@@ -529,8 +529,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} else if (itemId == R.id.menu_show_map) {
WebxdcActivity.openMaps(this, chatId);
return true;
- } else if (itemId == R.id.menu_show_apps) {
- handleProfile(true);
+ } else if (itemId == R.id.menu_all_media) {
+ handleAllMedia();
return true;
} else if (itemId == R.id.menu_search_up) {
handleMenuSearchNext(false);
@@ -612,15 +612,16 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
}
- private void handleProfile(boolean showApps) {
+ private void handleProfile() {
Intent intent = new Intent(this, ProfileActivity.class);
intent.putExtra(ProfileActivity.CHAT_ID_EXTRA, chatId);
- intent.putExtra(ProfileActivity.FROM_CHAT, true);
- if (showApps) {
- intent.putExtra(ProfileActivity.FORCE_TAB_EXTRA, ProfileActivity.TAB_WEBXDC);
- }
startActivity(intent);
- overridePendingTransition(0, 0);
+ }
+
+ private void handleAllMedia() {
+ Intent intent = new Intent(this, AllMediaActivity.class);
+ intent.putExtra(AllMediaActivity.CHAT_ID_EXTRA, chatId);
+ startActivity(intent);
}
private void handleLeaveGroup() {
@@ -872,7 +873,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
buttonToggle.getBackground().invalidateSelf();
});
- titleView.setOnClickListener(v -> handleProfile(false));
+ titleView.setOnClickListener(v -> handleProfile());
titleView.setOnBackClickedListener(view -> handleReturnToConversationList());
composeText.setOnKeyListener(composeKeyPressedListener);
diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java
index b588406cf..300cb62de 100644
--- a/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java
+++ b/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java
@@ -449,7 +449,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
onBackPressed();
return true;
} else if (itemId == R.id.menu_all_media) {
- startActivity(new Intent(this, ProfileActivity.class));
+ startActivity(new Intent(this, AllMediaActivity.class));
return true;
}
diff --git a/src/main/java/org/thoughtcrime/securesms/MediaPreviewActivity.java b/src/main/java/org/thoughtcrime/securesms/MediaPreviewActivity.java
index b603d2eff..bcb848cae 100644
--- a/src/main/java/org/thoughtcrime/securesms/MediaPreviewActivity.java
+++ b/src/main/java/org/thoughtcrime/securesms/MediaPreviewActivity.java
@@ -262,16 +262,16 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
finish();
}
else if(conversationRecipient.getAddress().isDcChat()) {
- Intent intent = new Intent(this, ProfileActivity.class);
- intent.putExtra(ProfileActivity.CHAT_ID_EXTRA, conversationRecipient.getAddress().getDcChatId());
- intent.putExtra(ProfileActivity.FORCE_TAB_EXTRA, ProfileActivity.TAB_GALLERY);
+ Intent intent = new Intent(this, AllMediaActivity.class);
+ intent.putExtra(AllMediaActivity.CHAT_ID_EXTRA, conversationRecipient.getAddress().getDcChatId());
+ intent.putExtra(AllMediaActivity.FORCE_GALLERY, true);
startActivity(intent);
finish();
}
else if(conversationRecipient.getAddress().isDcContact()) {
- Intent intent = new Intent(this, ProfileActivity.class);
- intent.putExtra(ProfileActivity.CONTACT_ID_EXTRA, conversationRecipient.getAddress().getDcContactId());
- intent.putExtra(ProfileActivity.FORCE_TAB_EXTRA, ProfileActivity.TAB_GALLERY);
+ Intent intent = new Intent(this, AllMediaActivity.class);
+ intent.putExtra(AllMediaActivity.CONTACT_ID_EXTRA, conversationRecipient.getAddress().getDcContactId());
+ intent.putExtra(AllMediaActivity.FORCE_GALLERY, true);
startActivity(intent);
finish();
}
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileActivity.java b/src/main/java/org/thoughtcrime/securesms/ProfileActivity.java
index 1ac092903..506e49e42 100644
--- a/src/main/java/org/thoughtcrime/securesms/ProfileActivity.java
+++ b/src/main/java/org/thoughtcrime/securesms/ProfileActivity.java
@@ -11,19 +11,13 @@ import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.view.ActionMode;
import androidx.appcompat.widget.Toolbar;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentStatePagerAdapter;
-import androidx.viewpager.widget.ViewPager;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
@@ -31,11 +25,9 @@ import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.rpc.Rpc;
import com.b44t.messenger.rpc.RpcException;
-import com.google.android.material.tabs.TabLayout;
import org.thoughtcrime.securesms.connect.DcEventCenter;
import org.thoughtcrime.securesms.connect.DcHelper;
-import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.RelayUtil;
@@ -43,7 +35,6 @@ import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import java.io.File;
-import java.util.ArrayList;
public class ProfileActivity extends PassphraseRequiredActionBarActivity
implements DcEventCenter.DcEventDelegate
@@ -51,16 +42,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
public static final String CHAT_ID_EXTRA = "chat_id";
public static final String CONTACT_ID_EXTRA = "contact_id";
- public static final String FORCE_TAB_EXTRA = "force_tab";
- public static final String FROM_CHAT = "from_chat";
-
- public static final int TAB_SETTINGS = 10;
- public static final int TAB_GALLERY = 20;
- public static final int TAB_AUDIO = 25;
- public static final int TAB_DOCS = 30;
- public static final int TAB_WEBXDC = 35;
- public static final int TAB_LINKS = 40;
- public static final int TAB_MAP = 50;
private static final int REQUEST_CODE_PICK_RINGTONE = 1;
@@ -72,13 +53,8 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
private boolean chatIsMailingList;
private boolean chatIsBroadcast;
private int contactId;
- private boolean fromChat;
-
- private final ArrayList tabs = new ArrayList<>();
- private Toolbar toolbar;
- private ConversationTitleView titleView;
- private TabLayout tabLayout;
- private ViewPager viewPager;
+ private boolean contactIsBot;
+ private Toolbar toolbar;
@Override
protected void onPreCreate() {
@@ -97,38 +73,27 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
setSupportActionBar(this.toolbar);
ActionBar supportActionBar = getSupportActionBar();
if (supportActionBar != null) {
- if (isGlobalProfile()) {
- supportActionBar.setDisplayHomeAsUpEnabled(true);
- supportActionBar.setHomeActionContentDescription(getString(R.string.back));
- } else {
- supportActionBar.setDisplayHomeAsUpEnabled(false);
- supportActionBar.setCustomView(R.layout.conversation_title_view);
- supportActionBar.setDisplayShowCustomEnabled(true);
- supportActionBar.setDisplayShowTitleEnabled(false);
- Toolbar parent = (Toolbar) supportActionBar.getCustomView().getParent();
- parent.setPadding(0,0,0,0);
- parent.setContentInsetsAbsolute(0,0);
-
- titleView = (ConversationTitleView) supportActionBar.getCustomView();
- titleView.setOnBackClickedListener(view -> onBackPressed());
- titleView.setOnClickListener(view -> onEnlargeAvatar());
- if (isContactProfile() && !isSelfProfile() && !chatIsDeviceTalk) {
- titleView.registerForContextMenu(this);
- }
+ String title = getString(R.string.profile);
+ if (chatIsMailingList) {
+ title = getString(R.string.mailing_list);
+ } else if (chatIsBroadcast) {
+ title = getString(R.string.broadcast_list);
+ } else if (chatIsMultiUser) {
+ title = getString(R.string.tab_group);
+ } else if (contactIsBot) {
+ title = getString(R.string.bot);
+ } else if (!chatIsDeviceTalk && !isSelfProfile()) {
+ title = getString(R.string.tab_contact);
}
+
+ supportActionBar.setDisplayHomeAsUpEnabled(true);
+ supportActionBar.setTitle(title);
}
- updateToolbar();
-
- this.tabLayout.setupWithViewPager(viewPager);
- this.viewPager.setAdapter(new ProfilePagerAdapter(getSupportFragmentManager()));
- int forceTab = getIntent().getIntExtra(FORCE_TAB_EXTRA, -1);
- if (forceTab != -1) {
- int forceIndex = tabs.indexOf(forceTab);
- if (forceIndex != -1) {
- this.viewPager.setCurrentItem(forceIndex);
- }
- }
+ Bundle args = new Bundle();
+ args.putInt(ProfileFragment.CHAT_ID_EXTRA, (chatId == 0) ? -1 : chatId);
+ args.putInt(ProfileFragment.CONTACT_ID_EXTRA, (contactId == 0) ? -1 : contactId);
+ initFragment(R.id.fragment_container, new ProfileFragment(), args);
DcEventCenter eventCenter = DcHelper.getEventCenter(this);
eventCenter.addObserver(DcContext.DC_EVENT_CHAT_MODIFIED, this);
@@ -137,7 +102,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
- if (!isSelfProfile() && !isGlobalProfile()) {
+ if (!isSelfProfile()) {
getMenuInflater().inflate(R.menu.profile_common, menu);
boolean canReceive = true;
@@ -149,6 +114,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
menu.findItem(R.id.show_encr_info).setVisible(false);
menu.findItem(R.id.share).setVisible(false);
} else if (chatIsMultiUser) {
+ menu.findItem(R.id.edit_name).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
if (chatIsBroadcast) {
canReceive = false;
} else {
@@ -207,21 +173,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
getMenuInflater().inflate(R.menu.profile_title_context, menu);
}
- boolean backPressed = false;
- @Override
- public void onBackPressed() {
- backPressed = true;
- super.onBackPressed();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- if (backPressed && fromChat) {
- overridePendingTransition(0, 0);
- }
- }
-
@Override
public void onDestroy() {
DcHelper.getEventCenter(this).removeObservers(this);
@@ -230,22 +181,24 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
@Override
public void handleEvent(@NonNull DcEvent event) {
- updateToolbar();
}
private void initializeResources() {
chatId = getIntent().getIntExtra(CHAT_ID_EXTRA, 0);
contactId = getIntent().getIntExtra(CONTACT_ID_EXTRA, 0);
+ contactIsBot = false;
chatIsMultiUser = false;
chatIsDeviceTalk = false;
chatIsMailingList= false;
chatIsBroadcast = false;
- fromChat = getIntent().getBooleanExtra(FROM_CHAT, false);
if (contactId!=0) {
+ DcContact dcContact = dcContext.getContact(contactId);
chatId = dcContext.getChatIdByContactId(contactId);
+ contactIsBot = dcContact.isBot();
}
- else if(chatId!=0) {
+
+ if(chatId!=0) {
DcChat dcChat = dcContext.getChat(chatId);
chatIsMultiUser = dcChat.isMultiUser();
chatIsDeviceTalk = dcChat.isDeviceTalk();
@@ -257,38 +210,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
}
}
- if(!isGlobalProfile() && !isSelfProfile() && !chatIsMailingList) {
- tabs.add(TAB_SETTINGS);
- }
- tabs.add(TAB_GALLERY);
- tabs.add(TAB_AUDIO);
- tabs.add(TAB_DOCS);
- tabs.add(TAB_WEBXDC);
- //tabs.add(TAB_LINKS);
- //if(Prefs.isLocationStreamingEnabled(this)) {
- // tabs.add(TAB_MAP);
- //}
-
- this.viewPager = ViewUtil.findById(this, R.id.pager);
this.toolbar = ViewUtil.findById(this, R.id.toolbar);
- this.tabLayout = ViewUtil.findById(this, R.id.tab_layout);
- }
-
- private void updateToolbar() {
- if (isGlobalProfile()){
- getSupportActionBar().setTitle(R.string.menu_all_media);
- }
- else if (chatId > 0) {
- DcChat dcChat = dcContext.getChat(chatId);
- titleView.setTitle(GlideApp.with(this), dcChat, true);
- }
- else if (isContactProfile()){
- titleView.setTitle(GlideApp.with(this), dcContext.getContact(contactId));
- }
- }
-
- private boolean isGlobalProfile() {
- return contactId==0 && chatId==0;
}
private boolean isContactProfile() {
@@ -300,124 +222,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
return isContactProfile() && contactId==DcContact.DC_CONTACT_ID_SELF;
}
- private class ProfilePagerAdapter extends FragmentStatePagerAdapter {
- private Object currentFragment = null;
-
- ProfilePagerAdapter(FragmentManager fragmentManager) {
- super(fragmentManager);
- }
-
- @Override
- public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
- super.setPrimaryItem(container, position, object);
- if (currentFragment != null && currentFragment != object) {
- ActionMode action = null;
- if (currentFragment instanceof MessageSelectorFragment) {
- action = ((MessageSelectorFragment) currentFragment).getActionMode();
- } else if (currentFragment instanceof ProfileSettingsFragment) {
- action = ((ProfileSettingsFragment) currentFragment).getActionMode();
- }
- if (action != null) {
- action.finish();
- }
- }
- currentFragment = object;
- }
-
- @NonNull
- @Override
- public Fragment getItem(int position) {
- int tabId = tabs.get(position);
- Fragment fragment;
- Bundle args = new Bundle();
-
- switch(tabId) {
- case TAB_SETTINGS:
- fragment = new ProfileSettingsFragment();
- args.putInt(ProfileSettingsFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
- args.putInt(ProfileSettingsFragment.CONTACT_ID_EXTRA, (contactId==0&&!isGlobalProfile())? -1 : contactId);
- break;
-
- case TAB_GALLERY:
- fragment = new ProfileGalleryFragment();
- args.putInt(ProfileGalleryFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
- break;
-
- case TAB_AUDIO:
- fragment = new ProfileDocumentsFragment();
- args.putInt(ProfileDocumentsFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
- args.putBoolean(ProfileDocumentsFragment.SHOW_AUDIO_EXTRA, true);
- break;
-
- case TAB_WEBXDC:
- fragment = new ProfileDocumentsFragment();
- args.putInt(ProfileDocumentsFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
- args.putBoolean(ProfileDocumentsFragment.SHOW_WEBXDC_EXTRA, true);
- break;
-
- default:
- fragment = new ProfileDocumentsFragment();
- args.putInt(ProfileGalleryFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
- break;
- }
-
- fragment.setArguments(args);
- return fragment;
- }
-
- @Override
- public int getCount() {
- return tabs.size();
- }
-
- @Override
- public CharSequence getPageTitle(int position) {
- int tabId = tabs.get(position);
- switch(tabId) {
- case TAB_SETTINGS:
- if (chatIsDeviceTalk) {
- return getString(R.string.profile);
- } else if(isContactProfile()) {
- if (dcContext.getContact(contactId).isBot()) {
- return getString(R.string.bot);
- } else {
- return getString(R.string.tab_contact);
- }
- }
- else if (chatIsBroadcast) {
- return getString(R.string.broadcast_list);
- }
- else if (chatIsMailingList) {
- return getString(R.string.mailing_list);
- } else {
- return getString(R.string.tab_group);
- }
-
- case TAB_GALLERY:
- return getString(R.string.tab_gallery);
-
- case TAB_AUDIO:
- return getString(R.string.audio);
-
- case TAB_DOCS:
- return getString(R.string.files);
-
- case TAB_WEBXDC:
- return getString(R.string.webxdc_apps);
-
- case TAB_LINKS:
- return getString(R.string.tab_links);
-
- case TAB_MAP:
- return getString(R.string.tab_map);
-
- default:
- throw new AssertionError();
- }
- }
- }
-
-
// handle events
// =========================================================================
@@ -427,7 +231,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
int itemId = item.getItemId();
if (itemId == android.R.id.home) {
- backPressed = true;
finish();
return true;
} else if (itemId == R.id.menu_mute_notifications) {
@@ -505,7 +308,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
.show();
}
- private void onEnlargeAvatar() {
+ public void onEnlargeAvatar() {
String profileImagePath;
String title;
Uri profileImageUri;
@@ -530,7 +333,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
intent.putExtra(MediaPreviewActivity.ACTIVITY_TITLE_EXTRA, title);
intent.putExtra(MediaPreviewActivity.EDIT_AVATAR_CHAT_ID, chatIsMultiUser ? chatId : 0); // shows edit-button, might be 0 for a contact-profile
startActivity(intent);
- } else {
+ } else if (chatIsMultiUser){
onEditName();
}
}
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileAdapter.java b/src/main/java/org/thoughtcrime/securesms/ProfileAdapter.java
new file mode 100644
index 000000000..1f6850bd1
--- /dev/null
+++ b/src/main/java/org/thoughtcrime/securesms/ProfileAdapter.java
@@ -0,0 +1,372 @@
+package org.thoughtcrime.securesms;
+
+import android.content.Context;
+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.recyclerview.widget.RecyclerView;
+
+import com.b44t.messenger.DcChat;
+import com.b44t.messenger.DcChatlist;
+import com.b44t.messenger.DcContact;
+import com.b44t.messenger.DcContext;
+import com.b44t.messenger.DcLot;
+import com.b44t.messenger.DcMsg;
+
+import org.thoughtcrime.securesms.connect.DcHelper;
+import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
+import org.thoughtcrime.securesms.mms.GlideRequests;
+import org.thoughtcrime.securesms.util.DateUtils;
+import org.thoughtcrime.securesms.util.Util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ProfileAdapter extends RecyclerView.Adapter
+{
+ public static final int ITEM_AVATAR = 10;
+ public static final int ITEM_DIVIDER = 20;
+ public static final int ITEM_SIGNATURE = 25;
+ public static final int ITEM_ALL_MEDIA_BUTTON = 30;
+ public static final int ITEM_SEND_MESSAGE_BUTTON = 35;
+ public static final int ITEM_LAST_SEEN = 40;
+ public static final int ITEM_INTRODUCED_BY = 45;
+ public static final int ITEM_ADDRESS = 50;
+ public static final int ITEM_HEADER = 53;
+ public static final int ITEM_MEMBERS = 55;
+ public static final int ITEM_SHARED_CHATS = 60;
+
+ private final @NonNull Context context;
+ private final @NonNull DcContext dcContext;
+ private @Nullable DcChat dcChat;
+ private @Nullable DcContact dcContact;
+
+ private final @NonNull ArrayList itemData = new ArrayList<>();
+ private DcChatlist itemDataSharedChats;
+ private String itemDataStatusText;
+ private boolean isBroadcast;
+ private int memberCount;
+ private final Set selectedMembers;
+
+ private final LayoutInflater layoutInflater;
+ private final ItemClickListener clickListener;
+ private final GlideRequests glideRequests;
+
+ static class ItemData {
+ final int viewType;
+ final int contactId;
+ final int chatlistIndex;
+ final String label;
+ final int icon;
+
+ ItemData(int viewType, String label, int icon) {
+ this(viewType, 0, 0, label, icon);
+ }
+
+ ItemData(int viewType, int contactId, int chatlistIndex) {
+ this(viewType, contactId, chatlistIndex, null, 0);
+ }
+
+ private ItemData(int viewType, int contactId, int chatlistIndex, @Nullable String label, int icon) {
+ this.viewType = viewType;
+ this.contactId = contactId;
+ this.chatlistIndex = chatlistIndex;
+ this.label = label;
+ this.icon = icon;
+ }
+ };
+
+ public ProfileAdapter(@NonNull Context context,
+ @NonNull GlideRequests glideRequests,
+ @Nullable ItemClickListener clickListener)
+ {
+ super();
+ this.context = context;
+ this.glideRequests = glideRequests;
+ this.clickListener = clickListener;
+ this.dcContext = DcHelper.getContext(context);
+ this.layoutInflater = LayoutInflater.from(context);
+ this.selectedMembers= new HashSet<>();
+ }
+
+ @Override
+ public int getItemCount() {
+ return itemData.size();
+ }
+
+ @Override
+ public int getItemViewType(int i) {
+ return itemData.get(i).viewType;
+ }
+
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ public ViewHolder(View itemView) {
+ super(itemView);
+ }
+ }
+
+ @NonNull
+ @Override
+ public ProfileAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ if (viewType == ITEM_HEADER) {
+ final View item = LayoutInflater.from(context).inflate(R.layout.contact_selection_list_divider, parent, false);
+ return new ViewHolder(item);
+ } else if (viewType == ITEM_DIVIDER) {
+ final View item = LayoutInflater.from(context).inflate(R.layout.profile_divider, parent, false);
+ return new ViewHolder(item);
+ } else if (viewType == ITEM_MEMBERS) {
+ final ContactSelectionListItem item = (ContactSelectionListItem)layoutInflater.inflate(R.layout.contact_selection_list_item, parent, false);
+ return new ViewHolder(item);
+ } else if (viewType == ITEM_SHARED_CHATS) {
+ final ConversationListItem item = (ConversationListItem)layoutInflater.inflate(R.layout.conversation_list_item_view, parent, false);
+ item.hideItemDivider();
+ return new ViewHolder(item);
+ } else if (viewType == ITEM_SIGNATURE) {
+ final ProfileStatusItem item = (ProfileStatusItem)layoutInflater.inflate(R.layout.profile_status_item, parent, false);
+ return new ViewHolder(item);
+ } else if (viewType == ITEM_AVATAR) {
+ final ProfileAvatarItem item = (ProfileAvatarItem)layoutInflater.inflate(R.layout.profile_avatar_item, parent, false);
+ return new ViewHolder(item);
+ } else if (viewType == ITEM_ALL_MEDIA_BUTTON || viewType == ITEM_SEND_MESSAGE_BUTTON) {
+ final ProfileTextItem item = (ProfileTextItem)layoutInflater.inflate(R.layout.profile_text_item_button, parent, false);
+ return new ViewHolder(item);
+ } else if (viewType == ITEM_LAST_SEEN || viewType == ITEM_INTRODUCED_BY || viewType == ITEM_ADDRESS) {
+ final ProfileTextItem item = (ProfileTextItem)layoutInflater.inflate(R.layout.profile_text_item_small, parent, false);
+ return new ViewHolder(item);
+ } else {
+ final ProfileTextItem item = (ProfileTextItem)layoutInflater.inflate(R.layout.profile_text_item, parent, false);
+ return new ViewHolder(item);
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
+ ViewHolder holder = (ViewHolder) viewHolder;
+ ItemData data = itemData.get(i);
+ if (holder.itemView instanceof ContactSelectionListItem) {
+ ContactSelectionListItem contactItem = (ContactSelectionListItem) holder.itemView;
+
+ int contactId = data.contactId;
+ DcContact dcContact = null;
+ String label = null;
+ String name;
+ String addr = null;
+
+ if (contactId == DcContact.DC_CONTACT_ID_ADD_MEMBER) {
+ if (isBroadcast) {
+ name = context.getString(R.string.add_recipients);
+ } else {
+ name = context.getString(R.string.group_add_members);
+ }
+ }
+ else if (contactId == DcContact.DC_CONTACT_ID_QR_INVITE) {
+ name = context.getString(R.string.qrshow_title);
+ }
+ else {
+ dcContact = dcContext.getContact(contactId);
+ name = dcContact.getDisplayName();
+ addr = dcContact.getAddr();
+ }
+
+ contactItem.unbind(glideRequests);
+ contactItem.set(glideRequests, contactId, dcContact, name, addr, label, false, true);
+ contactItem.setSelected(selectedMembers.contains(contactId));
+ contactItem.setOnClickListener(view -> clickListener.onMemberClicked(contactId));
+ contactItem.setOnLongClickListener(view -> {clickListener.onMemberLongClicked(contactId); return true;});
+ }
+ else if (holder.itemView instanceof ConversationListItem) {
+ ConversationListItem conversationListItem = (ConversationListItem) holder.itemView;
+ int chatlistIndex = data.chatlistIndex;
+
+ int chatId = itemDataSharedChats.getChatId(chatlistIndex);
+ DcChat chat = dcContext.getChat(chatId);
+ DcLot summary = itemDataSharedChats.getSummary(chatlistIndex, chat);
+
+ conversationListItem.bind(DcHelper.getThreadRecord(context, summary, chat),
+ itemDataSharedChats.getMsgId(chatlistIndex), summary, glideRequests,
+ Collections.emptySet(), false);
+ conversationListItem.setOnClickListener(view -> clickListener.onSharedChatClicked(chatId));
+ }
+ else if(holder.itemView instanceof ProfileStatusItem) {
+ ProfileStatusItem item = (ProfileStatusItem) holder.itemView;
+ item.setOnLongClickListener(view -> {clickListener.onStatusLongClicked(); return true;});
+ item.set(data.label);
+ }
+ else if(holder.itemView instanceof ProfileAvatarItem) {
+ ProfileAvatarItem item = (ProfileAvatarItem) holder.itemView;
+ item.setAvatarClickListener(view -> clickListener.onAvatarClicked());
+ item.set(glideRequests, dcChat, dcContact, memberCount);
+ }
+ else if(holder.itemView instanceof ProfileTextItem) {
+ ProfileTextItem item = (ProfileTextItem) holder.itemView;
+ item.setOnClickListener(view -> clickListener.onSettingsClicked(data.viewType));
+ item.set(data.label, data.icon);
+ if (data.viewType == ITEM_LAST_SEEN || data.viewType == ITEM_ADDRESS) {
+ int padding = (int)((float)context.getResources().getDimensionPixelSize(R.dimen.contact_list_normal_padding) * 1.2);
+ item.setPadding(item.getPaddingLeft(), item.getPaddingTop(), item.getPaddingRight(), padding);
+ } else if (data.viewType == ITEM_INTRODUCED_BY) {
+ int padding = context.getResources().getDimensionPixelSize(R.dimen.contact_list_normal_padding);
+ item.setPadding(item.getPaddingLeft(), padding, item.getPaddingRight(), item.getPaddingBottom());
+ } else if (data.viewType == ITEM_ALL_MEDIA_BUTTON && dcChat != null) {
+ Util.runOnAnyBackgroundThread(() -> {
+ String c = getAllMediaCountString(dcChat.getId());
+ Util.runOnMain(() -> {
+ item.setValue(c);
+ });
+ });
+ }
+ } else if (data.viewType == ITEM_HEADER) {
+ TextView textView = holder.itemView.findViewById(R.id.label);
+ textView.setText(data.label);
+ }
+ }
+
+ public interface ItemClickListener {
+ void onSettingsClicked(int settingsId);
+ void onStatusLongClicked();
+ void onSharedChatClicked(int chatId);
+ void onMemberClicked(int contactId);
+ void onMemberLongClicked(int contactId);
+ void onAvatarClicked();
+ }
+
+ public void toggleMemberSelection(int contactId) {
+ if (!selectedMembers.remove(contactId)) {
+ selectedMembers.add(contactId);
+ }
+ notifyDataSetChanged();
+ }
+
+ @NonNull
+ public Collection getSelectedMembers() {
+ return new HashSet<>(selectedMembers);
+ }
+
+ public int getSelectedMembersCount() {
+ return selectedMembers.size();
+ }
+
+ @NonNull
+ public String getStatusText() {
+ return itemDataStatusText;
+ }
+
+ public void clearSelection() {
+ selectedMembers.clear();
+ notifyDataSetChanged();
+ }
+
+ public void changeData(@Nullable int[] memberList, @Nullable DcContact dcContact, @Nullable DcChatlist sharedChats, @Nullable DcChat dcChat) {
+ this.dcChat = dcChat;
+ this.dcContact = dcContact;
+ itemData.clear();
+ itemDataSharedChats = sharedChats;
+ itemDataStatusText = "";
+ isBroadcast = dcChat != null && dcChat.isBroadcast();
+ boolean isMailingList = dcChat != null && dcChat.isMailingList();
+ boolean isGroup = dcChat != null && dcChat.getType() == DcChat.DC_CHAT_TYPE_GROUP;
+ boolean isSelfTalk = dcChat != null && dcChat.isSelfTalk();
+ boolean isDeviceTalk = dcChat != null && dcChat.isDeviceTalk();
+ memberCount = memberList!=null ? memberList.length : 0;
+
+ itemData.add(new ItemData(ITEM_AVATAR, null, 0));
+
+ if (isSelfTalk || dcContact != null && !dcContact.getStatus().isEmpty()) {
+ itemDataStatusText = isSelfTalk ? context.getString(R.string.saved_messages_explain) : dcContact.getStatus();
+ itemData.add(new ItemData(ITEM_SIGNATURE, itemDataStatusText, 0));
+ } else {
+ itemData.add(new ItemData(ITEM_DIVIDER, null, 0));
+ }
+
+ itemData.add(new ItemData(ITEM_ALL_MEDIA_BUTTON, context.getString(R.string.apps_and_media), R.drawable.ic_apps_24));
+
+ if (dcContact != null && !isDeviceTalk && !isSelfTalk) {
+ itemData.add(new ItemData(ITEM_SEND_MESSAGE_BUTTON, context.getString(R.string.send_message), R.drawable.ic_send_sms_white_24dp));
+ }
+
+ if (dcContact != null && !isDeviceTalk && !isSelfTalk) {
+ long lastSeenTimestamp = dcContact.getLastSeen();
+ String lastSeenTxt;
+ if (lastSeenTimestamp == 0) {
+ lastSeenTxt = context.getString(R.string.last_seen_unknown);
+ }
+ else {
+ lastSeenTxt = context.getString(R.string.last_seen_at, DateUtils.getExtendedTimeSpanString(context, lastSeenTimestamp));
+ }
+ itemData.add(new ItemData(ITEM_LAST_SEEN, lastSeenTxt, 0));
+ }
+
+ if (memberList!=null) {
+ itemData.add(new ItemData(ITEM_DIVIDER, null, 0));
+ if (dcChat != null) {
+ if (!isMailingList && dcChat.canSend() && dcChat.isEncrypted()) {
+ itemData.add(new ItemData(ITEM_MEMBERS, DcContact.DC_CONTACT_ID_ADD_MEMBER, 0));
+ if (!isBroadcast) {
+ itemData.add(new ItemData(ITEM_MEMBERS, DcContact.DC_CONTACT_ID_QR_INVITE, 0));
+ }
+ }
+ }
+ for (int value : memberList) {
+ itemData.add(new ItemData(ITEM_MEMBERS, value, 0));
+ }
+ }
+
+ if (sharedChats != null && !isDeviceTalk) {
+ itemData.add(new ItemData(ITEM_HEADER, context.getString(R.string.profile_shared_chats), 0));
+ for (int i = 0; i < sharedChats.getCnt(); i++) {
+ itemData.add(new ItemData(ITEM_SHARED_CHATS, 0, i));
+ }
+ }
+
+ if (dcContact != null && !isDeviceTalk && !isSelfTalk) {
+ int verifierId = dcContact.getVerifierId();
+ if (verifierId != 0) {
+ String introducedBy;
+ if (verifierId == DcContact.DC_CONTACT_ID_SELF) {
+ introducedBy = context.getString(R.string.verified_by_you);
+ } else {
+ introducedBy = context.getString(R.string.verified_by, dcContext.getContact(verifierId).getDisplayName());
+ }
+ itemData.add(new ItemData(ITEM_INTRODUCED_BY, introducedBy, 0));
+ }
+
+ if (dcContact != null) {
+ itemData.add(new ItemData(ITEM_ADDRESS, dcContact.getAddr(), 0));
+ } else if (isMailingList) {
+ itemData.add(new ItemData(ITEM_ADDRESS, dcChat.getMailinglistAddr(), 0));
+ }
+ }
+
+ notifyDataSetChanged();
+ }
+
+ public int ALL_MEDIA_COUNT_MAX = 500;
+ public int getAllMediaCount(int chatId) {
+ int c = dcContext.getChatMedia(chatId, DcMsg.DC_MSG_IMAGE, DcMsg.DC_MSG_GIF, DcMsg.DC_MSG_VIDEO).length;
+ if (c < ALL_MEDIA_COUNT_MAX) {
+ c += dcContext.getChatMedia(chatId, DcMsg.DC_MSG_AUDIO, DcMsg.DC_MSG_VOICE, 0).length;
+ }
+ if (c < ALL_MEDIA_COUNT_MAX) {
+ c += dcContext.getChatMedia(chatId, DcMsg.DC_MSG_FILE, DcMsg.DC_MSG_WEBXDC, 0).length;
+ }
+ return c;
+ }
+
+ public String getAllMediaCountString(int chatId) {
+ final int c = getAllMediaCount(chatId);
+ if (c == 0) {
+ return context.getString(R.string.none);
+ } else if (c >= ALL_MEDIA_COUNT_MAX) {
+ return ALL_MEDIA_COUNT_MAX + "+";
+ } else {
+ return c + "";
+ }
+ }
+}
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileAvatarItem.java b/src/main/java/org/thoughtcrime/securesms/ProfileAvatarItem.java
new file mode 100644
index 000000000..301c25fdd
--- /dev/null
+++ b/src/main/java/org/thoughtcrime/securesms/ProfileAvatarItem.java
@@ -0,0 +1,112 @@
+package org.thoughtcrime.securesms;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.b44t.messenger.DcChat;
+import com.b44t.messenger.DcContact;
+
+import org.thoughtcrime.securesms.components.AvatarView;
+import org.thoughtcrime.securesms.mms.GlideRequests;
+import org.thoughtcrime.securesms.recipients.Recipient;
+import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
+import org.thoughtcrime.securesms.util.Util;
+import org.thoughtcrime.securesms.util.ViewUtil;
+
+public class ProfileAvatarItem extends LinearLayout implements RecipientModifiedListener {
+
+ private AvatarView avatarView;
+ private TextView nameView;
+ private TextView subtitleView;
+
+ private Recipient recipient;
+ private GlideRequests glideRequests;
+
+ public ProfileAvatarItem(Context context) {
+ super(context);
+ }
+
+ public ProfileAvatarItem(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ avatarView = findViewById(R.id.avatar);
+ nameView = findViewById(R.id.name);
+ subtitleView = findViewById(R.id.subtitle);
+
+ ViewUtil.setTextViewGravityStart(nameView, getContext());
+ }
+
+ public void set(@NonNull GlideRequests glideRequests, @Nullable DcChat dcChat, @Nullable DcContact dcContact, int memberCount) {
+ this.glideRequests = glideRequests;
+
+ String name = "";
+ boolean greenCheckmark = false;
+ String subtitle = null;
+ if (dcChat != null) {
+ recipient = new Recipient(getContext(), dcChat);
+ name = dcChat.getName();
+ greenCheckmark = dcChat.isProtected();
+
+ if (dcChat.isMailingList()) {
+ subtitle = getContext().getString(R.string.contacts_headline);
+ } else if (dcChat.isBroadcast()) {
+ subtitle = getContext().getResources().getQuantityString(R.plurals.n_recipients, memberCount, memberCount);
+ } else if (dcChat.getType() == DcChat.DC_CHAT_TYPE_GROUP) {
+ subtitle = getContext().getResources().getQuantityString(R.plurals.n_members, memberCount, memberCount);
+ }
+ } else if (dcContact != null) {
+ recipient = new Recipient(getContext(), dcContact);
+ name = dcContact.getDisplayName();
+ greenCheckmark = dcContact.isVerified();
+ }
+
+ recipient.addListener(this);
+ avatarView.setAvatar(glideRequests, recipient, false);
+ avatarView.setSeenRecently(dcContact != null && dcContact.wasSeenRecently());
+
+ nameView.setText(name);
+ nameView.setCompoundDrawablesWithIntrinsicBounds(0,0, greenCheckmark ? R.drawable.ic_verified : 0, 0);
+
+ if (subtitle != null) {
+ subtitleView.setVisibility(View.VISIBLE);
+ subtitleView.setText(subtitle);
+ } else {
+ subtitleView.setVisibility(View.GONE);
+ }
+ }
+
+ public void setAvatarClickListener(OnClickListener listener) {
+ avatarView.setAvatarClickListener(listener);
+ }
+
+ public void unbind(GlideRequests glideRequests) {
+ if (recipient != null) {
+ recipient.removeListener(this);
+ recipient = null;
+ }
+
+ avatarView.clear(glideRequests);
+ }
+
+ @Override
+ public void onModified(final Recipient recipient) {
+ if (this.recipient == recipient) {
+ Util.runOnMain(() -> {
+ avatarView.setAvatar(glideRequests, recipient, false);
+ DcContact contact = recipient.getDcContact();
+ avatarView.setSeenRecently(contact != null && contact.wasSeenRecently());
+ nameView.setText(recipient.toShortString());
+ });
+ }
+ }
+}
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileSettingsFragment.java b/src/main/java/org/thoughtcrime/securesms/ProfileFragment.java
similarity index 91%
rename from src/main/java/org/thoughtcrime/securesms/ProfileSettingsFragment.java
rename to src/main/java/org/thoughtcrime/securesms/ProfileFragment.java
index b5e77e79e..3c9c0d855 100644
--- a/src/main/java/org/thoughtcrime/securesms/ProfileSettingsFragment.java
+++ b/src/main/java/org/thoughtcrime/securesms/ProfileFragment.java
@@ -31,7 +31,6 @@ import org.thoughtcrime.securesms.connect.DcEventCenter;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.qr.QrShowActivity;
-import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
@@ -39,16 +38,15 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-public class ProfileSettingsFragment extends Fragment
- implements ProfileSettingsAdapter.ItemClickListener, DcEventCenter.DcEventDelegate {
+public class ProfileFragment extends Fragment
+ implements ProfileAdapter.ItemClickListener, DcEventCenter.DcEventDelegate {
public static final String CHAT_ID_EXTRA = "chat_id";
public static final String CONTACT_ID_EXTRA = "contact_id";
private static final int REQUEST_CODE_PICK_CONTACT = 2;
- private StickyHeaderDecoration listDecoration;
- private ProfileSettingsAdapter adapter;
+ private ProfileAdapter adapter;
private ActionMode actionMode;
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
@@ -57,10 +55,6 @@ public class ProfileSettingsFragment extends Fragment
protected int chatId;
private int contactId;
- protected ActionMode getActionMode() {
- return actionMode;
- }
-
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
@@ -72,14 +66,12 @@ public class ProfileSettingsFragment extends Fragment
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.profile_settings_fragment, container, false);
- adapter = new ProfileSettingsAdapter(requireContext(), GlideApp.with(this), this);
+ View view = inflater.inflate(R.layout.profile_fragment, container, false);
+ adapter = new ProfileAdapter(requireContext(), GlideApp.with(this), this);
RecyclerView list = ViewUtil.findById(view, R.id.recycler_view);
list.setAdapter(adapter);
list.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
- listDecoration = new StickyHeaderDecoration(adapter, false, true);
- list.addItemDecoration(listDecoration);
update();
@@ -97,12 +89,6 @@ public class ProfileSettingsFragment extends Fragment
super.onDestroyView();
}
- @Override
- public void onConfigurationChanged(@NonNull Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- listDecoration.onConfigurationChanged(newConfig);
- }
-
@Override
public void handleEvent(@NonNull DcEvent event) {
update();
@@ -121,12 +107,11 @@ public class ProfileSettingsFragment extends Fragment
if(dcChat!=null && dcChat.isMultiUser()) {
memberList = dcContext.getChatContacts(chatId);
}
- else if(contactId>0) {
+ else if(contactId>0 && contactId!=DcContact.DC_CONTACT_ID_SELF) {
sharedChats = dcContext.getChatlist(0, null, contactId);
}
adapter.changeData(memberList, dcContact, sharedChats, dcChat);
- listDecoration.invalidateLayouts();
}
@@ -136,10 +121,17 @@ public class ProfileSettingsFragment extends Fragment
@Override
public void onSettingsClicked(int settingsId) {
switch(settingsId) {
- case ProfileSettingsAdapter.INFO_SEND_MESSAGE_BUTTON:
+ case ProfileAdapter.ITEM_ALL_MEDIA_BUTTON:
+ if (chatId > 0) {
+ Intent intent = new Intent(getActivity(), AllMediaActivity.class);
+ intent.putExtra(AllMediaActivity.CHAT_ID_EXTRA, chatId);
+ startActivity(intent);
+ }
+ break;
+ case ProfileAdapter.ITEM_SEND_MESSAGE_BUTTON:
onSendMessage();
break;
- case ProfileSettingsAdapter.INFO_VERIFIED:
+ case ProfileAdapter.ITEM_INTRODUCED_BY:
onVerifiedByClicked();
break;
}
@@ -202,6 +194,12 @@ public class ProfileSettingsFragment extends Fragment
}
}
+ @Override
+ public void onAvatarClicked() {
+ ProfileActivity activity = (ProfileActivity)getActivity();
+ activity.onEnlargeAvatar();
+ }
+
public void onAddMember() {
DcChat dcChat = dcContext.getChat(chatId);
Intent intent = new Intent(getContext(), ContactMultiSelectionActivity.class);
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileSettingsAdapter.java b/src/main/java/org/thoughtcrime/securesms/ProfileSettingsAdapter.java
deleted file mode 100644
index 90827157b..000000000
--- a/src/main/java/org/thoughtcrime/securesms/ProfileSettingsAdapter.java
+++ /dev/null
@@ -1,352 +0,0 @@
-package org.thoughtcrime.securesms;
-
-import android.content.Context;
-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.recyclerview.widget.RecyclerView;
-
-import com.b44t.messenger.DcChat;
-import com.b44t.messenger.DcChatlist;
-import com.b44t.messenger.DcContact;
-import com.b44t.messenger.DcContext;
-import com.b44t.messenger.DcLot;
-
-import org.thoughtcrime.securesms.connect.DcHelper;
-import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
-import org.thoughtcrime.securesms.mms.GlideRequests;
-import org.thoughtcrime.securesms.util.DateUtils;
-import org.thoughtcrime.securesms.util.StickyHeaderDecoration.StickyHeaderAdapter;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-public class ProfileSettingsAdapter extends RecyclerView.Adapter
- implements StickyHeaderAdapter
-{
- public static final int INFO_VERIFIED = 118;
- public static final int INFO_LAST_SEEN = 119;
- public static final int INFO_SEND_MESSAGE_BUTTON = 120;
-
- private final @NonNull Context context;
- private final @NonNull DcContext dcContext;
-
- private final @NonNull ArrayList itemData = new ArrayList<>();
- private int itemDataMemberCount;
- private DcChatlist itemDataSharedChats;
- private String itemDataStatusText;
- private boolean isMailingList;
- private boolean isBroadcast;
- private final Set selectedMembers;
-
- private final LayoutInflater layoutInflater;
- private final ItemClickListener clickListener;
- private final GlideRequests glideRequests;
-
- static class ItemData {
- static final int CATEGORY_INFO = 1;
- static final int CATEGORY_SIGNATURE = 2;
- static final int CATEGORY_MEMBERS = 3;
- static final int CATEGORY_SHARED_CHATS = 4;
- final int type;
- final int contactId;
- final int chatlistIndex;
- final int settingsId;
- final String label;
- final int labelColor;
- final int iconLeft;
-
- ItemData(int type, int settingsId, String label, int labelColor, int iconLeft) {
- this(type, 0, 0, settingsId, label, labelColor, iconLeft);
- }
-
- ItemData(int type, int contactId, int chatlistIndex) {
- this(type, contactId, chatlistIndex, 0, null, 0, 0);
- }
-
- ItemData(int type, int contactId, int chatlistIndex, int settingsId, @Nullable String label, int labelColor, int iconLeft) {
- this.type = type;
- this.contactId = contactId;
- this.chatlistIndex = chatlistIndex;
- this.settingsId = settingsId;
- this.label = label;
- this.labelColor = labelColor;
- this.iconLeft = iconLeft;
- }
- };
-
- public ProfileSettingsAdapter(@NonNull Context context,
- @NonNull GlideRequests glideRequests,
- @Nullable ItemClickListener clickListener)
- {
- super();
- this.context = context;
- this.glideRequests = glideRequests;
- this.clickListener = clickListener;
- this.dcContext = DcHelper.getContext(context);
- this.layoutInflater = LayoutInflater.from(context);
- this.selectedMembers= new HashSet<>();
- }
-
- @Override
- public int getItemCount() {
- return itemData.size();
- }
-
- public static class ViewHolder extends RecyclerView.ViewHolder {
- public ViewHolder(View itemView) {
- super(itemView);
- }
- }
-
- static class HeaderViewHolder extends RecyclerView.ViewHolder {
- final TextView textView;
- HeaderViewHolder(View itemView) {
- super(itemView);
- textView = itemView.findViewById(R.id.label);
- }
- }
-
- @NonNull
- @Override
- public ProfileSettingsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- if (viewType == ItemData.CATEGORY_MEMBERS) {
- final ContactSelectionListItem item = (ContactSelectionListItem)layoutInflater.inflate(R.layout.contact_selection_list_item, parent, false);
- item.setNoHeaderPadding();
- return new ViewHolder(item);
- }
- else if (viewType == ItemData.CATEGORY_SHARED_CHATS) {
- final ConversationListItem item = (ConversationListItem)layoutInflater.inflate(R.layout.conversation_list_item_view, parent, false);
- item.hideItemDivider();
- return new ViewHolder(item);
- }
- else if (viewType == ItemData.CATEGORY_SIGNATURE) {
- final ProfileStatusItem item = (ProfileStatusItem)layoutInflater.inflate(R.layout.profile_status_item, parent, false);
- return new ViewHolder(item);
- }
- else {
- final ProfileSettingsItem item = (ProfileSettingsItem)layoutInflater.inflate(R.layout.profile_settings_item, parent, false);
- return new ViewHolder(item);
- }
- }
-
- @Override
- public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
- ViewHolder holder = (ViewHolder) viewHolder;
- if (holder.itemView instanceof ContactSelectionListItem) {
- ContactSelectionListItem contactItem = (ContactSelectionListItem) holder.itemView;
-
- int contactId = itemData.get(i).contactId;
- DcContact dcContact = null;
- String label = null;
- String name;
- String addr = null;
-
- if (contactId == DcContact.DC_CONTACT_ID_ADD_MEMBER) {
- if (isBroadcast) {
- name = context.getString(R.string.add_recipients);
- } else {
- name = context.getString(R.string.group_add_members);
- }
- }
- else if (contactId == DcContact.DC_CONTACT_ID_QR_INVITE) {
- name = context.getString(R.string.qrshow_title);
- }
- else {
- dcContact = dcContext.getContact(contactId);
- name = dcContact.getDisplayName();
- addr = dcContact.getAddr();
- }
-
- contactItem.unbind(glideRequests);
- contactItem.set(glideRequests, contactId, dcContact, name, addr, label, false, true);
- contactItem.setSelected(selectedMembers.contains(contactId));
- contactItem.setOnClickListener(view -> clickListener.onMemberClicked(contactId));
- contactItem.setOnLongClickListener(view -> {clickListener.onMemberLongClicked(contactId); return true;});
- }
- else if (holder.itemView instanceof ConversationListItem) {
- ConversationListItem conversationListItem = (ConversationListItem) holder.itemView;
- int chatlistIndex = itemData.get(i).chatlistIndex;
-
- int chatId = itemDataSharedChats.getChatId(chatlistIndex);
- DcChat chat = dcContext.getChat(chatId);
- DcLot summary = itemDataSharedChats.getSummary(chatlistIndex, chat);
-
- conversationListItem.bind(DcHelper.getThreadRecord(context, summary, chat),
- itemDataSharedChats.getMsgId(chatlistIndex), summary, glideRequests,
- Collections.emptySet(), false);
- conversationListItem.setOnClickListener(view -> clickListener.onSharedChatClicked(chatId));
- }
- else if(holder.itemView instanceof ProfileStatusItem) {
- ProfileStatusItem item = (ProfileStatusItem) holder.itemView;
- item.setOnLongClickListener(view -> {clickListener.onStatusLongClicked(); return true;});
- item.set(itemData.get(i).label);
- }
- else if(holder.itemView instanceof ProfileSettingsItem) {
- int settingsId = itemData.get(i).settingsId;
- ProfileSettingsItem profileSettingsItem = (ProfileSettingsItem) holder.itemView;
- profileSettingsItem.setOnClickListener(view -> clickListener.onSettingsClicked(settingsId));
- profileSettingsItem.set(itemData.get(i).label, itemData.get(i).labelColor, itemData.get(i).iconLeft);
- }
- }
-
- @Override
- public int getItemViewType(int i) {
- return itemData.get(i).type;
- }
-
- public interface ItemClickListener {
- void onSettingsClicked(int settingsId);
- void onStatusLongClicked();
- void onSharedChatClicked(int chatId);
- void onMemberClicked(int contactId);
- void onMemberLongClicked(int contactId);
- }
-
- @Override
- public long getHeaderId(int position) {
- return getItemViewType(position);
- }
-
- @Override
- public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
- return new HeaderViewHolder(LayoutInflater.from(context).inflate(R.layout.contact_selection_list_divider, parent, false));
- }
-
- @Override
- public void onBindHeaderViewHolder(HeaderViewHolder viewHolder, int position) {
- String txt = "";
- switch(getItemViewType(position)) {
- case ItemData.CATEGORY_MEMBERS:
- if (isMailingList) {
- txt = context.getString(R.string.contacts_headline);
- } else if (isBroadcast) {
- txt = context.getResources().getQuantityString(R.plurals.n_recipients, (int) itemDataMemberCount, (int) itemDataMemberCount);
- } else {
- txt = context.getResources().getQuantityString(R.plurals.n_members, (int) itemDataMemberCount, (int) itemDataMemberCount);
- }
- break;
- case ItemData.CATEGORY_SHARED_CHATS:
- txt = context.getString(R.string.profile_shared_chats);
- break;
- case ItemData.CATEGORY_INFO:
- txt = context.getString(R.string.info);
- break;
- case ItemData.CATEGORY_SIGNATURE:
- txt = context.getString(R.string.pref_default_status_label);
- break;
- default:
- txt = context.getString(R.string.menu_settings);
- break;
- }
- viewHolder.textView.setText(txt);
- }
-
- public void toggleMemberSelection(int contactId) {
- if (!selectedMembers.remove(contactId)) {
- selectedMembers.add(contactId);
- }
- notifyDataSetChanged();
- }
-
- @NonNull
- public Collection getSelectedMembers() {
- return new HashSet<>(selectedMembers);
- }
-
- public int getSelectedMembersCount() {
- return selectedMembers.size();
- }
-
- @NonNull
- public String getStatusText() {
- return itemDataStatusText;
- }
-
- public void clearSelection() {
- selectedMembers.clear();
- notifyDataSetChanged();
- }
-
- public void changeData(@Nullable int[] memberList, @Nullable DcContact dcContact, @Nullable DcChatlist sharedChats, @Nullable DcChat dcChat) {
- itemData.clear();
- itemDataMemberCount = 0;
- itemDataSharedChats = null;
- itemDataStatusText = "";
- isMailingList = false;
- isBroadcast = false;
-
- if (memberList!=null) {
- itemDataMemberCount = memberList.length;
- if (dcChat != null) {
- if (dcChat.isBroadcast()) {
- isBroadcast = true;
- }
-
- if (dcChat.isMailingList()) {
- isMailingList = true;
- } else if (dcChat.canSend() && dcChat.isEncrypted()) {
- itemData.add(new ItemData(ItemData.CATEGORY_MEMBERS, DcContact.DC_CONTACT_ID_ADD_MEMBER, 0));
- if (!isBroadcast) {
- itemData.add(new ItemData(ItemData.CATEGORY_MEMBERS, DcContact.DC_CONTACT_ID_QR_INVITE, 0));
- }
- }
- }
-
- for (int value : memberList) {
- itemData.add(new ItemData(ItemData.CATEGORY_MEMBERS, value, 0));
- }
- }
- else if (sharedChats!=null && dcContact!=null) {
- boolean chatIsDeviceTalk = dcChat != null && dcChat.isDeviceTalk();
-
- if (!chatIsDeviceTalk) {
- int verifierId = dcContact.getVerifierId();
- if (verifierId != 0) {
- String verifiedInfo;
- if (verifierId == DcContact.DC_CONTACT_ID_SELF) {
- verifiedInfo = context.getString(R.string.verified_by_you);
- } else {
- verifiedInfo = context.getString(R.string.verified_by, dcContext.getContact(verifierId).getDisplayName());
- }
- itemData.add(new ItemData(ItemData.CATEGORY_INFO, INFO_VERIFIED, verifiedInfo, 0, R.drawable.ic_verified));
- }
-
- long lastSeenTimestamp = dcContact.getLastSeen();
- String lastSeenTxt;
- if (lastSeenTimestamp == 0) {
- lastSeenTxt = context.getString(R.string.last_seen_unknown);
- }
- else {
- lastSeenTxt = context.getString(R.string.last_seen_at, DateUtils.getExtendedTimeSpanString(context, lastSeenTimestamp));
- }
- itemData.add(new ItemData(ItemData.CATEGORY_INFO, INFO_LAST_SEEN, lastSeenTxt, 0, 0));
-
-
- itemData.add(new ItemData(ItemData.CATEGORY_INFO, INFO_SEND_MESSAGE_BUTTON, context.getString(R.string.send_message), R.color.delta_accent, 0));
- }
-
- itemDataStatusText = dcContact.getStatus();
- if (!itemDataStatusText.isEmpty()) {
- itemData.add(new ItemData(ItemData.CATEGORY_SIGNATURE, 0, itemDataStatusText, 0, 0));
- }
-
- itemDataSharedChats = sharedChats;
- if (!chatIsDeviceTalk) {
- int sharedChatsCnt = sharedChats.getCnt();
- for (int i = 0; i < sharedChatsCnt; i++) {
- itemData.add(new ItemData(ItemData.CATEGORY_SHARED_CHATS, 0, i));
- }
- }
- }
-
- notifyDataSetChanged();
- }
-}
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileSettingsItem.java b/src/main/java/org/thoughtcrime/securesms/ProfileSettingsItem.java
deleted file mode 100644
index 8b113c29d..000000000
--- a/src/main/java/org/thoughtcrime/securesms/ProfileSettingsItem.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.thoughtcrime.securesms;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.core.content.ContextCompat;
-
-import org.thoughtcrime.securesms.util.ResUtil;
-
-public class ProfileSettingsItem extends LinearLayout {
-
- private TextView labelView;
-
- public ProfileSettingsItem(Context context) {
- super(context);
- }
-
- public ProfileSettingsItem(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- labelView = findViewById(R.id.label);
- }
-
- public void set(String label, int labelColor, int iconLeft) {
- labelView.setText(label==null? "" : label);
- labelView.setCompoundDrawablesWithIntrinsicBounds(iconLeft, 0,0,0);
-
- // we need different color getters as `labelColor` is `R.color.name` while default is `R.attr.name`
- if (labelColor != 0) {
- labelView.setTextColor(ContextCompat.getColor(getContext(), labelColor));
- } else {
- labelView.setTextColor(ResUtil.getColor(getContext(), R.attr.emoji_text_color));
- }
- }
-}
diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileTextItem.java b/src/main/java/org/thoughtcrime/securesms/ProfileTextItem.java
new file mode 100644
index 000000000..d75082c04
--- /dev/null
+++ b/src/main/java/org/thoughtcrime/securesms/ProfileTextItem.java
@@ -0,0 +1,57 @@
+package org.thoughtcrime.securesms;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
+import androidx.core.graphics.drawable.DrawableCompat;
+
+import org.thoughtcrime.securesms.util.ResUtil;
+
+public class ProfileTextItem extends LinearLayout {
+
+ private TextView labelView;
+ private @Nullable TextView valueView;
+
+ public ProfileTextItem(Context context) {
+ super(context);
+ }
+
+ public ProfileTextItem(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ labelView = findViewById(R.id.label);
+ valueView = findViewById(R.id.value);
+ }
+
+ public void set(String label, int icon) {
+ labelView.setText(label);
+
+ if (icon != 0) {
+ Drawable orgDrawable = ContextCompat.getDrawable(getContext(), icon);
+ if (orgDrawable != null) {
+ Drawable drawable = orgDrawable.mutate(); // avoid global state modification and showing eg. app-icon tinted also elsewhere
+ drawable = DrawableCompat.wrap(drawable);
+ DrawableCompat.setTint(drawable, getResources().getColor(R.color.delta_accent));
+ labelView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
+ }
+ }
+ }
+
+ public void setValue(String value) {
+ if (valueView != null) {
+ valueView.setText(value);
+ valueView.setVisibility(View.VISIBLE);
+ }
+ }
+}
diff --git a/src/main/java/org/thoughtcrime/securesms/contacts/ContactSelectionListItem.java b/src/main/java/org/thoughtcrime/securesms/contacts/ContactSelectionListItem.java
index 83959ecad..943ee3901 100644
--- a/src/main/java/org/thoughtcrime/securesms/contacts/ContactSelectionListItem.java
+++ b/src/main/java/org/thoughtcrime/securesms/contacts/ContactSelectionListItem.java
@@ -163,9 +163,4 @@ public class ContactSelectionListItem extends LinearLayout implements RecipientM
});
}
}
-
- public void setNoHeaderPadding() {
- int paddinglr = getContext().getResources().getDimensionPixelSize(R.dimen.contact_list_normal_padding);
- setPadding(paddinglr, 0, paddinglr, 0);
- }
}
diff --git a/src/main/res/layout/all_media_activity.xml b/src/main/res/layout/all_media_activity.xml
new file mode 100644
index 000000000..d2c2e1a7a
--- /dev/null
+++ b/src/main/res/layout/all_media_activity.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/avatar_view.xml b/src/main/res/layout/avatar_view.xml
index f175f8c8b..cb28e84dc 100644
--- a/src/main/res/layout/avatar_view.xml
+++ b/src/main/res/layout/avatar_view.xml
@@ -25,6 +25,8 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/top_guideline"
app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintWidth_max="34dp"
+ app:layout_constraintHeight_max="34dp"
android:src="@drawable/ic_circle_status_online"
android:contentDescription="@null"
diff --git a/src/main/res/layout/contact_selection_list_item.xml b/src/main/res/layout/contact_selection_list_item.xml
index 0d2f5243f..2b01e070c 100644
--- a/src/main/res/layout/contact_selection_list_item.xml
+++ b/src/main/res/layout/contact_selection_list_item.xml
@@ -8,8 +8,8 @@
android:gravity="center_vertical"
android:focusable="true"
android:background="?attr/conversation_list_item_background"
- android:paddingLeft="24dp"
- android:paddingRight="24dp">
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp">
-
-
-
-
diff --git a/src/main/res/layout/profile_avatar_item.xml b/src/main/res/layout/profile_avatar_item.xml
new file mode 100644
index 000000000..ab7ed97bb
--- /dev/null
+++ b/src/main/res/layout/profile_avatar_item.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/profile_divider.xml b/src/main/res/layout/profile_divider.xml
new file mode 100644
index 000000000..a1458c441
--- /dev/null
+++ b/src/main/res/layout/profile_divider.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/src/main/res/layout/profile_settings_fragment.xml b/src/main/res/layout/profile_fragment.xml
similarity index 100%
rename from src/main/res/layout/profile_settings_fragment.xml
rename to src/main/res/layout/profile_fragment.xml
diff --git a/src/main/res/layout/profile_settings_item.xml b/src/main/res/layout/profile_settings_item.xml
deleted file mode 100644
index 1a57eec3a..000000000
--- a/src/main/res/layout/profile_settings_item.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/res/layout/profile_status_item.xml b/src/main/res/layout/profile_status_item.xml
index fbeace308..0dc5e6158 100644
--- a/src/main/res/layout/profile_status_item.xml
+++ b/src/main/res/layout/profile_status_item.xml
@@ -4,15 +4,18 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
- android:padding="16dp">
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp">
+ android:textColorLink="?attr/emoji_text_color"
+ android:background="?attr/contact_list_divider"/>
diff --git a/src/main/res/layout/profile_text_item.xml b/src/main/res/layout/profile_text_item.xml
new file mode 100644
index 000000000..bd7e2b9f2
--- /dev/null
+++ b/src/main/res/layout/profile_text_item.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
diff --git a/src/main/res/layout/profile_text_item_button.xml b/src/main/res/layout/profile_text_item_button.xml
new file mode 100644
index 000000000..027cf5180
--- /dev/null
+++ b/src/main/res/layout/profile_text_item_button.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/profile_text_item_small.xml b/src/main/res/layout/profile_text_item_small.xml
new file mode 100644
index 000000000..5db68843f
--- /dev/null
+++ b/src/main/res/layout/profile_text_item_small.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/src/main/res/menu/conversation.xml b/src/main/res/menu/conversation.xml
index d21b28434..2cbf9a2c9 100644
--- a/src/main/res/menu/conversation.xml
+++ b/src/main/res/menu/conversation.xml
@@ -25,10 +25,10 @@
android:visible="false"
app:showAsAction="always"/>
-
+ app:showAsAction="always" />
diff --git a/src/main/res/menu/profile_common.xml b/src/main/res/menu/profile_common.xml
index 2ae4969d3..7ec7330a6 100644
--- a/src/main/res/menu/profile_common.xml
+++ b/src/main/res/menu/profile_common.xml
@@ -8,7 +8,8 @@
+ android:icon="@drawable/ic_create_white_24dp"
+ app:showAsAction="always"/>