mirror of
https://github.com/deltachat/deltachat-android.git
synced 2025-10-03 09:49:21 +02:00
re-focus profile (#3792)
* duplicate ProfileActivity to AllMediaActivity
* update CHANGELOG
* remove profile stuff from AllMediaActivity
* remove media stuff from ProfileActivity
* remove TabLayout from ProfileActivity
* decouple header from viewType
* easier name editing
* add link to 'apps & media'
* move bio up
* move 'send message' up
* prepare avatar/title/subtitle
* set title
* set subtitle to member count
* add address to profile
* rename ProfileSettings* to just Profile*
* set avatar
* use avatar view
* adaptive avatar cell height
* no endless growing of online-indicator
* simplify
* handle tap on avatars
* rename Profile* to AllMedia*
* set title accordingly
* move 'last seen' up
* edit name by tapping
* Revert "edit name by tapping"
This reverts commit 6727b16830
.
Reason is that it introduces uncertainity what happens if the name is tapped -
we do not want to nudge ppl to edit the group name in a similar way.
we may revert this revert,
but for now, let's see if the icon atop isn't sufficient.
* add media count
* space below avatar
* refactor allmedia viewtypes
* select the first tab that has content
* format footer
* remove unused headers
* space above header
* add dividers
* tweak some spacings
* tap on avatar only for enlarge/set avatar
* immediate view of first tap
* tweak value display
* add icons to buttons
* tweak paddings
* no address for self-talk and device-chat
* use signature background for less cluttered UI
* avoid global state modification and showing eg. app-icon tinted also elsewhere
* tweak sizes
* move introduced-by/server down. these information become less important the more chats you have with the contact - and otherwise just clutter UI
* update CHANGELOG
* typo
* use more normal font and spacing for footer
* open "media" deterministically
remove the smart forwarding to "tab with content",
which results in unclear behaviour.
also, we want to push for apps,
which is also the thing that really changes.
when searching for an image, another tap is fine.
This commit is contained in:
parent
9caf94d035
commit
4663299951
32 changed files with 1058 additions and 752 deletions
|
@ -2,6 +2,8 @@
|
|||
|
||||
## Unreleased
|
||||
|
||||
* Profiles focus on recognizing contacts
|
||||
* See the number of media directly in the profile, no need to tap around
|
||||
* Clearer app lists by removing redundant "App" subtitle
|
||||
* New button for quick access to the apps sent in current chat
|
||||
* New icon for the in-chat apps button
|
||||
|
|
|
@ -288,6 +288,10 @@
|
|||
android:theme="@style/TextSecure.LightNoActionBar"
|
||||
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"
|
||||
android:theme="@android:style/Theme.NoDisplay"
|
||||
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.Set;
|
||||
|
||||
class ProfileDocumentsAdapter extends StickyHeaderGridAdapter {
|
||||
class AllMediaDocumentsAdapter extends StickyHeaderGridAdapter {
|
||||
|
||||
private final Context context;
|
||||
private final ItemClickListener itemClickListener;
|
||||
|
@ -57,9 +57,9 @@ class ProfileDocumentsAdapter extends StickyHeaderGridAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
ProfileDocumentsAdapter(@NonNull Context context,
|
||||
BucketedThreadMedia media,
|
||||
ItemClickListener clickListener)
|
||||
AllMediaDocumentsAdapter(@NonNull Context context,
|
||||
BucketedThreadMedia media,
|
||||
ItemClickListener clickListener)
|
||||
{
|
||||
this.context = context;
|
||||
this.media = media;
|
|
@ -33,21 +33,21 @@ import org.thoughtcrime.securesms.util.ViewUtil;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
public class ProfileDocumentsFragment
|
||||
public class AllMediaDocumentsFragment
|
||||
extends MessageSelectorFragment
|
||||
implements LoaderManager.LoaderCallbacks<BucketedThreadMediaLoader.BucketedThreadMedia>,
|
||||
ProfileDocumentsAdapter.ItemClickListener
|
||||
AllMediaDocumentsAdapter.ItemClickListener
|
||||
{
|
||||
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||
public static final String SHOW_AUDIO_EXTRA = "show_audio";
|
||||
public static final String SHOW_WEBXDC_EXTRA = "show_webxdc";
|
||||
public static final String VIEWTYPE1 = "viewtype1";
|
||||
public static final String VIEWTYPE2 = "viewtype2";
|
||||
|
||||
protected TextView noMedia;
|
||||
protected RecyclerView recyclerView;
|
||||
private StickyHeaderGridLayoutManager gridManager;
|
||||
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
|
||||
private boolean showAudio;
|
||||
private boolean showWebxdc;
|
||||
private int viewtype1;
|
||||
private int viewtype2;
|
||||
|
||||
protected int chatId;
|
||||
|
||||
|
@ -57,8 +57,8 @@ public class ProfileDocumentsFragment
|
|||
|
||||
dcContext = DcHelper.getContext(getContext());
|
||||
chatId = getArguments().getInt(CHAT_ID_EXTRA, -1);
|
||||
showAudio = getArguments().getBoolean(SHOW_AUDIO_EXTRA, false);
|
||||
showWebxdc = getArguments().getBoolean(SHOW_WEBXDC_EXTRA, false);
|
||||
viewtype1 = getArguments().getInt(VIEWTYPE1, 0);
|
||||
viewtype2 = getArguments().getInt(VIEWTYPE2, 0);
|
||||
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public class ProfileDocumentsFragment
|
|||
this.noMedia = ViewUtil.findById(view, R.id.no_documents);
|
||||
this.gridManager = new StickyHeaderGridLayoutManager(1);
|
||||
|
||||
this.recyclerView.setAdapter(new ProfileDocumentsAdapter(getContext(),
|
||||
this.recyclerView.setAdapter(new AllMediaDocumentsAdapter(getContext(),
|
||||
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
|
||||
this));
|
||||
this.recyclerView.setLayoutManager(gridManager);
|
||||
|
@ -105,32 +105,26 @@ public class ProfileDocumentsFragment
|
|||
|
||||
@Override
|
||||
public Loader<BucketedThreadMediaLoader.BucketedThreadMedia> onCreateLoader(int i, Bundle bundle) {
|
||||
if (showAudio) {
|
||||
return new BucketedThreadMediaLoader(getContext(), chatId, DcMsg.DC_MSG_AUDIO, DcMsg.DC_MSG_VOICE, 0);
|
||||
} else if (showWebxdc) {
|
||||
return new BucketedThreadMediaLoader(getContext(), chatId, DcMsg.DC_MSG_WEBXDC, 0, 0);
|
||||
} else {
|
||||
return new BucketedThreadMediaLoader(getContext(), chatId, DcMsg.DC_MSG_FILE, 0, 0);
|
||||
}
|
||||
return new BucketedThreadMediaLoader(getContext(), chatId, viewtype1, viewtype2, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> loader, BucketedThreadMediaLoader.BucketedThreadMedia bucketedThreadMedia) {
|
||||
((ProfileDocumentsAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
|
||||
((ProfileDocumentsAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
|
||||
((AllMediaDocumentsAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
|
||||
((AllMediaDocumentsAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
|
||||
|
||||
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
|
||||
if (chatId == DC_CHAT_NO_CHAT) {
|
||||
if (showWebxdc) {
|
||||
if (viewtype1 == DcMsg.DC_MSG_WEBXDC) {
|
||||
noMedia.setText(R.string.all_apps_empty_hint);
|
||||
} else if (!showAudio){
|
||||
} else if (viewtype1 == DcMsg.DC_MSG_FILE){
|
||||
noMedia.setText(R.string.all_files_empty_hint);
|
||||
} else {
|
||||
noMedia.setText(R.string.tab_all_media_empty_hint);
|
||||
}
|
||||
} else if (showAudio) {
|
||||
} else if (viewtype1 == DcMsg.DC_MSG_AUDIO) {
|
||||
noMedia.setText(R.string.tab_audio_empty_hint);
|
||||
} else if (showWebxdc) {
|
||||
} else if (viewtype1 == DcMsg.DC_MSG_WEBXDC) {
|
||||
noMedia.setText(R.string.tab_webxdc_empty_hint);
|
||||
}
|
||||
getActivity().invalidateOptionsMenu();
|
||||
|
@ -138,7 +132,7 @@ public class ProfileDocumentsFragment
|
|||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> cursorLoader) {
|
||||
((ProfileDocumentsAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
|
||||
((AllMediaDocumentsAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,7 +150,7 @@ public class ProfileDocumentsFragment
|
|||
}
|
||||
|
||||
private void handleMediaMultiSelectClick(@NonNull DcMsg mediaRecord) {
|
||||
ProfileDocumentsAdapter adapter = getListAdapter();
|
||||
AllMediaDocumentsAdapter adapter = getListAdapter();
|
||||
|
||||
adapter.toggleSelection(mediaRecord);
|
||||
if (adapter.getSelectedMediaCount() == 0) {
|
||||
|
@ -188,7 +182,7 @@ public class ProfileDocumentsFragment
|
|||
@Override
|
||||
public void onMediaLongClicked(DcMsg mediaRecord) {
|
||||
if (actionMode == null) {
|
||||
((ProfileDocumentsAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
|
||||
((AllMediaDocumentsAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
|
||||
|
||||
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
|
||||
}
|
||||
|
@ -221,8 +215,8 @@ public class ProfileDocumentsFragment
|
|||
menu.findItem(R.id.menu_add_to_home_screen).setVisible(webxdcApp);
|
||||
}
|
||||
|
||||
private ProfileDocumentsAdapter getListAdapter() {
|
||||
return (ProfileDocumentsAdapter) recyclerView.getAdapter();
|
||||
private AllMediaDocumentsAdapter getListAdapter() {
|
||||
return (AllMediaDocumentsAdapter) recyclerView.getAdapter();
|
||||
}
|
||||
|
||||
private class ActionModeCallback implements ActionMode.Callback {
|
|
@ -21,7 +21,7 @@ import java.util.Collections;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
class ProfileGalleryAdapter extends StickyHeaderGridAdapter {
|
||||
class AllMediaGalleryAdapter extends StickyHeaderGridAdapter {
|
||||
|
||||
private final Context context;
|
||||
private final GlideRequests glideRequests;
|
||||
|
@ -50,10 +50,10 @@ class ProfileGalleryAdapter extends StickyHeaderGridAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
ProfileGalleryAdapter(@NonNull Context context,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
BucketedThreadMedia media,
|
||||
ItemClickListener clickListener)
|
||||
AllMediaGalleryAdapter(@NonNull Context context,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
BucketedThreadMedia media,
|
||||
ItemClickListener clickListener)
|
||||
{
|
||||
this.context = context;
|
||||
this.glideRequests = glideRequests;
|
|
@ -35,10 +35,10 @@ import org.thoughtcrime.securesms.util.ViewUtil;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
public class ProfileGalleryFragment
|
||||
public class AllMediaGalleryFragment
|
||||
extends MessageSelectorFragment
|
||||
implements LoaderManager.LoaderCallbacks<BucketedThreadMediaLoader.BucketedThreadMedia>,
|
||||
ProfileGalleryAdapter.ItemClickListener
|
||||
AllMediaGalleryAdapter.ItemClickListener
|
||||
{
|
||||
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class ProfileGalleryFragment
|
|||
this.noMedia = ViewUtil.findById(view, R.id.no_images);
|
||||
this.gridManager = new StickyHeaderGridLayoutManager(getCols());
|
||||
|
||||
this.recyclerView.setAdapter(new ProfileGalleryAdapter(getContext(),
|
||||
this.recyclerView.setAdapter(new AllMediaGalleryAdapter(getContext(),
|
||||
GlideApp.with(this),
|
||||
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
|
||||
this));
|
||||
|
@ -112,8 +112,8 @@ public class ProfileGalleryFragment
|
|||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> loader, BucketedThreadMediaLoader.BucketedThreadMedia bucketedThreadMedia) {
|
||||
((ProfileGalleryAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
|
||||
((ProfileGalleryAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
|
||||
((AllMediaGalleryAdapter) recyclerView.getAdapter()).setMedia(bucketedThreadMedia);
|
||||
((AllMediaGalleryAdapter) recyclerView.getAdapter()).notifyAllSectionsDataSetChanged();
|
||||
|
||||
noMedia.setVisibility(recyclerView.getAdapter().getItemCount() > 0 ? View.GONE : View.VISIBLE);
|
||||
if (chatId == DC_CHAT_NO_CHAT) {
|
||||
|
@ -124,7 +124,7 @@ public class ProfileGalleryFragment
|
|||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<BucketedThreadMediaLoader.BucketedThreadMedia> cursorLoader) {
|
||||
((ProfileGalleryAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
|
||||
((AllMediaGalleryAdapter) recyclerView.getAdapter()).setMedia(new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -142,7 +142,7 @@ public class ProfileGalleryFragment
|
|||
}
|
||||
|
||||
private void handleMediaMultiSelectClick(@NonNull DcMsg mediaRecord) {
|
||||
ProfileGalleryAdapter adapter = getListAdapter();
|
||||
AllMediaGalleryAdapter adapter = getListAdapter();
|
||||
|
||||
adapter.toggleSelection(mediaRecord);
|
||||
if (adapter.getSelectedMediaCount() == 0) {
|
||||
|
@ -175,7 +175,7 @@ public class ProfileGalleryFragment
|
|||
@Override
|
||||
public void onMediaLongClicked(DcMsg mediaRecord) {
|
||||
if (actionMode == null) {
|
||||
((ProfileGalleryAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
|
||||
((AllMediaGalleryAdapter) recyclerView.getAdapter()).toggleSelection(mediaRecord);
|
||||
recyclerView.getAdapter().notifyDataSetChanged();
|
||||
|
||||
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
|
||||
|
@ -206,8 +206,8 @@ public class ProfileGalleryFragment
|
|||
menu.findItem(R.id.menu_resend).setVisible(canResend);
|
||||
}
|
||||
|
||||
private ProfileGalleryAdapter getListAdapter() {
|
||||
return (ProfileGalleryAdapter) recyclerView.getAdapter();
|
||||
private AllMediaGalleryAdapter getListAdapter() {
|
||||
return (AllMediaGalleryAdapter) recyclerView.getAdapter();
|
||||
}
|
||||
|
||||
private class ActionModeCallback implements ActionMode.Callback {
|
|
@ -526,8 +526,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
} else if (itemId == R.id.menu_show_map) {
|
||||
WebxdcActivity.openMaps(this, chatId);
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_show_apps) {
|
||||
handleProfile(true);
|
||||
} else if (itemId == R.id.menu_all_media) {
|
||||
handleAllMedia();
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_search_up) {
|
||||
handleMenuSearchNext(false);
|
||||
|
@ -609,15 +609,16 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
}
|
||||
|
||||
private void handleProfile(boolean showApps) {
|
||||
private void handleProfile() {
|
||||
Intent intent = new Intent(this, ProfileActivity.class);
|
||||
intent.putExtra(ProfileActivity.CHAT_ID_EXTRA, chatId);
|
||||
intent.putExtra(ProfileActivity.FROM_CHAT, true);
|
||||
if (showApps) {
|
||||
intent.putExtra(ProfileActivity.FORCE_TAB_EXTRA, ProfileActivity.TAB_WEBXDC);
|
||||
}
|
||||
startActivity(intent);
|
||||
overridePendingTransition(0, 0);
|
||||
}
|
||||
|
||||
private void handleAllMedia() {
|
||||
Intent intent = new Intent(this, AllMediaActivity.class);
|
||||
intent.putExtra(AllMediaActivity.CHAT_ID_EXTRA, chatId);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void handleLeaveGroup() {
|
||||
|
@ -869,7 +870,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
buttonToggle.getBackground().invalidateSelf();
|
||||
});
|
||||
|
||||
titleView.setOnClickListener(v -> handleProfile(false));
|
||||
titleView.setOnClickListener(v -> handleProfile());
|
||||
titleView.setOnBackClickedListener(view -> handleReturnToConversationList());
|
||||
|
||||
composeText.setOnKeyListener(composeKeyPressedListener);
|
||||
|
|
|
@ -447,7 +447,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
|||
onBackPressed();
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_all_media) {
|
||||
startActivity(new Intent(this, ProfileActivity.class));
|
||||
startActivity(new Intent(this, AllMediaActivity.class));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -262,16 +262,16 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
|
|||
finish();
|
||||
}
|
||||
else if(conversationRecipient.getAddress().isDcChat()) {
|
||||
Intent intent = new Intent(this, ProfileActivity.class);
|
||||
intent.putExtra(ProfileActivity.CHAT_ID_EXTRA, conversationRecipient.getAddress().getDcChatId());
|
||||
intent.putExtra(ProfileActivity.FORCE_TAB_EXTRA, ProfileActivity.TAB_GALLERY);
|
||||
Intent intent = new Intent(this, AllMediaActivity.class);
|
||||
intent.putExtra(AllMediaActivity.CHAT_ID_EXTRA, conversationRecipient.getAddress().getDcChatId());
|
||||
intent.putExtra(AllMediaActivity.FORCE_GALLERY, true);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
else if(conversationRecipient.getAddress().isDcContact()) {
|
||||
Intent intent = new Intent(this, ProfileActivity.class);
|
||||
intent.putExtra(ProfileActivity.CONTACT_ID_EXTRA, conversationRecipient.getAddress().getDcContactId());
|
||||
intent.putExtra(ProfileActivity.FORCE_TAB_EXTRA, ProfileActivity.TAB_GALLERY);
|
||||
Intent intent = new Intent(this, AllMediaActivity.class);
|
||||
intent.putExtra(AllMediaActivity.CONTACT_ID_EXTRA, conversationRecipient.getAddress().getDcContactId());
|
||||
intent.putExtra(AllMediaActivity.FORCE_GALLERY, true);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -11,19 +11,13 @@ import android.view.ContextMenu;
|
|||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.b44t.messenger.DcChat;
|
||||
import com.b44t.messenger.DcContact;
|
||||
|
@ -31,11 +25,9 @@ import com.b44t.messenger.DcContext;
|
|||
import com.b44t.messenger.DcEvent;
|
||||
import com.b44t.messenger.rpc.Rpc;
|
||||
import com.b44t.messenger.rpc.RpcException;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.Prefs;
|
||||
import org.thoughtcrime.securesms.util.RelayUtil;
|
||||
|
@ -43,7 +35,6 @@ import org.thoughtcrime.securesms.util.Util;
|
|||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||
implements DcEventCenter.DcEventDelegate
|
||||
|
@ -51,16 +42,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
|
||||
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||
public static final String CONTACT_ID_EXTRA = "contact_id";
|
||||
public static final String FORCE_TAB_EXTRA = "force_tab";
|
||||
public static final String FROM_CHAT = "from_chat";
|
||||
|
||||
public static final int TAB_SETTINGS = 10;
|
||||
public static final int TAB_GALLERY = 20;
|
||||
public static final int TAB_AUDIO = 25;
|
||||
public static final int TAB_DOCS = 30;
|
||||
public static final int TAB_WEBXDC = 35;
|
||||
public static final int TAB_LINKS = 40;
|
||||
public static final int TAB_MAP = 50;
|
||||
|
||||
private static final int REQUEST_CODE_PICK_RINGTONE = 1;
|
||||
|
||||
|
@ -72,13 +53,8 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
private boolean chatIsMailingList;
|
||||
private boolean chatIsBroadcast;
|
||||
private int contactId;
|
||||
private boolean fromChat;
|
||||
|
||||
private final ArrayList<Integer> tabs = new ArrayList<>();
|
||||
private Toolbar toolbar;
|
||||
private ConversationTitleView titleView;
|
||||
private TabLayout tabLayout;
|
||||
private ViewPager viewPager;
|
||||
private boolean contactIsBot;
|
||||
private Toolbar toolbar;
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
|
@ -97,38 +73,27 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
setSupportActionBar(this.toolbar);
|
||||
ActionBar supportActionBar = getSupportActionBar();
|
||||
if (supportActionBar != null) {
|
||||
if (isGlobalProfile()) {
|
||||
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
||||
supportActionBar.setHomeActionContentDescription(getString(R.string.back));
|
||||
} else {
|
||||
supportActionBar.setDisplayHomeAsUpEnabled(false);
|
||||
supportActionBar.setCustomView(R.layout.conversation_title_view);
|
||||
supportActionBar.setDisplayShowCustomEnabled(true);
|
||||
supportActionBar.setDisplayShowTitleEnabled(false);
|
||||
Toolbar parent = (Toolbar) supportActionBar.getCustomView().getParent();
|
||||
parent.setPadding(0,0,0,0);
|
||||
parent.setContentInsetsAbsolute(0,0);
|
||||
|
||||
titleView = (ConversationTitleView) supportActionBar.getCustomView();
|
||||
titleView.setOnBackClickedListener(view -> onBackPressed());
|
||||
titleView.setOnClickListener(view -> onEnlargeAvatar());
|
||||
if (isContactProfile() && !isSelfProfile() && !chatIsDeviceTalk) {
|
||||
titleView.registerForContextMenu(this);
|
||||
}
|
||||
String title = getString(R.string.profile);
|
||||
if (chatIsMailingList) {
|
||||
title = getString(R.string.mailing_list);
|
||||
} else if (chatIsBroadcast) {
|
||||
title = getString(R.string.broadcast_list);
|
||||
} else if (chatIsMultiUser) {
|
||||
title = getString(R.string.tab_group);
|
||||
} else if (contactIsBot) {
|
||||
title = getString(R.string.bot);
|
||||
} else if (!chatIsDeviceTalk && !isSelfProfile()) {
|
||||
title = getString(R.string.tab_contact);
|
||||
}
|
||||
|
||||
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
||||
supportActionBar.setTitle(title);
|
||||
}
|
||||
|
||||
updateToolbar();
|
||||
|
||||
this.tabLayout.setupWithViewPager(viewPager);
|
||||
this.viewPager.setAdapter(new ProfilePagerAdapter(getSupportFragmentManager()));
|
||||
int forceTab = getIntent().getIntExtra(FORCE_TAB_EXTRA, -1);
|
||||
if (forceTab != -1) {
|
||||
int forceIndex = tabs.indexOf(forceTab);
|
||||
if (forceIndex != -1) {
|
||||
this.viewPager.setCurrentItem(forceIndex);
|
||||
}
|
||||
}
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ProfileFragment.CHAT_ID_EXTRA, (chatId == 0) ? -1 : chatId);
|
||||
args.putInt(ProfileFragment.CONTACT_ID_EXTRA, (contactId == 0) ? -1 : contactId);
|
||||
initFragment(R.id.fragment_container, new ProfileFragment(), args);
|
||||
|
||||
DcEventCenter eventCenter = DcHelper.getEventCenter(this);
|
||||
eventCenter.addObserver(DcContext.DC_EVENT_CHAT_MODIFIED, this);
|
||||
|
@ -137,7 +102,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
if (!isSelfProfile() && !isGlobalProfile()) {
|
||||
if (!isSelfProfile()) {
|
||||
getMenuInflater().inflate(R.menu.profile_common, menu);
|
||||
boolean canReceive = true;
|
||||
|
||||
|
@ -148,6 +113,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
menu.findItem(R.id.show_encr_info).setVisible(false);
|
||||
menu.findItem(R.id.share).setVisible(false);
|
||||
} else if (chatIsMultiUser) {
|
||||
menu.findItem(R.id.edit_name).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||
if (chatIsBroadcast) {
|
||||
canReceive = false;
|
||||
} else {
|
||||
|
@ -205,21 +171,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
getMenuInflater().inflate(R.menu.profile_title_context, menu);
|
||||
}
|
||||
|
||||
boolean backPressed = false;
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
backPressed = true;
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (backPressed && fromChat) {
|
||||
overridePendingTransition(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
DcHelper.getEventCenter(this).removeObservers(this);
|
||||
|
@ -228,22 +179,24 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
|
||||
@Override
|
||||
public void handleEvent(@NonNull DcEvent event) {
|
||||
updateToolbar();
|
||||
}
|
||||
|
||||
private void initializeResources() {
|
||||
chatId = getIntent().getIntExtra(CHAT_ID_EXTRA, 0);
|
||||
contactId = getIntent().getIntExtra(CONTACT_ID_EXTRA, 0);
|
||||
contactIsBot = false;
|
||||
chatIsMultiUser = false;
|
||||
chatIsDeviceTalk = false;
|
||||
chatIsMailingList= false;
|
||||
chatIsBroadcast = false;
|
||||
fromChat = getIntent().getBooleanExtra(FROM_CHAT, false);
|
||||
|
||||
if (contactId!=0) {
|
||||
DcContact dcContact = dcContext.getContact(contactId);
|
||||
chatId = dcContext.getChatIdByContactId(contactId);
|
||||
contactIsBot = dcContact.isBot();
|
||||
}
|
||||
else if(chatId!=0) {
|
||||
|
||||
if(chatId!=0) {
|
||||
DcChat dcChat = dcContext.getChat(chatId);
|
||||
chatIsMultiUser = dcChat.isMultiUser();
|
||||
chatIsDeviceTalk = dcChat.isDeviceTalk();
|
||||
|
@ -255,38 +208,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
}
|
||||
|
||||
if(!isGlobalProfile() && !isSelfProfile() && !chatIsMailingList) {
|
||||
tabs.add(TAB_SETTINGS);
|
||||
}
|
||||
tabs.add(TAB_GALLERY);
|
||||
tabs.add(TAB_AUDIO);
|
||||
tabs.add(TAB_DOCS);
|
||||
tabs.add(TAB_WEBXDC);
|
||||
//tabs.add(TAB_LINKS);
|
||||
//if(Prefs.isLocationStreamingEnabled(this)) {
|
||||
// tabs.add(TAB_MAP);
|
||||
//}
|
||||
|
||||
this.viewPager = ViewUtil.findById(this, R.id.pager);
|
||||
this.toolbar = ViewUtil.findById(this, R.id.toolbar);
|
||||
this.tabLayout = ViewUtil.findById(this, R.id.tab_layout);
|
||||
}
|
||||
|
||||
private void updateToolbar() {
|
||||
if (isGlobalProfile()){
|
||||
getSupportActionBar().setTitle(R.string.menu_all_media);
|
||||
}
|
||||
else if (chatId > 0) {
|
||||
DcChat dcChat = dcContext.getChat(chatId);
|
||||
titleView.setTitle(GlideApp.with(this), dcChat, true);
|
||||
}
|
||||
else if (isContactProfile()){
|
||||
titleView.setTitle(GlideApp.with(this), dcContext.getContact(contactId));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGlobalProfile() {
|
||||
return contactId==0 && chatId==0;
|
||||
}
|
||||
|
||||
private boolean isContactProfile() {
|
||||
|
@ -298,124 +220,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
return isContactProfile() && contactId==DcContact.DC_CONTACT_ID_SELF;
|
||||
}
|
||||
|
||||
private class ProfilePagerAdapter extends FragmentStatePagerAdapter {
|
||||
private Object currentFragment = null;
|
||||
|
||||
ProfilePagerAdapter(FragmentManager fragmentManager) {
|
||||
super(fragmentManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
|
||||
super.setPrimaryItem(container, position, object);
|
||||
if (currentFragment != null && currentFragment != object) {
|
||||
ActionMode action = null;
|
||||
if (currentFragment instanceof MessageSelectorFragment) {
|
||||
action = ((MessageSelectorFragment) currentFragment).getActionMode();
|
||||
} else if (currentFragment instanceof ProfileSettingsFragment) {
|
||||
action = ((ProfileSettingsFragment) currentFragment).getActionMode();
|
||||
}
|
||||
if (action != null) {
|
||||
action.finish();
|
||||
}
|
||||
}
|
||||
currentFragment = object;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
int tabId = tabs.get(position);
|
||||
Fragment fragment;
|
||||
Bundle args = new Bundle();
|
||||
|
||||
switch(tabId) {
|
||||
case TAB_SETTINGS:
|
||||
fragment = new ProfileSettingsFragment();
|
||||
args.putInt(ProfileSettingsFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
|
||||
args.putInt(ProfileSettingsFragment.CONTACT_ID_EXTRA, (contactId==0&&!isGlobalProfile())? -1 : contactId);
|
||||
break;
|
||||
|
||||
case TAB_GALLERY:
|
||||
fragment = new ProfileGalleryFragment();
|
||||
args.putInt(ProfileGalleryFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
|
||||
break;
|
||||
|
||||
case TAB_AUDIO:
|
||||
fragment = new ProfileDocumentsFragment();
|
||||
args.putInt(ProfileDocumentsFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
|
||||
args.putBoolean(ProfileDocumentsFragment.SHOW_AUDIO_EXTRA, true);
|
||||
break;
|
||||
|
||||
case TAB_WEBXDC:
|
||||
fragment = new ProfileDocumentsFragment();
|
||||
args.putInt(ProfileDocumentsFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
|
||||
args.putBoolean(ProfileDocumentsFragment.SHOW_WEBXDC_EXTRA, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
fragment = new ProfileDocumentsFragment();
|
||||
args.putInt(ProfileGalleryFragment.CHAT_ID_EXTRA, (chatId==0&&!isGlobalProfile())? -1 : chatId);
|
||||
break;
|
||||
}
|
||||
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return tabs.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
int tabId = tabs.get(position);
|
||||
switch(tabId) {
|
||||
case TAB_SETTINGS:
|
||||
if (chatIsDeviceTalk) {
|
||||
return getString(R.string.profile);
|
||||
} else if(isContactProfile()) {
|
||||
if (dcContext.getContact(contactId).isBot()) {
|
||||
return getString(R.string.bot);
|
||||
} else {
|
||||
return getString(R.string.tab_contact);
|
||||
}
|
||||
}
|
||||
else if (chatIsBroadcast) {
|
||||
return getString(R.string.broadcast_list);
|
||||
}
|
||||
else if (chatIsMailingList) {
|
||||
return getString(R.string.mailing_list);
|
||||
} else {
|
||||
return getString(R.string.tab_group);
|
||||
}
|
||||
|
||||
case TAB_GALLERY:
|
||||
return getString(R.string.tab_gallery);
|
||||
|
||||
case TAB_AUDIO:
|
||||
return getString(R.string.audio);
|
||||
|
||||
case TAB_DOCS:
|
||||
return getString(R.string.files);
|
||||
|
||||
case TAB_WEBXDC:
|
||||
return getString(R.string.webxdc_apps);
|
||||
|
||||
case TAB_LINKS:
|
||||
return getString(R.string.tab_links);
|
||||
|
||||
case TAB_MAP:
|
||||
return getString(R.string.tab_map);
|
||||
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// handle events
|
||||
// =========================================================================
|
||||
|
||||
|
@ -425,7 +229,6 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == android.R.id.home) {
|
||||
backPressed = true;
|
||||
finish();
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_mute_notifications) {
|
||||
|
@ -503,7 +306,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
.show();
|
||||
}
|
||||
|
||||
private void onEnlargeAvatar() {
|
||||
public void onEnlargeAvatar() {
|
||||
String profileImagePath;
|
||||
String title;
|
||||
Uri profileImageUri;
|
||||
|
@ -528,7 +331,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
|||
intent.putExtra(MediaPreviewActivity.ACTIVITY_TITLE_EXTRA, title);
|
||||
intent.putExtra(MediaPreviewActivity.EDIT_AVATAR_CHAT_ID, chatIsMultiUser ? chatId : 0); // shows edit-button, might be 0 for a contact-profile
|
||||
startActivity(intent);
|
||||
} else {
|
||||
} else if (chatIsMultiUser){
|
||||
onEditName();
|
||||
}
|
||||
}
|
||||
|
|
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()) {
|
||||
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.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.qr.QrShowActivity;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
|
@ -39,16 +38,15 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ProfileSettingsFragment extends Fragment
|
||||
implements ProfileSettingsAdapter.ItemClickListener, DcEventCenter.DcEventDelegate {
|
||||
public class ProfileFragment extends Fragment
|
||||
implements ProfileAdapter.ItemClickListener, DcEventCenter.DcEventDelegate {
|
||||
|
||||
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||
public static final String CONTACT_ID_EXTRA = "contact_id";
|
||||
|
||||
private static final int REQUEST_CODE_PICK_CONTACT = 2;
|
||||
|
||||
private StickyHeaderDecoration listDecoration;
|
||||
private ProfileSettingsAdapter adapter;
|
||||
private ProfileAdapter adapter;
|
||||
private ActionMode actionMode;
|
||||
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
|
||||
|
||||
|
@ -57,10 +55,6 @@ public class ProfileSettingsFragment extends Fragment
|
|||
protected int chatId;
|
||||
private int contactId;
|
||||
|
||||
protected ActionMode getActionMode() {
|
||||
return actionMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
|
@ -72,14 +66,12 @@ public class ProfileSettingsFragment extends Fragment
|
|||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.profile_settings_fragment, container, false);
|
||||
adapter = new ProfileSettingsAdapter(requireContext(), GlideApp.with(this), this);
|
||||
View view = inflater.inflate(R.layout.profile_fragment, container, false);
|
||||
adapter = new ProfileAdapter(requireContext(), GlideApp.with(this), this);
|
||||
|
||||
RecyclerView list = ViewUtil.findById(view, R.id.recycler_view);
|
||||
list.setAdapter(adapter);
|
||||
list.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
|
||||
listDecoration = new StickyHeaderDecoration(adapter, false, true);
|
||||
list.addItemDecoration(listDecoration);
|
||||
|
||||
update();
|
||||
|
||||
|
@ -97,12 +89,6 @@ public class ProfileSettingsFragment extends Fragment
|
|||
super.onDestroyView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
listDecoration.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(@NonNull DcEvent event) {
|
||||
update();
|
||||
|
@ -121,12 +107,11 @@ public class ProfileSettingsFragment extends Fragment
|
|||
if(dcChat!=null && dcChat.isMultiUser()) {
|
||||
memberList = dcContext.getChatContacts(chatId);
|
||||
}
|
||||
else if(contactId>0) {
|
||||
else if(contactId>0 && contactId!=DcContact.DC_CONTACT_ID_SELF) {
|
||||
sharedChats = dcContext.getChatlist(0, null, contactId);
|
||||
}
|
||||
|
||||
adapter.changeData(memberList, dcContact, sharedChats, dcChat);
|
||||
listDecoration.invalidateLayouts();
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,10 +121,17 @@ public class ProfileSettingsFragment extends Fragment
|
|||
@Override
|
||||
public void onSettingsClicked(int settingsId) {
|
||||
switch(settingsId) {
|
||||
case ProfileSettingsAdapter.INFO_SEND_MESSAGE_BUTTON:
|
||||
case ProfileAdapter.ITEM_ALL_MEDIA_BUTTON:
|
||||
if (chatId > 0) {
|
||||
Intent intent = new Intent(getActivity(), AllMediaActivity.class);
|
||||
intent.putExtra(AllMediaActivity.CHAT_ID_EXTRA, chatId);
|
||||
startActivity(intent);
|
||||
}
|
||||
break;
|
||||
case ProfileAdapter.ITEM_SEND_MESSAGE_BUTTON:
|
||||
onSendMessage();
|
||||
break;
|
||||
case ProfileSettingsAdapter.INFO_VERIFIED:
|
||||
case ProfileAdapter.ITEM_INTRODUCED_BY:
|
||||
onVerifiedByClicked();
|
||||
break;
|
||||
}
|
||||
|
@ -202,6 +194,12 @@ public class ProfileSettingsFragment extends Fragment
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAvatarClicked() {
|
||||
ProfileActivity activity = (ProfileActivity)getActivity();
|
||||
activity.onEnlargeAvatar();
|
||||
}
|
||||
|
||||
public void onAddMember() {
|
||||
DcChat dcChat = dcContext.getChat(chatId);
|
||||
Intent intent = new Intent(getContext(), ContactMultiSelectionActivity.class);
|
|
@ -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()) {
|
||||
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_constraintTop_toTopOf="@+id/top_guideline"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintWidth_max="34dp"
|
||||
app:layout_constraintHeight_max="34dp"
|
||||
|
||||
android:src="@drawable/ic_circle_status_online"
|
||||
android:contentDescription="@null"
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
android:gravity="center_vertical"
|
||||
android:focusable="true"
|
||||
android:background="?attr/conversation_list_item_background"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp">
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.AvatarView
|
||||
android:id="@+id/avatar"
|
||||
|
|
|
@ -19,26 +19,10 @@
|
|||
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"
|
||||
<FrameLayout
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
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_height="wrap_content"
|
||||
android:focusable="true"
|
||||
android:padding="16dp">
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:padding="16dp"
|
||||
android:id="@+id/status_text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start|center_vertical"
|
||||
style="@style/Signal.Text.Body"
|
||||
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>
|
||||
|
|
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"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item android:id="@+id/menu_show_apps"
|
||||
android:title="@string/webxdc_apps"
|
||||
<item android:id="@+id/menu_all_media"
|
||||
android:title="@string/apps_and_media"
|
||||
android:icon="@drawable/ic_apps_24"
|
||||
app:showAsAction="ifRoom" />
|
||||
app:showAsAction="always" />
|
||||
|
||||
<item android:id="@+id/menu_ephemeral_messages"
|
||||
android:title="@string/ephemeral_messages" />
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
<item android:title="@string/global_menu_edit_desktop"
|
||||
android:id="@+id/edit_name"
|
||||
app:showAsAction="never"/>
|
||||
android:icon="@drawable/ic_create_white_24dp"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item android:title="@string/menu_mute"
|
||||
android:id="@+id/menu_mute_notifications"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue