mirror of
https://github.com/deltachat/deltachat-android.git
synced 2025-10-03 09:49:21 +02:00
Merge branch 'main' into adb/pgp-contacts2
This commit is contained in:
commit
b9520c95ed
32 changed files with 1058 additions and 752 deletions
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
## Unreleased
|
## 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
|
* Clearer app lists by removing redundant "App" subtitle
|
||||||
* New button for quick access to the apps sent in current chat
|
* New button for quick access to the apps sent in current chat
|
||||||
* New icon for the in-chat apps button
|
* New icon for the in-chat apps button
|
||||||
|
|
|
@ -288,6 +288,10 @@
|
||||||
android:theme="@style/TextSecure.LightNoActionBar"
|
android:theme="@style/TextSecure.LightNoActionBar"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
|
||||||
|
<activity android:name=".AllMediaActivity"
|
||||||
|
android:theme="@style/TextSecure.LightNoActionBar"
|
||||||
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
|
||||||
<activity android:name=".DummyActivity"
|
<activity android:name=".DummyActivity"
|
||||||
android:theme="@android:style/Theme.NoDisplay"
|
android:theme="@android:style/Theme.NoDisplay"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
|
|
196
src/main/java/org/thoughtcrime/securesms/AllMediaActivity.java
Normal file
196
src/main/java/org/thoughtcrime/securesms/AllMediaActivity.java
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
package org.thoughtcrime.securesms;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
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.DcContext;
|
||||||
|
import com.b44t.messenger.DcEvent;
|
||||||
|
import com.b44t.messenger.DcMsg;
|
||||||
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||||
|
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||||
|
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||||
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class AllMediaActivity extends PassphraseRequiredActionBarActivity
|
||||||
|
implements DcEventCenter.DcEventDelegate
|
||||||
|
{
|
||||||
|
|
||||||
|
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||||
|
public static final String CONTACT_ID_EXTRA = "contact_id";
|
||||||
|
public static final String FORCE_GALLERY = "force_gallery";
|
||||||
|
|
||||||
|
static class TabData {
|
||||||
|
final int title;
|
||||||
|
final int type1;
|
||||||
|
final int type2;
|
||||||
|
final int type3;
|
||||||
|
TabData(int title, int type1, int type2, int type3) {
|
||||||
|
this.title = title;
|
||||||
|
this.type1 = type1;
|
||||||
|
this.type2 = type2;
|
||||||
|
this.type3 = type3;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private DcContext dcContext;
|
||||||
|
private int chatId;
|
||||||
|
private int contactId;
|
||||||
|
|
||||||
|
private final ArrayList<TabData> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
class ProfileDocumentsAdapter extends StickyHeaderGridAdapter {
|
class AllMediaDocumentsAdapter extends StickyHeaderGridAdapter {
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final ItemClickListener itemClickListener;
|
private final ItemClickListener itemClickListener;
|
||||||
|
@ -57,9 +57,9 @@ class ProfileDocumentsAdapter extends StickyHeaderGridAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileDocumentsAdapter(@NonNull Context context,
|
AllMediaDocumentsAdapter(@NonNull Context context,
|
||||||
BucketedThreadMedia media,
|
BucketedThreadMedia media,
|
||||||
ItemClickListener clickListener)
|
ItemClickListener clickListener)
|
||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.media = media;
|
this.media = media;
|
|
@ -33,21 +33,21 @@ import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ProfileDocumentsFragment
|
public class AllMediaDocumentsFragment
|
||||||
extends MessageSelectorFragment
|
extends MessageSelectorFragment
|
||||||
implements LoaderManager.LoaderCallbacks<BucketedThreadMediaLoader.BucketedThreadMedia>,
|
implements LoaderManager.LoaderCallbacks<BucketedThreadMediaLoader.BucketedThreadMedia>,
|
||||||
ProfileDocumentsAdapter.ItemClickListener
|
AllMediaDocumentsAdapter.ItemClickListener
|
||||||
{
|
{
|
||||||
public static final String CHAT_ID_EXTRA = "chat_id";
|
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||||
public static final String SHOW_AUDIO_EXTRA = "show_audio";
|
public static final String VIEWTYPE1 = "viewtype1";
|
||||||
public static final String SHOW_WEBXDC_EXTRA = "show_webxdc";
|
public static final String VIEWTYPE2 = "viewtype2";
|
||||||
|
|
||||||
protected TextView noMedia;
|
protected TextView noMedia;
|
||||||
protected RecyclerView recyclerView;
|
protected RecyclerView recyclerView;
|
||||||
private StickyHeaderGridLayoutManager gridManager;
|
private StickyHeaderGridLayoutManager gridManager;
|
||||||
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
|
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
|
||||||
private boolean showAudio;
|
private int viewtype1;
|
||||||
private boolean showWebxdc;
|
private int viewtype2;
|
||||||
|
|
||||||
protected int chatId;
|
protected int chatId;
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ public class ProfileDocumentsFragment
|
||||||
|
|
||||||
dcContext = DcHelper.getContext(getContext());
|
dcContext = DcHelper.getContext(getContext());
|
||||||
chatId = getArguments().getInt(CHAT_ID_EXTRA, -1);
|
chatId = getArguments().getInt(CHAT_ID_EXTRA, -1);
|
||||||
showAudio = getArguments().getBoolean(SHOW_AUDIO_EXTRA, false);
|
viewtype1 = getArguments().getInt(VIEWTYPE1, 0);
|
||||||
showWebxdc = getArguments().getBoolean(SHOW_WEBXDC_EXTRA, false);
|
viewtype2 = getArguments().getInt(VIEWTYPE2, 0);
|
||||||
|
|
||||||
getLoaderManager().initLoader(0, null, this);
|
getLoaderManager().initLoader(0, null, this);
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ public class ProfileDocumentsFragment
|
||||||
this.noMedia = ViewUtil.findById(view, R.id.no_documents);
|
this.noMedia = ViewUtil.findById(view, R.id.no_documents);
|
||||||
this.gridManager = new StickyHeaderGridLayoutManager(1);
|
this.gridManager = new StickyHeaderGridLayoutManager(1);
|
||||||
|
|
||||||
this.recyclerView.setAdapter(new ProfileDocumentsAdapter(getContext(),
|
this.recyclerView.setAdapter(new AllMediaDocumentsAdapter(getContext(),
|
||||||
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
|
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
|
||||||
this));
|
this));
|
||||||
this.recyclerView.setLayoutManager(gridManager);
|
this.recyclerView.setLayoutManager(gridManager);
|
||||||
|
@ -105,32 +105,26 @@ public class ProfileDocumentsFragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<BucketedThreadMediaLoader.BucketedThreadMedia> onCreateLoader(int i, Bundle bundle) {
|
public Loader<BucketedThreadMediaLoader.BucketedThreadMedia> onCreateLoader(int i, Bundle bundle) {
|
||||||
if (showAudio) {
|
return new BucketedThreadMediaLoader(getContext(), chatId, viewtype1, viewtype2, 0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> loader, BucketedThreadMediaLoader.BucketedThreadMedia bucketedThreadMedia) {
|
public void onLoadFinished(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> loader, BucketedThreadMediaLoader.BucketedThreadMedia bucketedThreadMedia) {
|
||||||
((ProfileDocumentsAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
|
((AllMediaDocumentsAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
|
||||||
((ProfileDocumentsAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
|
((AllMediaDocumentsAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
|
||||||
|
|
||||||
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
|
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
|
||||||
if (chatId == DC_CHAT_NO_CHAT) {
|
if (chatId == DC_CHAT_NO_CHAT) {
|
||||||
if (showWebxdc) {
|
if (viewtype1 == DcMsg.DC_MSG_WEBXDC) {
|
||||||
noMedia.setText(R.string.all_apps_empty_hint);
|
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);
|
noMedia.setText(R.string.all_files_empty_hint);
|
||||||
} else {
|
} else {
|
||||||
noMedia.setText(R.string.tab_all_media_empty_hint);
|
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);
|
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);
|
noMedia.setText(R.string.tab_webxdc_empty_hint);
|
||||||
}
|
}
|
||||||
getActivity().invalidateOptionsMenu();
|
getActivity().invalidateOptionsMenu();
|
||||||
|
@ -138,7 +132,7 @@ public class ProfileDocumentsFragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaderReset(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> cursorLoader) {
|
public void onLoaderReset(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> cursorLoader) {
|
||||||
((ProfileDocumentsAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
|
((AllMediaDocumentsAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -156,7 +150,7 @@ public class ProfileDocumentsFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMediaMultiSelectClick(@NonNull DcMsg mediaRecord) {
|
private void handleMediaMultiSelectClick(@NonNull DcMsg mediaRecord) {
|
||||||
ProfileDocumentsAdapter adapter = getListAdapter();
|
AllMediaDocumentsAdapter adapter = getListAdapter();
|
||||||
|
|
||||||
adapter.toggleSelection(mediaRecord);
|
adapter.toggleSelection(mediaRecord);
|
||||||
if (adapter.getSelectedMediaCount() == 0) {
|
if (adapter.getSelectedMediaCount() == 0) {
|
||||||
|
@ -188,7 +182,7 @@ public class ProfileDocumentsFragment
|
||||||
@Override
|
@Override
|
||||||
public void onMediaLongClicked(DcMsg mediaRecord) {
|
public void onMediaLongClicked(DcMsg mediaRecord) {
|
||||||
if (actionMode == null) {
|
if (actionMode == null) {
|
||||||
((ProfileDocumentsAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
|
((AllMediaDocumentsAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
|
||||||
|
|
||||||
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
|
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
|
||||||
}
|
}
|
||||||
|
@ -221,8 +215,8 @@ public class ProfileDocumentsFragment
|
||||||
menu.findItem(R.id.menu_add_to_home_screen).setVisible(webxdcApp);
|
menu.findItem(R.id.menu_add_to_home_screen).setVisible(webxdcApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProfileDocumentsAdapter getListAdapter() {
|
private AllMediaDocumentsAdapter getListAdapter() {
|
||||||
return (ProfileDocumentsAdapter) recyclerView.getAdapter();
|
return (AllMediaDocumentsAdapter) recyclerView.getAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ActionModeCallback implements ActionMode.Callback {
|
private class ActionModeCallback implements ActionMode.Callback {
|
|
@ -21,7 +21,7 @@ import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
class ProfileGalleryAdapter extends StickyHeaderGridAdapter {
|
class AllMediaGalleryAdapter extends StickyHeaderGridAdapter {
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final GlideRequests glideRequests;
|
private final GlideRequests glideRequests;
|
||||||
|
@ -50,10 +50,10 @@ class ProfileGalleryAdapter extends StickyHeaderGridAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileGalleryAdapter(@NonNull Context context,
|
AllMediaGalleryAdapter(@NonNull Context context,
|
||||||
@NonNull GlideRequests glideRequests,
|
@NonNull GlideRequests glideRequests,
|
||||||
BucketedThreadMedia media,
|
BucketedThreadMedia media,
|
||||||
ItemClickListener clickListener)
|
ItemClickListener clickListener)
|
||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.glideRequests = glideRequests;
|
this.glideRequests = glideRequests;
|
|
@ -35,10 +35,10 @@ import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ProfileGalleryFragment
|
public class AllMediaGalleryFragment
|
||||||
extends MessageSelectorFragment
|
extends MessageSelectorFragment
|
||||||
implements LoaderManager.LoaderCallbacks<BucketedThreadMediaLoader.BucketedThreadMedia>,
|
implements LoaderManager.LoaderCallbacks<BucketedThreadMediaLoader.BucketedThreadMedia>,
|
||||||
ProfileGalleryAdapter.ItemClickListener
|
AllMediaGalleryAdapter.ItemClickListener
|
||||||
{
|
{
|
||||||
public static final String CHAT_ID_EXTRA = "chat_id";
|
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.noMedia = ViewUtil.findById(view, R.id.no_images);
|
||||||
this.gridManager = new StickyHeaderGridLayoutManager(getCols());
|
this.gridManager = new StickyHeaderGridLayoutManager(getCols());
|
||||||
|
|
||||||
this.recyclerView.setAdapter(new ProfileGalleryAdapter(getContext(),
|
this.recyclerView.setAdapter(new AllMediaGalleryAdapter(getContext(),
|
||||||
GlideApp.with(this),
|
GlideApp.with(this),
|
||||||
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
|
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
|
||||||
this));
|
this));
|
||||||
|
@ -112,8 +112,8 @@ public class ProfileGalleryFragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> loader, BucketedThreadMediaLoader.BucketedThreadMedia bucketedThreadMedia) {
|
public void onLoadFinished(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> loader, BucketedThreadMediaLoader.BucketedThreadMedia bucketedThreadMedia) {
|
||||||
((ProfileGalleryAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
|
((AllMediaGalleryAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
|
||||||
((ProfileGalleryAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
|
((AllMediaGalleryAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
|
||||||
|
|
||||||
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
|
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
|
||||||
if (chatId == DC_CHAT_NO_CHAT) {
|
if (chatId == DC_CHAT_NO_CHAT) {
|
||||||
|
@ -124,7 +124,7 @@ public class ProfileGalleryFragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaderReset(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> cursorLoader) {
|
public void onLoaderReset(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> cursorLoader) {
|
||||||
((ProfileGalleryAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
|
((AllMediaGalleryAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -142,7 +142,7 @@ public class ProfileGalleryFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMediaMultiSelectClick(@NonNull DcMsg mediaRecord) {
|
private void handleMediaMultiSelectClick(@NonNull DcMsg mediaRecord) {
|
||||||
ProfileGalleryAdapter adapter = getListAdapter();
|
AllMediaGalleryAdapter adapter = getListAdapter();
|
||||||
|
|
||||||
adapter.toggleSelection(mediaRecord);
|
adapter.toggleSelection(mediaRecord);
|
||||||
if (adapter.getSelectedMediaCount() == 0) {
|
if (adapter.getSelectedMediaCount() == 0) {
|
||||||
|
@ -175,7 +175,7 @@ public class ProfileGalleryFragment
|
||||||
@Override
|
@Override
|
||||||
public void onMediaLongClicked(DcMsg mediaRecord) {
|
public void onMediaLongClicked(DcMsg mediaRecord) {
|
||||||
if (actionMode == null) {
|
if (actionMode == null) {
|
||||||
((ProfileGalleryAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
|
((AllMediaGalleryAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
|
||||||
recyclerView.getAdapter().notifyDataSetChanged();
|
recyclerView.getAdapter().notifyDataSetChanged();
|
||||||
|
|
||||||
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
|
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
|
||||||
|
@ -206,8 +206,8 @@ public class ProfileGalleryFragment
|
||||||
menu.findItem(R.id.menu_resend).setVisible(canResend);
|
menu.findItem(R.id.menu_resend).setVisible(canResend);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProfileGalleryAdapter getListAdapter() {
|
private AllMediaGalleryAdapter getListAdapter() {
|
||||||
return (ProfileGalleryAdapter) recyclerView.getAdapter();
|
return (AllMediaGalleryAdapter) recyclerView.getAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ActionModeCallback implements ActionMode.Callback {
|
private class ActionModeCallback implements ActionMode.Callback {
|
|
@ -529,8 +529,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
} else if (itemId == R.id.menu_show_map) {
|
} else if (itemId == R.id.menu_show_map) {
|
||||||
WebxdcActivity.openMaps(this, chatId);
|
WebxdcActivity.openMaps(this, chatId);
|
||||||
return true;
|
return true;
|
||||||
} else if (itemId == R.id.menu_show_apps) {
|
} else if (itemId == R.id.menu_all_media) {
|
||||||
handleProfile(true);
|
handleAllMedia();
|
||||||
return true;
|
return true;
|
||||||
} else if (itemId == R.id.menu_search_up) {
|
} else if (itemId == R.id.menu_search_up) {
|
||||||
handleMenuSearchNext(false);
|
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 intent = new Intent(this, ProfileActivity.class);
|
||||||
intent.putExtra(ProfileActivity.CHAT_ID_EXTRA, chatId);
|
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);
|
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() {
|
private void handleLeaveGroup() {
|
||||||
|
@ -872,7 +873,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
buttonToggle.getBackground().invalidateSelf();
|
buttonToggle.getBackground().invalidateSelf();
|
||||||
});
|
});
|
||||||
|
|
||||||
titleView.setOnClickListener(v -> handleProfile(false));
|
titleView.setOnClickListener(v -> handleProfile());
|
||||||
titleView.setOnBackClickedListener(view -> handleReturnToConversationList());
|
titleView.setOnBackClickedListener(view -> handleReturnToConversationList());
|
||||||
|
|
||||||
composeText.setOnKeyListener(composeKeyPressedListener);
|
composeText.setOnKeyListener(composeKeyPressedListener);
|
||||||
|
|
|
@ -449,7 +449,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||||
onBackPressed();
|
onBackPressed();
|
||||||
return true;
|
return true;
|
||||||
} else if (itemId == R.id.menu_all_media) {
|
} else if (itemId == R.id.menu_all_media) {
|
||||||
startActivity(new Intent(this, ProfileActivity.class));
|
startActivity(new Intent(this, AllMediaActivity.class));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,16 +262,16 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
else if(conversationRecipient.getAddress().isDcChat()) {
|
else if(conversationRecipient.getAddress().isDcChat()) {
|
||||||
Intent intent = new Intent(this, ProfileActivity.class);
|
Intent intent = new Intent(this, AllMediaActivity.class);
|
||||||
intent.putExtra(ProfileActivity.CHAT_ID_EXTRA, conversationRecipient.getAddress().getDcChatId());
|
intent.putExtra(AllMediaActivity.CHAT_ID_EXTRA, conversationRecipient.getAddress().getDcChatId());
|
||||||
intent.putExtra(ProfileActivity.FORCE_TAB_EXTRA, ProfileActivity.TAB_GALLERY);
|
intent.putExtra(AllMediaActivity.FORCE_GALLERY, true);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
else if(conversationRecipient.getAddress().isDcContact()) {
|
else if(conversationRecipient.getAddress().isDcContact()) {
|
||||||
Intent intent = new Intent(this, ProfileActivity.class);
|
Intent intent = new Intent(this, AllMediaActivity.class);
|
||||||
intent.putExtra(ProfileActivity.CONTACT_ID_EXTRA, conversationRecipient.getAddress().getDcContactId());
|
intent.putExtra(AllMediaActivity.CONTACT_ID_EXTRA, conversationRecipient.getAddress().getDcContactId());
|
||||||
intent.putExtra(ProfileActivity.FORCE_TAB_EXTRA, ProfileActivity.TAB_GALLERY);
|
intent.putExtra(AllMediaActivity.FORCE_GALLERY, true);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,13 @@ import android.view.ContextMenu;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.view.ActionMode;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
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.DcChat;
|
||||||
import com.b44t.messenger.DcContact;
|
import com.b44t.messenger.DcContact;
|
||||||
|
@ -31,11 +25,9 @@ import com.b44t.messenger.DcContext;
|
||||||
import com.b44t.messenger.DcEvent;
|
import com.b44t.messenger.DcEvent;
|
||||||
import com.b44t.messenger.rpc.Rpc;
|
import com.b44t.messenger.rpc.Rpc;
|
||||||
import com.b44t.messenger.rpc.RpcException;
|
import com.b44t.messenger.rpc.RpcException;
|
||||||
import com.google.android.material.tabs.TabLayout;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
|
||||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||||
import org.thoughtcrime.securesms.util.Prefs;
|
import org.thoughtcrime.securesms.util.Prefs;
|
||||||
import org.thoughtcrime.securesms.util.RelayUtil;
|
import org.thoughtcrime.securesms.util.RelayUtil;
|
||||||
|
@ -43,7 +35,6 @@ import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
implements DcEventCenter.DcEventDelegate
|
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 CHAT_ID_EXTRA = "chat_id";
|
||||||
public static final String CONTACT_ID_EXTRA = "contact_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;
|
private static final int REQUEST_CODE_PICK_RINGTONE = 1;
|
||||||
|
|
||||||
|
@ -72,13 +53,8 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
private boolean chatIsMailingList;
|
private boolean chatIsMailingList;
|
||||||
private boolean chatIsBroadcast;
|
private boolean chatIsBroadcast;
|
||||||
private int contactId;
|
private int contactId;
|
||||||
private boolean fromChat;
|
private boolean contactIsBot;
|
||||||
|
private Toolbar toolbar;
|
||||||
private final ArrayList<Integer> tabs = new ArrayList<>();
|
|
||||||
private Toolbar toolbar;
|
|
||||||
private ConversationTitleView titleView;
|
|
||||||
private TabLayout tabLayout;
|
|
||||||
private ViewPager viewPager;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPreCreate() {
|
protected void onPreCreate() {
|
||||||
|
@ -97,38 +73,27 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
setSupportActionBar(this.toolbar);
|
setSupportActionBar(this.toolbar);
|
||||||
ActionBar supportActionBar = getSupportActionBar();
|
ActionBar supportActionBar = getSupportActionBar();
|
||||||
if (supportActionBar != null) {
|
if (supportActionBar != null) {
|
||||||
if (isGlobalProfile()) {
|
String title = getString(R.string.profile);
|
||||||
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
if (chatIsMailingList) {
|
||||||
supportActionBar.setHomeActionContentDescription(getString(R.string.back));
|
title = getString(R.string.mailing_list);
|
||||||
} else {
|
} else if (chatIsBroadcast) {
|
||||||
supportActionBar.setDisplayHomeAsUpEnabled(false);
|
title = getString(R.string.broadcast_list);
|
||||||
supportActionBar.setCustomView(R.layout.conversation_title_view);
|
} else if (chatIsMultiUser) {
|
||||||
supportActionBar.setDisplayShowCustomEnabled(true);
|
title = getString(R.string.tab_group);
|
||||||
supportActionBar.setDisplayShowTitleEnabled(false);
|
} else if (contactIsBot) {
|
||||||
Toolbar parent = (Toolbar) supportActionBar.getCustomView().getParent();
|
title = getString(R.string.bot);
|
||||||
parent.setPadding(0,0,0,0);
|
} else if (!chatIsDeviceTalk && !isSelfProfile()) {
|
||||||
parent.setContentInsetsAbsolute(0,0);
|
title = getString(R.string.tab_contact);
|
||||||
|
|
||||||
titleView = (ConversationTitleView) supportActionBar.getCustomView();
|
|
||||||
titleView.setOnBackClickedListener(view -> onBackPressed());
|
|
||||||
titleView.setOnClickListener(view -> onEnlargeAvatar());
|
|
||||||
if (isContactProfile() && !isSelfProfile() && !chatIsDeviceTalk) {
|
|
||||||
titleView.registerForContextMenu(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
|
supportActionBar.setTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateToolbar();
|
Bundle args = new Bundle();
|
||||||
|
args.putInt(ProfileFragment.CHAT_ID_EXTRA, (chatId == 0) ? -1 : chatId);
|
||||||
this.tabLayout.setupWithViewPager(viewPager);
|
args.putInt(ProfileFragment.CONTACT_ID_EXTRA, (contactId == 0) ? -1 : contactId);
|
||||||
this.viewPager.setAdapter(new ProfilePagerAdapter(getSupportFragmentManager()));
|
initFragment(R.id.fragment_container, new ProfileFragment(), args);
|
||||||
int forceTab = getIntent().getIntExtra(FORCE_TAB_EXTRA, -1);
|
|
||||||
if (forceTab != -1) {
|
|
||||||
int forceIndex = tabs.indexOf(forceTab);
|
|
||||||
if (forceIndex != -1) {
|
|
||||||
this.viewPager.setCurrentItem(forceIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DcEventCenter eventCenter = DcHelper.getEventCenter(this);
|
DcEventCenter eventCenter = DcHelper.getEventCenter(this);
|
||||||
eventCenter.addObserver(DcContext.DC_EVENT_CHAT_MODIFIED, this);
|
eventCenter.addObserver(DcContext.DC_EVENT_CHAT_MODIFIED, this);
|
||||||
|
@ -137,7 +102,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
if (!isSelfProfile() && !isGlobalProfile()) {
|
if (!isSelfProfile()) {
|
||||||
getMenuInflater().inflate(R.menu.profile_common, menu);
|
getMenuInflater().inflate(R.menu.profile_common, menu);
|
||||||
boolean canReceive = true;
|
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.show_encr_info).setVisible(false);
|
||||||
menu.findItem(R.id.share).setVisible(false);
|
menu.findItem(R.id.share).setVisible(false);
|
||||||
} else if (chatIsMultiUser) {
|
} else if (chatIsMultiUser) {
|
||||||
|
menu.findItem(R.id.edit_name).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||||
if (chatIsBroadcast) {
|
if (chatIsBroadcast) {
|
||||||
canReceive = false;
|
canReceive = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -207,21 +173,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
getMenuInflater().inflate(R.menu.profile_title_context, menu);
|
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
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
DcHelper.getEventCenter(this).removeObservers(this);
|
DcHelper.getEventCenter(this).removeObservers(this);
|
||||||
|
@ -230,22 +181,24 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(@NonNull DcEvent event) {
|
public void handleEvent(@NonNull DcEvent event) {
|
||||||
updateToolbar();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeResources() {
|
private void initializeResources() {
|
||||||
chatId = getIntent().getIntExtra(CHAT_ID_EXTRA, 0);
|
chatId = getIntent().getIntExtra(CHAT_ID_EXTRA, 0);
|
||||||
contactId = getIntent().getIntExtra(CONTACT_ID_EXTRA, 0);
|
contactId = getIntent().getIntExtra(CONTACT_ID_EXTRA, 0);
|
||||||
|
contactIsBot = false;
|
||||||
chatIsMultiUser = false;
|
chatIsMultiUser = false;
|
||||||
chatIsDeviceTalk = false;
|
chatIsDeviceTalk = false;
|
||||||
chatIsMailingList= false;
|
chatIsMailingList= false;
|
||||||
chatIsBroadcast = false;
|
chatIsBroadcast = false;
|
||||||
fromChat = getIntent().getBooleanExtra(FROM_CHAT, false);
|
|
||||||
|
|
||||||
if (contactId!=0) {
|
if (contactId!=0) {
|
||||||
|
DcContact dcContact = dcContext.getContact(contactId);
|
||||||
chatId = dcContext.getChatIdByContactId(contactId);
|
chatId = dcContext.getChatIdByContactId(contactId);
|
||||||
|
contactIsBot = dcContact.isBot();
|
||||||
}
|
}
|
||||||
else if(chatId!=0) {
|
|
||||||
|
if(chatId!=0) {
|
||||||
DcChat dcChat = dcContext.getChat(chatId);
|
DcChat dcChat = dcContext.getChat(chatId);
|
||||||
chatIsMultiUser = dcChat.isMultiUser();
|
chatIsMultiUser = dcChat.isMultiUser();
|
||||||
chatIsDeviceTalk = dcChat.isDeviceTalk();
|
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.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() {
|
private boolean isContactProfile() {
|
||||||
|
@ -300,124 +222,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
return isContactProfile() && contactId==DcContact.DC_CONTACT_ID_SELF;
|
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
|
// handle events
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
|
@ -427,7 +231,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
|
|
||||||
int itemId = item.getItemId();
|
int itemId = item.getItemId();
|
||||||
if (itemId == android.R.id.home) {
|
if (itemId == android.R.id.home) {
|
||||||
backPressed = true;
|
|
||||||
finish();
|
finish();
|
||||||
return true;
|
return true;
|
||||||
} else if (itemId == R.id.menu_mute_notifications) {
|
} else if (itemId == R.id.menu_mute_notifications) {
|
||||||
|
@ -505,7 +308,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onEnlargeAvatar() {
|
public void onEnlargeAvatar() {
|
||||||
String profileImagePath;
|
String profileImagePath;
|
||||||
String title;
|
String title;
|
||||||
Uri profileImageUri;
|
Uri profileImageUri;
|
||||||
|
@ -530,7 +333,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||||
intent.putExtra(MediaPreviewActivity.ACTIVITY_TITLE_EXTRA, title);
|
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
|
intent.putExtra(MediaPreviewActivity.EDIT_AVATAR_CHAT_ID, chatIsMultiUser ? chatId : 0); // shows edit-button, might be 0 for a contact-profile
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
} else {
|
} else if (chatIsMultiUser){
|
||||||
onEditName();
|
onEditName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
372
src/main/java/org/thoughtcrime/securesms/ProfileAdapter.java
Normal file
372
src/main/java/org/thoughtcrime/securesms/ProfileAdapter.java
Normal file
|
@ -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> itemData = new ArrayList<>();
|
||||||
|
private DcChatlist itemDataSharedChats;
|
||||||
|
private String itemDataStatusText;
|
||||||
|
private boolean isBroadcast;
|
||||||
|
private int memberCount;
|
||||||
|
private final Set<Integer> 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<Integer> 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 + "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
112
src/main/java/org/thoughtcrime/securesms/ProfileAvatarItem.java
Normal file
112
src/main/java/org/thoughtcrime/securesms/ProfileAvatarItem.java
Normal file
|
@ -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());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,6 @@ import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||||
import org.thoughtcrime.securesms.qr.QrShowActivity;
|
import org.thoughtcrime.securesms.qr.QrShowActivity;
|
||||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
|
@ -39,16 +38,15 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ProfileSettingsFragment extends Fragment
|
public class ProfileFragment extends Fragment
|
||||||
implements ProfileSettingsAdapter.ItemClickListener, DcEventCenter.DcEventDelegate {
|
implements ProfileAdapter.ItemClickListener, DcEventCenter.DcEventDelegate {
|
||||||
|
|
||||||
public static final String CHAT_ID_EXTRA = "chat_id";
|
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||||
public static final String CONTACT_ID_EXTRA = "contact_id";
|
public static final String CONTACT_ID_EXTRA = "contact_id";
|
||||||
|
|
||||||
private static final int REQUEST_CODE_PICK_CONTACT = 2;
|
private static final int REQUEST_CODE_PICK_CONTACT = 2;
|
||||||
|
|
||||||
private StickyHeaderDecoration listDecoration;
|
private ProfileAdapter adapter;
|
||||||
private ProfileSettingsAdapter adapter;
|
|
||||||
private ActionMode actionMode;
|
private ActionMode actionMode;
|
||||||
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
|
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
|
||||||
|
|
||||||
|
@ -57,10 +55,6 @@ public class ProfileSettingsFragment extends Fragment
|
||||||
protected int chatId;
|
protected int chatId;
|
||||||
private int contactId;
|
private int contactId;
|
||||||
|
|
||||||
protected ActionMode getActionMode() {
|
|
||||||
return actionMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle bundle) {
|
public void onCreate(Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
|
@ -72,14 +66,12 @@ public class ProfileSettingsFragment extends Fragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.profile_settings_fragment, container, false);
|
View view = inflater.inflate(R.layout.profile_fragment, container, false);
|
||||||
adapter = new ProfileSettingsAdapter(requireContext(), GlideApp.with(this), this);
|
adapter = new ProfileAdapter(requireContext(), GlideApp.with(this), this);
|
||||||
|
|
||||||
RecyclerView list = ViewUtil.findById(view, R.id.recycler_view);
|
RecyclerView list = ViewUtil.findById(view, R.id.recycler_view);
|
||||||
list.setAdapter(adapter);
|
list.setAdapter(adapter);
|
||||||
list.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
|
list.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
|
||||||
listDecoration = new StickyHeaderDecoration(adapter, false, true);
|
|
||||||
list.addItemDecoration(listDecoration);
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
@ -97,12 +89,6 @@ public class ProfileSettingsFragment extends Fragment
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
|
||||||
super.onConfigurationChanged(newConfig);
|
|
||||||
listDecoration.onConfigurationChanged(newConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(@NonNull DcEvent event) {
|
public void handleEvent(@NonNull DcEvent event) {
|
||||||
update();
|
update();
|
||||||
|
@ -121,12 +107,11 @@ public class ProfileSettingsFragment extends Fragment
|
||||||
if(dcChat!=null && dcChat.isMultiUser()) {
|
if(dcChat!=null && dcChat.isMultiUser()) {
|
||||||
memberList = dcContext.getChatContacts(chatId);
|
memberList = dcContext.getChatContacts(chatId);
|
||||||
}
|
}
|
||||||
else if(contactId>0) {
|
else if(contactId>0 && contactId!=DcContact.DC_CONTACT_ID_SELF) {
|
||||||
sharedChats = dcContext.getChatlist(0, null, contactId);
|
sharedChats = dcContext.getChatlist(0, null, contactId);
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.changeData(memberList, dcContact, sharedChats, dcChat);
|
adapter.changeData(memberList, dcContact, sharedChats, dcChat);
|
||||||
listDecoration.invalidateLayouts();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,10 +121,17 @@ public class ProfileSettingsFragment extends Fragment
|
||||||
@Override
|
@Override
|
||||||
public void onSettingsClicked(int settingsId) {
|
public void onSettingsClicked(int settingsId) {
|
||||||
switch(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();
|
onSendMessage();
|
||||||
break;
|
break;
|
||||||
case ProfileSettingsAdapter.INFO_VERIFIED:
|
case ProfileAdapter.ITEM_INTRODUCED_BY:
|
||||||
onVerifiedByClicked();
|
onVerifiedByClicked();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -202,6 +194,12 @@ public class ProfileSettingsFragment extends Fragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAvatarClicked() {
|
||||||
|
ProfileActivity activity = (ProfileActivity)getActivity();
|
||||||
|
activity.onEnlargeAvatar();
|
||||||
|
}
|
||||||
|
|
||||||
public void onAddMember() {
|
public void onAddMember() {
|
||||||
DcChat dcChat = dcContext.getChat(chatId);
|
DcChat dcChat = dcContext.getChat(chatId);
|
||||||
Intent intent = new Intent(getContext(), ContactMultiSelectionActivity.class);
|
Intent intent = new Intent(getContext(), ContactMultiSelectionActivity.class);
|
|
@ -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<ProfileSettingsAdapter.HeaderViewHolder>
|
|
||||||
{
|
|
||||||
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> itemData = new ArrayList<>();
|
|
||||||
private int itemDataMemberCount;
|
|
||||||
private DcChatlist itemDataSharedChats;
|
|
||||||
private String itemDataStatusText;
|
|
||||||
private boolean isMailingList;
|
|
||||||
private boolean isBroadcast;
|
|
||||||
private final Set<Integer> 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<Integer> 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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
46
src/main/res/layout/all_media_activity.xml
Normal file
46
src/main/res/layout/all_media_activity.xml
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:minHeight="?attr/actionBarSize"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
app:contentInsetStart="14dp"
|
||||||
|
app:contentInsetLeft="14dp"
|
||||||
|
android:elevation="4dp"
|
||||||
|
android:theme="?attr/actionBarStyle"/>
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tab_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:elevation="4dp"
|
||||||
|
android:layout_gravity="top"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
app:tabMode="scrollable"
|
||||||
|
app:tabPaddingStart="8dp"
|
||||||
|
app:tabPaddingEnd="8dp"
|
||||||
|
app:tabBackground="?attr/colorPrimary"
|
||||||
|
app:tabIndicatorColor="@color/white"
|
||||||
|
app:tabTextColor="@color/gray10"
|
||||||
|
app:tabSelectedTextColor="@color/white"/>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.viewpager.widget.ViewPager
|
||||||
|
android:id="@+id/pager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -25,6 +25,8 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/top_guideline"
|
app:layout_constraintTop_toTopOf="@+id/top_guideline"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintWidth_max="34dp"
|
||||||
|
app:layout_constraintHeight_max="34dp"
|
||||||
|
|
||||||
android:src="@drawable/ic_circle_status_online"
|
android:src="@drawable/ic_circle_status_online"
|
||||||
android:contentDescription="@null"
|
android:contentDescription="@null"
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:background="?attr/conversation_list_item_background"
|
android:background="?attr/conversation_list_item_background"
|
||||||
android:paddingLeft="24dp"
|
android:paddingLeft="16dp"
|
||||||
android:paddingRight="24dp">
|
android:paddingRight="16dp">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.AvatarView
|
<org.thoughtcrime.securesms.components.AvatarView
|
||||||
android:id="@+id/avatar"
|
android:id="@+id/avatar"
|
||||||
|
|
|
@ -19,26 +19,10 @@
|
||||||
app:contentInsetLeft="14dp"
|
app:contentInsetLeft="14dp"
|
||||||
android:elevation="4dp"
|
android:elevation="4dp"
|
||||||
android:theme="?attr/actionBarStyle"/>
|
android:theme="?attr/actionBarStyle"/>
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
|
||||||
android:id="@+id/tab_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:elevation="4dp"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
android:background="?attr/colorPrimary"
|
|
||||||
app:tabMode="scrollable"
|
|
||||||
app:tabPaddingStart="8dp"
|
|
||||||
app:tabPaddingEnd="8dp"
|
|
||||||
app:tabBackground="?attr/colorPrimary"
|
|
||||||
app:tabIndicatorColor="@color/white"
|
|
||||||
app:tabTextColor="@color/gray10"
|
|
||||||
app:tabSelectedTextColor="@color/white"/>
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<FrameLayout
|
||||||
android:id="@+id/pager"
|
android:id="@+id/fragment_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
||||||
|
|
57
src/main/res/layout/profile_avatar_item.xml
Normal file
57
src/main/res/layout/profile_avatar_item.xml
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<org.thoughtcrime.securesms.ProfileAvatarItem
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:focusable="true"
|
||||||
|
android:background="?attr/conversation_list_item_background"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:layout_marginBottom="16dp">
|
||||||
|
|
||||||
|
<LinearLayout android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.AvatarView
|
||||||
|
android:id="@+id/avatar"
|
||||||
|
android:layout_width="152dp"
|
||||||
|
android:layout_height="152dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginBottom="5dp"/>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawablePadding="5dp"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textColor="?attr/conversation_list_item_contact_color"
|
||||||
|
tools:text="Some Group" />
|
||||||
|
<!-- Attention: Using android:maxLines="1", if the name is an emoji followed by a
|
||||||
|
long word and the chat is muted, then the long word is not shown at all
|
||||||
|
(instead of using `…`). That's why we use android:singleLine="true" -->
|
||||||
|
|
||||||
|
<TextView android:id="@+id/subtitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="?attr/conversation_list_item_contact_color"
|
||||||
|
tools:text="3 members" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</org.thoughtcrime.securesms.ProfileAvatarItem>
|
14
src/main/res/layout/profile_divider.xml
Normal file
14
src/main/res/layout/profile_divider.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<View android:id="@+id/label"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="3dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:background="?attr/contact_list_divider"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<org.thoughtcrime.securesms.ProfileSettingsItem
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?attr/conversation_list_item_background"
|
|
||||||
android:focusable="true"
|
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:drawablePadding="7dp"
|
|
||||||
android:gravity="start|center_vertical"
|
|
||||||
android:textColor="?attr/emoji_text_color"
|
|
||||||
android:textSize="16sp"/>
|
|
||||||
</org.thoughtcrime.securesms.ProfileSettingsItem>
|
|
|
@ -4,15 +4,18 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:padding="16dp">
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:padding="16dp"
|
||||||
android:id="@+id/status_text"
|
android:id="@+id/status_text"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="start|center_vertical"
|
android:gravity="start|center_vertical"
|
||||||
style="@style/Signal.Text.Body"
|
style="@style/Signal.Text.Body"
|
||||||
android:textColor="?attr/emoji_text_color"
|
android:textColor="?attr/emoji_text_color"
|
||||||
android:textColorLink="?attr/emoji_text_color"/>
|
android:textColorLink="?attr/emoji_text_color"
|
||||||
|
android:background="?attr/contact_list_divider"/>
|
||||||
|
|
||||||
</org.thoughtcrime.securesms.ProfileStatusItem>
|
</org.thoughtcrime.securesms.ProfileStatusItem>
|
||||||
|
|
19
src/main/res/layout/profile_text_item.xml
Normal file
19
src/main/res/layout/profile_text_item.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<org.thoughtcrime.securesms.ProfileTextItem
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/conversation_list_item_background"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
android:textColor="?attr/emoji_text_color"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
</org.thoughtcrime.securesms.ProfileTextItem>
|
34
src/main/res/layout/profile_text_item_button.xml
Normal file
34
src/main/res/layout/profile_text_item_button.xml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<org.thoughtcrime.securesms.ProfileTextItem
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/conversation_list_item_background"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<LinearLayout android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
android:textColor="@color/delta_accent"
|
||||||
|
android:drawablePadding="5dp"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/value"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="end|center_vertical"
|
||||||
|
style="@style/Signal.Text.Caption"
|
||||||
|
android:textColor="?attr/conversation_list_item_date_color"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</org.thoughtcrime.securesms.ProfileTextItem>
|
22
src/main/res/layout/profile_text_item_small.xml
Normal file
22
src/main/res/layout/profile_text_item_small.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<org.thoughtcrime.securesms.ProfileTextItem
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/conversation_list_item_background"
|
||||||
|
android:focusable="true"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="?attr/conversation_list_item_contact_color" />
|
||||||
|
|
||||||
|
</org.thoughtcrime.securesms.ProfileTextItem>
|
|
@ -25,10 +25,10 @@
|
||||||
android:visible="false"
|
android:visible="false"
|
||||||
app:showAsAction="always"/>
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
<item android:id="@+id/menu_show_apps"
|
<item android:id="@+id/menu_all_media"
|
||||||
android:title="@string/webxdc_apps"
|
android:title="@string/apps_and_media"
|
||||||
android:icon="@drawable/ic_apps_24"
|
android:icon="@drawable/ic_apps_24"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="always" />
|
||||||
|
|
||||||
<item android:id="@+id/menu_ephemeral_messages"
|
<item android:id="@+id/menu_ephemeral_messages"
|
||||||
android:title="@string/ephemeral_messages" />
|
android:title="@string/ephemeral_messages" />
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
|
|
||||||
<item android:title="@string/global_menu_edit_desktop"
|
<item android:title="@string/global_menu_edit_desktop"
|
||||||
android:id="@+id/edit_name"
|
android:id="@+id/edit_name"
|
||||||
app:showAsAction="never"/>
|
android:icon="@drawable/ic_create_white_24dp"
|
||||||
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
<item android:title="@string/menu_mute"
|
<item android:title="@string/menu_mute"
|
||||||
android:id="@+id/menu_mute_notifications"
|
android:id="@+id/menu_mute_notifications"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue