diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e615d85e6a..3abe40cb7c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -176,9 +176,6 @@ android:name="org.thoughtcrime.securesms.loki.activities.LinkedDevicesActivity" android:screenOrientation="portrait" /> - - - diff --git a/app/src/main/java/org/thoughtcrime/securesms/BasicIntroFragment.java b/app/src/main/java/org/thoughtcrime/securesms/BasicIntroFragment.java deleted file mode 100644 index 25e7a901df..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/BasicIntroFragment.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.thoughtcrime.securesms; - -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import network.loki.messenger.R; - -public class BasicIntroFragment extends Fragment { - - private static final String ARG_DRAWABLE = "drawable"; - private static final String ARG_TEXT = "text"; - private static final String ARG_SUBTEXT = "subtext"; - - private int drawable; - private int text; - private int subtext; - - public static BasicIntroFragment newInstance(int drawable, int text, int subtext) { - BasicIntroFragment fragment = new BasicIntroFragment(); - Bundle args = new Bundle(); - args.putInt(ARG_DRAWABLE, drawable); - args.putInt(ARG_TEXT, text); - args.putInt(ARG_SUBTEXT, subtext); - fragment.setArguments(args); - return fragment; - } - - public BasicIntroFragment() {} - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (getArguments() != null) { - drawable = getArguments().getInt(ARG_DRAWABLE); - text = getArguments().getInt(ARG_TEXT ); - subtext = getArguments().getInt(ARG_SUBTEXT ); - } - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.color_fragment, container, false); - - ((ImageView)v.findViewById(R.id.watermark)).setImageResource(drawable); - ((TextView)v.findViewById(R.id.blurb)).setText(text); - ((TextView)v.findViewById(R.id.subblurb)).setText(subtext); - - return v; - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/ConversationListAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/ConversationListAdapter.java deleted file mode 100644 index ab86efd223..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/ConversationListAdapter.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2011 Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms; - -import android.content.Context; -import android.database.Cursor; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.database.model.ThreadRecord; -import org.thoughtcrime.securesms.mms.GlideRequests; -import org.thoughtcrime.securesms.util.Conversions; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Collections; -import java.util.HashSet; -import java.util.Locale; -import java.util.Set; - -import network.loki.messenger.R; - -/** - * A CursorAdapter for building a list of conversation threads. - * - * @author Moxie Marlinspike - */ -class ConversationListAdapter extends CursorRecyclerViewAdapter { - - private static final int MESSAGE_TYPE_SWITCH_ARCHIVE = 1; - private static final int MESSAGE_TYPE_THREAD = 2; - private static final int MESSAGE_TYPE_INBOX_ZERO = 3; - - private final @NonNull ThreadDatabase threadDatabase; - private final @NonNull GlideRequests glideRequests; - private final @NonNull Locale locale; - private final @NonNull LayoutInflater inflater; - private final @Nullable ItemClickListener clickListener; - private final @NonNull MessageDigest digest; - - private final Set batchSet = Collections.synchronizedSet(new HashSet()); - private boolean batchMode = false; - private final Set typingSet = new HashSet<>(); - - protected static class ViewHolder extends RecyclerView.ViewHolder { - public ViewHolder(final @NonNull V itemView) - { - super(itemView); - } - - public BindableConversationListItem getItem() { - return (BindableConversationListItem)itemView; - } - } - - @Override - public long getItemId(@NonNull Cursor cursor) { - ThreadRecord record = getThreadRecord(cursor); - - return Conversions.byteArrayToLong(digest.digest(record.getRecipient().getAddress().serialize().getBytes())); - } - - @Override - protected long getFastAccessItemId(int position) { - return super.getFastAccessItemId(position); - } - - ConversationListAdapter(@NonNull Context context, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @Nullable Cursor cursor, - @Nullable ItemClickListener clickListener) - { - super(context, cursor); - try { - this.glideRequests = glideRequests; - this.threadDatabase = DatabaseFactory.getThreadDatabase(context); - this.locale = locale; - this.inflater = LayoutInflater.from(context); - this.clickListener = clickListener; - this.digest = MessageDigest.getInstance("SHA1"); - setHasStableIds(true); - } catch (NoSuchAlgorithmException nsae) { - throw new AssertionError("SHA-1 missing"); - } - } - - @Override - public ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) { - if (viewType == MESSAGE_TYPE_SWITCH_ARCHIVE) { - ConversationListItemAction action = (ConversationListItemAction) inflater.inflate(R.layout.conversation_list_item_action, - parent, false); - - action.setOnClickListener(v -> { - if (clickListener != null) clickListener.onSwitchToArchive(); - }); - - return new ViewHolder(action); - } else if (viewType == MESSAGE_TYPE_INBOX_ZERO) { - return new ViewHolder((ConversationListItemInboxZero)inflater.inflate(R.layout.conversation_list_item_inbox_zero, parent, false)); - } else { - final ConversationListItem item = (ConversationListItem)inflater.inflate(R.layout.conversation_list_item_view, - parent, false); - - item.setOnClickListener(view -> { - if (clickListener != null) clickListener.onItemClick(item); - }); - - item.setOnLongClickListener(view -> { - if (clickListener != null) clickListener.onItemLongClick(item); - return true; - }); - - return new ViewHolder(item); - } - } - - @Override - public void onItemViewRecycled(ViewHolder holder) { - holder.getItem().unbind(); - } - - @Override - public void onBindItemViewHolder(ViewHolder viewHolder, @NonNull Cursor cursor) { - viewHolder.getItem().bind(getThreadRecord(cursor), glideRequests, locale, typingSet, batchSet, batchMode); - } - - @Override - public int getItemViewType(@NonNull Cursor cursor) { - ThreadRecord threadRecord = getThreadRecord(cursor); - - if (threadRecord.getDistributionType() == ThreadDatabase.DistributionTypes.ARCHIVE) { - return MESSAGE_TYPE_SWITCH_ARCHIVE; - } else if (threadRecord.getDistributionType() == ThreadDatabase.DistributionTypes.INBOX_ZERO) { - return MESSAGE_TYPE_INBOX_ZERO; - } else { - return MESSAGE_TYPE_THREAD; - } - } - - public void setTypingThreads(@NonNull Set threadsIds) { - typingSet.clear(); - typingSet.addAll(threadsIds); - notifyDataSetChanged(); - } - - private ThreadRecord getThreadRecord(@NonNull Cursor cursor) { - return threadDatabase.readerFor(cursor).getCurrent(); - } - - void toggleThreadInBatchSet(long threadId) { - if (batchSet.contains(threadId)) { - batchSet.remove(threadId); - } else if (threadId != -1) { - batchSet.add(threadId); - } - } - - Set getBatchSelections() { - return batchSet; - } - - void initializeBatchMode(boolean toggle) { - this.batchMode = toggle; - unselectAllThreads(); - } - - private void unselectAllThreads() { - this.batchSet.clear(); - this.notifyDataSetChanged(); - } - - void selectAllThreads() { - for (int i = 0; i < getItemCount(); i++) { - long threadId = getThreadRecord(getCursorAtPositionOrThrow(i)).getThreadId(); - if (threadId != -1) batchSet.add(threadId); - } - this.notifyDataSetChanged(); - } - - interface ItemClickListener { - void onItemClick(ConversationListItem item); - void onItemLongClick(ConversationListItem item); - void onSwitchToArchive(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/ConversationListItem.java b/app/src/main/java/org/thoughtcrime/securesms/ConversationListItem.java deleted file mode 100644 index b2ab627659..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/ConversationListItem.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (C) 2014-2017 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.graphics.Typeface; -import android.graphics.drawable.RippleDrawable; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.text.style.StyleSpan; -import android.util.AttributeSet; -import android.view.View; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import org.thoughtcrime.securesms.components.ConversationItemAlertView; -import org.thoughtcrime.securesms.components.AvatarImageView; -import org.thoughtcrime.securesms.components.DeliveryStatusView; -import org.thoughtcrime.securesms.components.FromTextView; -import org.thoughtcrime.securesms.components.ThumbnailView; -import org.thoughtcrime.securesms.components.TypingIndicatorView; -import org.thoughtcrime.securesms.database.model.ThreadRecord; -import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities; -import org.thoughtcrime.securesms.loki.utilities.MentionUtilities; -import org.thoughtcrime.securesms.mms.GlideRequests; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.recipients.RecipientModifiedListener; -import org.thoughtcrime.securesms.search.model.MessageResult; -import org.thoughtcrime.securesms.util.DateUtils; -import org.thoughtcrime.securesms.util.SearchUtil; -import org.thoughtcrime.securesms.util.ThemeUtil; -import org.thoughtcrime.securesms.util.Util; -import org.thoughtcrime.securesms.util.ViewUtil; - -import java.util.Collections; -import java.util.Locale; -import java.util.Set; - -import network.loki.messenger.R; - -public class ConversationListItem extends RelativeLayout - implements RecipientModifiedListener, - BindableConversationListItem, Unbindable -{ - @SuppressWarnings("unused") - private final static String TAG = ConversationListItem.class.getSimpleName(); - - private final static Typeface BOLD_TYPEFACE = Typeface.create("sans-serif-medium", Typeface.NORMAL); - private final static Typeface LIGHT_TYPEFACE = Typeface.create("sans-serif", Typeface.NORMAL); - - private static final int MAX_SNIPPET_LENGTH = 500; - - private Set selectedThreads; - private Recipient recipient; - private long threadId; - private GlideRequests glideRequests; - private View subjectContainer; - private TextView subjectView; - private TypingIndicatorView typingView; - private FromTextView fromView; - private TextView dateView; - private TextView archivedView; - private DeliveryStatusView deliveryStatusIndicator; - private ConversationItemAlertView alertView; - private TextView unreadIndicator; - private long lastSeen; - - private int unreadCount; - private AvatarImageView contactPhotoImage; - private ThumbnailView thumbnailView; - - private int distributionType; - - public ConversationListItem(Context context) { - this(context, null); - } - - public ConversationListItem(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - this.subjectContainer = findViewById(R.id.subject_container); - this.subjectView = findViewById(R.id.subject); - this.typingView = findViewById(R.id.typing_indicator); - this.fromView = findViewById(R.id.from); - this.dateView = findViewById(R.id.date); - this.deliveryStatusIndicator = findViewById(R.id.delivery_status); - this.alertView = findViewById(R.id.indicators_parent); - this.contactPhotoImage = findViewById(R.id.contact_photo_image); - this.thumbnailView = findViewById(R.id.thumbnail); - this.archivedView = findViewById(R.id.archived); - this.unreadIndicator = findViewById(R.id.unread_indicator); - thumbnailView.setClickable(false); - - ViewUtil.setTextViewGravityStart(this.fromView, getContext()); - ViewUtil.setTextViewGravityStart(this.subjectView, getContext()); - } - - @Override - public void bind(@NonNull ThreadRecord thread, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @NonNull Set typingThreads, - @NonNull Set selectedThreads, - boolean batchMode) - { - bind(thread, glideRequests, locale, typingThreads, selectedThreads, batchMode, null); - } - - public void bind(@NonNull ThreadRecord thread, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @NonNull Set typingThreads, - @NonNull Set selectedThreads, - boolean batchMode, - @Nullable String highlightSubstring) - { - this.selectedThreads = selectedThreads; - this.recipient = thread.getRecipient(); - this.threadId = thread.getThreadId(); - this.glideRequests = glideRequests; - this.unreadCount = thread.getUnreadCount(); - this.distributionType = thread.getDistributionType(); - this.lastSeen = thread.getLastSeen(); - - this.recipient.addListener(this); - if (highlightSubstring != null) { - String name = recipient.isLocalNumber() ? getContext().getString(R.string.note_to_self) : recipient.getName(); - - this.fromView.setText(SearchUtil.getHighlightedSpan(locale, () -> new StyleSpan(Typeface.BOLD), name, highlightSubstring)); - } else { - this.fromView.setText(recipient, unreadCount == 0); - } - - if (typingThreads.contains(threadId)) { - this.subjectView.setVisibility(INVISIBLE); - - this.typingView.setVisibility(VISIBLE); - this.typingView.startAnimation(); - } else { - this.typingView.setVisibility(GONE); - this.typingView.stopAnimation(); - - this.subjectView.setVisibility(VISIBLE); - this.subjectView.setText(getTrimmedSnippet(thread.getDisplayBody(getContext()))); - this.subjectView.setTypeface(unreadCount == 0 ? LIGHT_TYPEFACE : BOLD_TYPEFACE); - this.subjectView.setTextColor(unreadCount == 0 ? ThemeUtil.getThemedColor(getContext(), R.attr.conversation_list_item_subject_color) - : ThemeUtil.getThemedColor(getContext(), R.attr.conversation_list_item_unread_color)); - } - - if (thread.getDate() > 0) { - CharSequence date = DateUtils.getBriefRelativeTimeSpanString(getContext(), locale, thread.getDate()); - dateView.setText(date); - dateView.setTypeface(unreadCount == 0 ? LIGHT_TYPEFACE : BOLD_TYPEFACE); - dateView.setTextColor(unreadCount == 0 ? ThemeUtil.getThemedColor(getContext(), R.attr.conversation_list_item_date_color) - : ThemeUtil.getThemedColor(getContext(), R.attr.conversation_list_item_unread_color)); - } - - if (thread.isArchived()) { - this.archivedView.setVisibility(View.VISIBLE); - } else { - this.archivedView.setVisibility(View.GONE); - } - - setStatusIcons(thread); - setThumbnailSnippet(thread); - setBatchState(batchMode); - setRippleColor(recipient); - setUnreadIndicator(thread); - this.contactPhotoImage.setAvatar(glideRequests, recipient, true); - } - - public void bind(@NonNull Recipient contact, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @Nullable String highlightSubstring) - { - this.selectedThreads = Collections.emptySet(); - this.recipient = contact; - this.glideRequests = glideRequests; - - this.recipient.addListener(this); - - String name = recipient.isLocalNumber() ? getContext().getString(R.string.note_to_self) : recipient.getName(); - - fromView.setText(SearchUtil.getHighlightedSpan(locale, () -> new StyleSpan(Typeface.BOLD), name, highlightSubstring)); - subjectView.setText(SearchUtil.getHighlightedSpan(locale, () -> new StyleSpan(Typeface.BOLD), contact.getAddress().toString(), highlightSubstring)); - dateView.setText(""); - archivedView.setVisibility(GONE); - unreadIndicator.setVisibility(GONE); - deliveryStatusIndicator.setNone(); - alertView.setNone(); - thumbnailView.setVisibility(GONE); - - setBatchState(false); - setRippleColor(contact); - contactPhotoImage.setAvatar(glideRequests, recipient, true); - } - - public void bind(@NonNull MessageResult messageResult, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @Nullable String highlightSubstring) - { - this.selectedThreads = Collections.emptySet(); - this.recipient = messageResult.conversationRecipient; - this.glideRequests = glideRequests; - - this.recipient.addListener(this); - - fromView.setText(recipient, true); - subjectView.setText(SearchUtil.getHighlightedSpan(locale, () -> new StyleSpan(Typeface.BOLD), messageResult.bodySnippet, highlightSubstring)); - dateView.setText(DateUtils.getBriefRelativeTimeSpanString(getContext(), locale, messageResult.receivedTimestampMs)); - archivedView.setVisibility(GONE); - unreadIndicator.setVisibility(GONE); - deliveryStatusIndicator.setNone(); - alertView.setNone(); - thumbnailView.setVisibility(GONE); - - setBatchState(false); - setRippleColor(recipient); - contactPhotoImage.setAvatar(glideRequests, recipient, true); - } - - @Override - public void unbind() { - if (this.recipient != null) this.recipient.removeListener(this); - } - - private void setBatchState(boolean batch) { - setSelected(batch && selectedThreads.contains(threadId)); - } - - public Recipient getRecipient() { - return recipient; - } - - public long getThreadId() { - return threadId; - } - - public int getUnreadCount() { - return unreadCount; - } - - public int getDistributionType() { - return distributionType; - } - - public long getLastSeen() { - return lastSeen; - } - - private @NonNull CharSequence getTrimmedSnippet(@NonNull CharSequence snippet) { - MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(threadId, getContext()); // TODO: Terrible place to do this, but okay for now - snippet = MentionUtilities.highlightMentions(snippet, threadId, getContext()); - return snippet.length() <= MAX_SNIPPET_LENGTH ? snippet : snippet.subSequence(0, MAX_SNIPPET_LENGTH); - } - - private void setThumbnailSnippet(ThreadRecord thread) { - if (thread.getSnippetUri() != null) { - this.thumbnailView.setVisibility(View.VISIBLE); - this.thumbnailView.setImageResource(glideRequests, thread.getSnippetUri()); - - LayoutParams subjectParams = (RelativeLayout.LayoutParams)this.subjectContainer .getLayoutParams(); - subjectParams.addRule(RelativeLayout.LEFT_OF, R.id.thumbnail); - if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { - subjectParams.addRule(RelativeLayout.START_OF, R.id.thumbnail); - } - this.subjectContainer.setLayoutParams(subjectParams); - this.post(new ThumbnailPositioner(thumbnailView, archivedView, deliveryStatusIndicator, dateView)); - } else { - this.thumbnailView.setVisibility(View.GONE); - - LayoutParams subjectParams = (RelativeLayout.LayoutParams)this.subjectContainer.getLayoutParams(); - subjectParams.addRule(RelativeLayout.LEFT_OF, R.id.status); - if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { - subjectParams.addRule(RelativeLayout.START_OF, R.id.status); - } - this.subjectContainer.setLayoutParams(subjectParams); - } - } - - private void setStatusIcons(ThreadRecord thread) { - if (!thread.isOutgoing() || thread.isOutgoingCall() || thread.isVerificationStatusChange()) { - deliveryStatusIndicator.setNone(); - alertView.setNone(); - } else if (thread.isFailed()) { - deliveryStatusIndicator.setNone(); - alertView.setFailed(); - } else if (thread.isPendingInsecureSmsFallback()) { - deliveryStatusIndicator.setNone(); - alertView.setPendingApproval(); - } else { - alertView.setNone(); - - if (thread.isPending()) deliveryStatusIndicator.setPending(); - else if (thread.isRemoteRead()) deliveryStatusIndicator.setRead(); - else if (thread.isDelivered()) deliveryStatusIndicator.setDelivered(); - else deliveryStatusIndicator.setSent(); - } - } - - private void setRippleColor(Recipient recipient) { - if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - ((RippleDrawable)(getBackground()).mutate()) - .setColor(ColorStateList.valueOf(recipient.getColor().toConversationColor(getContext()))); - } - } - - private void setUnreadIndicator(ThreadRecord thread) { - if (thread.isOutgoing() || thread.getUnreadCount() == 0) { - unreadIndicator.setVisibility(View.GONE); - return; - } - - unreadIndicator.setText(String.valueOf(unreadCount)); - unreadIndicator.setVisibility(View.VISIBLE); - } - - @Override - public void onModified(final Recipient recipient) { - Util.runOnMain(() -> { - fromView.setText(recipient, unreadCount == 0); - contactPhotoImage.setAvatar(glideRequests, recipient, true); - setRippleColor(recipient); - }); - } - - private static class ThumbnailPositioner implements Runnable { - - private final View thumbnailView; - private final View archivedView; - private final View deliveryStatusView; - private final View dateView; - - ThumbnailPositioner(View thumbnailView, View archivedView, View deliveryStatusView, View dateView) { - this.thumbnailView = thumbnailView; - this.archivedView = archivedView; - this.deliveryStatusView = deliveryStatusView; - this.dateView = dateView; - } - - @Override - public void run() { - LayoutParams thumbnailParams = (RelativeLayout.LayoutParams)thumbnailView.getLayoutParams(); - - if (archivedView.getVisibility() == View.VISIBLE && - (archivedView.getWidth() + deliveryStatusView.getWidth()) > dateView.getWidth()) - { - thumbnailParams.addRule(RelativeLayout.LEFT_OF, R.id.status); - if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { - thumbnailParams.addRule(RelativeLayout.START_OF, R.id.status); - } - } else { - thumbnailParams.addRule(RelativeLayout.LEFT_OF, R.id.date); - if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { - thumbnailParams.addRule(RelativeLayout.START_OF, R.id.date); - } - } - - thumbnailView.setLayoutParams(thumbnailParams); - } - } - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/ConversationListItemAction.java b/app/src/main/java/org/thoughtcrime/securesms/ConversationListItemAction.java deleted file mode 100644 index b5553e8529..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/ConversationListItemAction.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.thoughtcrime.securesms; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import androidx.annotation.NonNull; -import android.util.AttributeSet; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.thoughtcrime.securesms.database.model.ThreadRecord; -import org.thoughtcrime.securesms.mms.GlideRequests; -import org.thoughtcrime.securesms.util.ViewUtil; - -import java.util.Locale; -import java.util.Set; - -import network.loki.messenger.R; - -public class ConversationListItemAction extends LinearLayout implements BindableConversationListItem { - - private TextView description; - - public ConversationListItemAction(Context context) { - super(context); - } - - public ConversationListItemAction(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public ConversationListItemAction(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - public void onFinishInflate() { - super.onFinishInflate(); - this.description = ViewUtil.findById(this, R.id.description); - } - - @Override - public void bind(@NonNull ThreadRecord thread, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @NonNull Set typingThreads, - @NonNull Set selectedThreads, - boolean batchMode) - { - this.description.setText(getContext().getString(R.string.ConversationListItemAction_archived_conversations_d, thread.getCount())); - } - - @Override - public void unbind() { - - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/ConversationListItemInboxZero.java b/app/src/main/java/org/thoughtcrime/securesms/ConversationListItemInboxZero.java deleted file mode 100644 index c24063b0e5..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/ConversationListItemInboxZero.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.thoughtcrime.securesms; - - -import android.content.Context; -import android.os.Build; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import android.util.AttributeSet; -import android.widget.LinearLayout; - -import org.thoughtcrime.securesms.database.model.ThreadRecord; -import org.thoughtcrime.securesms.mms.GlideRequests; - -import java.util.Locale; -import java.util.Set; - -public class ConversationListItemInboxZero extends LinearLayout implements BindableConversationListItem{ - public ConversationListItemInboxZero(Context context) { - super(context); - } - - public ConversationListItemInboxZero(Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - } - - public ConversationListItemInboxZero(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - public ConversationListItemInboxZero(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - @Override - public void unbind() { - - } - - @Override - public void bind(@NonNull ThreadRecord thread, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @NonNull Set typingThreads, - @NonNull Set selectedThreads, - boolean batchMode) - { - - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/CountrySelectionActivity.java b/app/src/main/java/org/thoughtcrime/securesms/CountrySelectionActivity.java deleted file mode 100644 index 11e2f559dd..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/CountrySelectionActivity.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.thoughtcrime.securesms; - - -import android.content.Intent; -import android.os.Bundle; - -import network.loki.messenger.R; - -public class CountrySelectionActivity extends BaseActivity - implements CountrySelectionFragment.CountrySelectedListener - -{ - - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); - this.setContentView(R.layout.country_selection); - } - - @Override - public void countrySelected(String countryName, int countryCode) { - Intent result = getIntent(); - result.putExtra("country_name", countryName); - result.putExtra("country_code", countryCode); - - this.setResult(RESULT_OK, result); - this.finish(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/CountrySelectionFragment.java b/app/src/main/java/org/thoughtcrime/securesms/CountrySelectionFragment.java deleted file mode 100644 index ac266afd8b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/CountrySelectionFragment.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.thoughtcrime.securesms; - -import android.app.Activity; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.ListFragment; -import androidx.loader.app.LoaderManager; -import androidx.loader.content.Loader; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.SimpleAdapter; - -import org.thoughtcrime.securesms.database.loaders.CountryListLoader; - -import java.util.ArrayList; -import java.util.Map; - -import network.loki.messenger.R; - -public class CountrySelectionFragment extends ListFragment implements LoaderManager.LoaderCallbacks>> { - - private EditText countryFilter; - private CountrySelectedListener listener; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - return inflater.inflate(R.layout.country_selection_fragment, container, false); - } - - @Override - public void onActivityCreated(Bundle bundle) { - super.onActivityCreated(bundle); - this.countryFilter = (EditText)getView().findViewById(R.id.country_search); - this.countryFilter.addTextChangedListener(new FilterWatcher()); - getLoaderManager().initLoader(0, null, this).forceLoad(); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - this.listener = (CountrySelectedListener)activity; - } - - @Override - public void onListItemClick(ListView listView, View view, int position, long id) { - Map item = (Map)this.getListAdapter().getItem(position); - if (this.listener != null) { - this.listener.countrySelected(item.get("country_name"), - Integer.parseInt(item.get("country_code").substring(1))); - } - } - - @Override - public @NonNull Loader>> onCreateLoader(int arg0, Bundle arg1) { - return new CountryListLoader(getActivity()); - } - - @Override - public void onLoadFinished(@NonNull Loader>> loader, - ArrayList> results) - { - String[] from = {"country_name", "country_code"}; - int[] to = {R.id.country_name, R.id.country_code}; - this.setListAdapter(new SimpleAdapter(getActivity(), results, R.layout.country_list_item, from, to)); - - if (this.countryFilter != null && this.countryFilter.getText().length() != 0) { - ((SimpleAdapter)getListAdapter()).getFilter().filter(this.countryFilter.getText().toString()); - } - } - - @Override - public void onLoaderReset(@NonNull Loader>> arg0) { - this.setListAdapter(null); - } - - public interface CountrySelectedListener { - public void countrySelected(String countryName, int countryCode); - } - - private class FilterWatcher implements TextWatcher { - - @Override - public void afterTextChanged(Editable s) { - if (getListAdapter() != null) { - ((SimpleAdapter)getListAdapter()).getFilter().filter(s.toString()); - } - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/DatabaseMigrationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/DatabaseMigrationActivity.java deleted file mode 100644 index d7c1031635..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/DatabaseMigrationActivity.java +++ /dev/null @@ -1,197 +0,0 @@ -package org.thoughtcrime.securesms; - -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Message; -import android.os.Parcelable; -import android.view.View; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.TextView; - -import org.thoughtcrime.securesms.database.SmsMigrator.ProgressDescription; -import org.thoughtcrime.securesms.loki.activities.HomeActivity; -import org.thoughtcrime.securesms.service.ApplicationMigrationService; -import org.thoughtcrime.securesms.service.ApplicationMigrationService.ImportState; - -import network.loki.messenger.R; - -public class DatabaseMigrationActivity extends PassphraseRequiredActionBarActivity { - - private final ImportServiceConnection serviceConnection = new ImportServiceConnection(); - private final ImportStateHandler importStateHandler = new ImportStateHandler(); - private final BroadcastReceiver completedReceiver = new NullReceiver(); - - private LinearLayout promptLayout; - private LinearLayout progressLayout; - private Button skipButton; - private Button importButton; - private ProgressBar progress; - private TextView progressLabel; - - private ApplicationMigrationService importService; - private boolean isVisible = false; - - @Override - protected void onCreate(Bundle bundle, boolean ready) { - setContentView(R.layout.database_migration_activity); - - initializeResources(); - initializeServiceBinding(); - } - - @Override - public void onResume() { - super.onResume(); - isVisible = true; - registerForCompletedNotification(); - } - - @Override - public void onPause() { - super.onPause(); - isVisible = false; - unregisterForCompletedNotification(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - shutdownServiceBinding(); - } - - @Override - public void onBackPressed() { - - } - - private void initializeServiceBinding() { - Intent intent = new Intent(this, ApplicationMigrationService.class); - bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); - } - - private void initializeResources() { - this.promptLayout = (LinearLayout)findViewById(R.id.prompt_layout); - this.progressLayout = (LinearLayout)findViewById(R.id.progress_layout); - this.skipButton = (Button) findViewById(R.id.skip_button); - this.importButton = (Button) findViewById(R.id.import_button); - this.progress = (ProgressBar) findViewById(R.id.import_progress); - this.progressLabel = (TextView) findViewById(R.id.import_status); - - this.progressLayout.setVisibility(View.GONE); - this.promptLayout.setVisibility(View.GONE); - - this.importButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(DatabaseMigrationActivity.this, ApplicationMigrationService.class); - intent.setAction(ApplicationMigrationService.MIGRATE_DATABASE); - intent.putExtra("master_secret", (Parcelable)getIntent().getParcelableExtra("master_secret")); - startService(intent); - - promptLayout.setVisibility(View.GONE); - progressLayout.setVisibility(View.VISIBLE); - } - }); - - this.skipButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ApplicationMigrationService.setDatabaseImported(DatabaseMigrationActivity.this); - handleImportComplete(); - } - }); - } - - private void registerForCompletedNotification() { - IntentFilter filter = new IntentFilter(); - filter.addAction(ApplicationMigrationService.COMPLETED_ACTION); - filter.setPriority(1000); - - registerReceiver(completedReceiver, filter); - } - - private void unregisterForCompletedNotification() { - unregisterReceiver(completedReceiver); - } - - private void shutdownServiceBinding() { - unbindService(serviceConnection); - } - - private void handleStateIdle() { - this.promptLayout.setVisibility(View.VISIBLE); - this.progressLayout.setVisibility(View.GONE); - } - - private void handleStateProgress(ProgressDescription update) { - this.promptLayout.setVisibility(View.GONE); - this.progressLayout.setVisibility(View.VISIBLE); - this.progressLabel.setText(update.primaryComplete + "/" + update.primaryTotal); - - double max = this.progress.getMax(); - double primaryTotal = update.primaryTotal; - double primaryComplete = update.primaryComplete; - double secondaryTotal = update.secondaryTotal; - double secondaryComplete = update.secondaryComplete; - - this.progress.setProgress((int)Math.round((primaryComplete / primaryTotal) * max)); - this.progress.setSecondaryProgress((int)Math.round((secondaryComplete / secondaryTotal) * max)); - } - - private void handleImportComplete() { - if (isVisible) { - if (getIntent().hasExtra("next_intent")) { - startActivity((Intent)getIntent().getParcelableExtra("next_intent")); - } else { - startActivity(new Intent(this, HomeActivity.class)); - } - } - - finish(); - } - - private class ImportStateHandler extends Handler { - @Override - public void handleMessage(Message message) { - switch (message.what) { - case ImportState.STATE_IDLE: handleStateIdle(); break; - case ImportState.STATE_MIGRATING_IN_PROGRESS: handleStateProgress((ProgressDescription)message.obj); break; - case ImportState.STATE_MIGRATING_COMPLETE: handleImportComplete(); break; - } - } - } - - private class ImportServiceConnection implements ServiceConnection { - @Override - public void onServiceConnected(ComponentName className, IBinder service) { - importService = ((ApplicationMigrationService.ApplicationMigrationBinder)service).getService(); - importService.setImportStateHandler(importStateHandler); - - ImportState state = importService.getState(); - importStateHandler.obtainMessage(state.state, state.progress).sendToTarget(); - } - - @Override - public void onServiceDisconnected(ComponentName name) { - importService.setImportStateHandler(null); - } - } - - private static class NullReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - abortBroadcast(); - } - } - - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsRecipientAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsRecipientAdapter.java index 422330dd81..4c3467402f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsRecipientAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsRecipientAdapter.java @@ -67,7 +67,7 @@ class MessageDetailsRecipientAdapter extends BaseAdapter implements AbsListView. @Override public void onMovedToScrapHeap(View view) { - ((MessageRecipientListItem)view).unbind(); + ((UserView)view).unbind(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/MessageRecipientListItem.java b/app/src/main/java/org/thoughtcrime/securesms/MessageRecipientListItem.java deleted file mode 100644 index 3cca57ae4e..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/MessageRecipientListItem.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2014 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms; - -import android.content.Context; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.View; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import org.thoughtcrime.securesms.MessageDetailsRecipientAdapter.RecipientDeliveryStatus; -import org.thoughtcrime.securesms.components.AvatarImageView; -import org.thoughtcrime.securesms.components.DeliveryStatusView; -import org.thoughtcrime.securesms.components.FromTextView; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.NetworkFailure; -import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.thoughtcrime.securesms.mms.GlideRequests; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.recipients.RecipientModifiedListener; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.thoughtcrime.securesms.util.Util; - -import network.loki.messenger.R; - -/** - * A simple view to show the recipients of a message - * - * @author Jake McGinty - */ -public class MessageRecipientListItem extends RelativeLayout - implements RecipientModifiedListener -{ - @SuppressWarnings("unused") - private final static String TAG = MessageRecipientListItem.class.getSimpleName(); - - private RecipientDeliveryStatus member; - private GlideRequests glideRequests; - private FromTextView fromView; - private TextView errorDescription; - private TextView actionDescription; - private Button conflictButton; - private AvatarImageView contactPhotoImage; - private ImageView unidentifiedDeliveryIcon; - private DeliveryStatusView deliveryStatusView; - - public MessageRecipientListItem(Context context) { - super(context); - } - - public MessageRecipientListItem(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - this.fromView = findViewById(R.id.from); - this.errorDescription = findViewById(R.id.error_description); - this.actionDescription = findViewById(R.id.action_description); - this.contactPhotoImage = findViewById(R.id.contact_photo_image); - this.conflictButton = findViewById(R.id.conflict_button); - this.unidentifiedDeliveryIcon = findViewById(R.id.ud_indicator); - this.deliveryStatusView = findViewById(R.id.delivery_status); - } - - public void set(final GlideRequests glideRequests, - final MessageRecord record, - final RecipientDeliveryStatus member, - final boolean isPushGroup) - { - this.glideRequests = glideRequests; - this.member = member; - - member.getRecipient().addListener(this); - fromView.setText(member.getRecipient()); - contactPhotoImage.setAvatar(glideRequests, member.getRecipient(), false); - setIssueIndicators(record, isPushGroup); - unidentifiedDeliveryIcon.setVisibility(TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(getContext()) && member.isUnidentified() ? VISIBLE : GONE); - } - - private void setIssueIndicators(final MessageRecord record, - final boolean isPushGroup) - { - final NetworkFailure networkFailure = getNetworkFailure(record); - final IdentityKeyMismatch keyMismatch = networkFailure == null ? getKeyMismatch(record) : null; - - String errorText = ""; - - if (keyMismatch != null) { - conflictButton.setVisibility(View.VISIBLE); - - errorText = getContext().getString(R.string.MessageDetailsRecipient_new_safety_number); - conflictButton.setOnClickListener(v -> new ConfirmIdentityDialog(getContext(), record, keyMismatch).show()); - } else if ((networkFailure != null && !record.isPending()) || (!isPushGroup && record.isFailed())) { - conflictButton.setVisibility(View.GONE); - errorText = getContext().getString(R.string.MessageDetailsRecipient_failed_to_send); - } else { - if (record.isOutgoing()) { - if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.PENDING || member.getDeliveryStatus() == RecipientDeliveryStatus.Status.UNKNOWN) { - deliveryStatusView.setVisibility(View.GONE); - } else if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.READ) { - deliveryStatusView.setRead(); - deliveryStatusView.setVisibility(View.VISIBLE); - } else if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.DELIVERED) { - deliveryStatusView.setDelivered(); - deliveryStatusView.setVisibility(View.VISIBLE); - } else if (member.getDeliveryStatus() == RecipientDeliveryStatus.Status.SENT) { - deliveryStatusView.setSent(); - deliveryStatusView.setVisibility(View.VISIBLE); - } - } else { - deliveryStatusView.setVisibility(View.GONE); - } - - conflictButton.setVisibility(View.GONE); - } - - errorDescription.setText(errorText); - errorDescription.setVisibility(TextUtils.isEmpty(errorText) ? View.GONE : View.VISIBLE); - } - - private NetworkFailure getNetworkFailure(final MessageRecord record) { - if (record.hasNetworkFailures()) { - for (final NetworkFailure failure : record.getNetworkFailures()) { - if (failure.getAddress().equals(member.getRecipient().getAddress())) { - return failure; - } - } - } - return null; - } - - private IdentityKeyMismatch getKeyMismatch(final MessageRecord record) { - if (record.isIdentityMismatchFailure()) { - for (final IdentityKeyMismatch mismatch : record.getIdentityKeyMismatches()) { - if (mismatch.getAddress().equals(member.getRecipient().getAddress())) { - return mismatch; - } - } - } - return null; - } - - public void unbind() { - if (this.member != null && this.member.getRecipient() != null) this.member.getRecipient().removeListener(this); - } - - @Override - public void onModified(final Recipient recipient) { - Util.runOnMain(() -> { - fromView.setText(recipient); - contactPhotoImage.setAvatar(glideRequests, recipient, false); - }); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt index 27c4974546..48de4ef3a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt @@ -99,8 +99,8 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { lblGroupNameDisplay.text = originalName cntGroupNameDisplay.setOnClickListener { isEditingName = true } - findViewById