mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-17 12:58:25 +00:00
Visually note quotes for messages you don't have.
We will now show a small footer under quotes for messages that you don't have locally. Also fixes #7850
This commit is contained in:
parent
4d565990c9
commit
13c72779af
BIN
res/drawable-hdpi/ic_broken_link.png
Normal file
BIN
res/drawable-hdpi/ic_broken_link.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 327 B |
BIN
res/drawable-mdpi/ic_broken_link.png
Normal file
BIN
res/drawable-mdpi/ic_broken_link.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 286 B |
BIN
res/drawable-xhdpi/ic_broken_link.png
Normal file
BIN
res/drawable-xhdpi/ic_broken_link.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 532 B |
BIN
res/drawable-xxhdpi/ic_broken_link.png
Normal file
BIN
res/drawable-xxhdpi/ic_broken_link.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 628 B |
BIN
res/drawable-xxxhdpi/ic_broken_link.png
Normal file
BIN
res/drawable-xxxhdpi/ic_broken_link.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 970 B |
@ -11,133 +11,167 @@
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/quote_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/quote_bar"
|
||||
android:layout_width="@dimen/quote_corner_radius_bottom"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@color/white"
|
||||
tools:tint="@color/purple_400" />
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:id="@+id/quote_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/quote_author"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Signal.Text.Caption"
|
||||
android:textColor="@color/core_black"
|
||||
android:textStyle="bold"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:text="Peter Parker" />
|
||||
<ImageView
|
||||
android:id="@+id/quote_bar"
|
||||
android:layout_width="@dimen/quote_corner_radius_bottom"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@color/white"
|
||||
tools:tint="@color/purple_400" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/quote_attachment_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="27dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:paddingLeft="-4dp"
|
||||
android:paddingStart="-4dp"
|
||||
android:src="?attr/attachment_document_icon_small" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/quote_attachment_name"
|
||||
android:layout_width="match_parent"
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/quote_author"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Signal.Text.Body"
|
||||
android:textColor="@color/core_light_90"
|
||||
style="@style/Signal.Text.Caption"
|
||||
android:textColor="@color/core_black"
|
||||
android:textStyle="bold"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:text="The-Amazing-Spider-Man.cba" />
|
||||
tools:text="Peter Parker" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/quote_attachment_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="27dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:paddingLeft="-4dp"
|
||||
android:paddingStart="-4dp"
|
||||
android:src="?attr/attachment_document_icon_small" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/quote_attachment_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Signal.Text.Body"
|
||||
android:textColor="@color/core_light_90"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:text="The-Amazing-Spider-Man.cba" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/media_type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
style="@style/Signal.Text.Caption"
|
||||
android:textColor="@color/core_light_90"
|
||||
android:paddingTop="4dp"
|
||||
android:textStyle="italic"
|
||||
android:visibility="gone"
|
||||
tools:text="Photo"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/quote_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Signal.Text.Body"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
tools:text="With great power comes great responsibility."
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/media_type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
style="@style/Signal.Text.Caption"
|
||||
android:textColor="@color/core_light_90"
|
||||
android:paddingTop="4dp"
|
||||
android:textStyle="italic"
|
||||
android:visibility="gone"
|
||||
tools:text="Photo"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/quote_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Signal.Text.Body"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
tools:text="With great power comes great responsibility."
|
||||
tools:visibility="visible" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/quote_thumbnail"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:visibility="gone"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/quote_video_overlay"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/circle_white"
|
||||
android:layout_gravity="center"
|
||||
android:longClickable="false"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="13dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_marginLeft="11dp"
|
||||
android:layout_marginStart="11dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:tint="@color/core_blue"
|
||||
android:scaleType="fitXY"
|
||||
app:srcCompat="@drawable/triangle_right" />
|
||||
android:id="@+id/quote_thumbnail"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:visibility="gone"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/quote_video_overlay"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/circle_white"
|
||||
android:layout_gravity="center"
|
||||
android:longClickable="false"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="13dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_marginLeft="11dp"
|
||||
android:layout_marginStart="11dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:tint="@color/core_blue"
|
||||
android:scaleType="fitXY"
|
||||
app:srcCompat="@drawable/triangle_right" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/quote_missing_footer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:src="@drawable/ic_broken_link"
|
||||
android:tint="?attr/quote_missing_icon_color"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/quote_missing_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Signal.Text.Caption"
|
||||
android:text="@string/QuoteView_original_missing"
|
||||
android:textColor="@color/core_light_90"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -127,6 +127,8 @@
|
||||
|
||||
<attr name="pref_divider" format="reference" />
|
||||
|
||||
<attr name="quote_missing_icon_color" format="color" />
|
||||
|
||||
<declare-styleable name="CustomDefaultPreference">
|
||||
<attr name="custom_pref_toggle" format="string"/>
|
||||
</declare-styleable>
|
||||
|
@ -29,6 +29,7 @@
|
||||
<color name="transparent_black_30">#30000000</color>
|
||||
<color name="transparent_black_40">#40000000</color>
|
||||
<color name="transparent_black_70">#70000000</color>
|
||||
<color name="transparent_black_90">#90000000</color>
|
||||
|
||||
<color name="transparent_white_05">#05ffffff</color>
|
||||
<color name="transparent_white_10">#10ffffff</color>
|
||||
@ -38,6 +39,7 @@
|
||||
<color name="transparent_white_60">#60ffffff</color>
|
||||
<color name="transparent_white_70">#70ffffff</color>
|
||||
<color name="transparent_white_aa">#aaffffff</color>
|
||||
<color name="transparent_white_bb">#bbffffff</color>
|
||||
<color name="transparent_white_dd">#ddffffff</color>
|
||||
|
||||
<color name="conversation_compose_divider">#32000000</color>
|
||||
|
@ -204,7 +204,8 @@
|
||||
<string name="ConversationFragment_sms">SMS</string>
|
||||
<string name="ConversationFragment_deleting">Deleting</string>
|
||||
<string name="ConversationFragment_deleting_messages">Deleting messages...</string>
|
||||
<string name="ConversationFragment_quoted_message_not_found">Quoted message not found</string>
|
||||
<string name="ConversationFragment_quoted_message_not_found">Original message not found</string>
|
||||
<string name="ConversationFragment_quoted_message_no_longer_available">Original message no longer available</string>
|
||||
|
||||
<!-- ConversationListActivity -->
|
||||
<string name="ConversationListActivity_there_is_no_browser_installed_on_your_device">There is no browser installed on your device.</string>
|
||||
@ -793,6 +794,7 @@
|
||||
<string name="QuoteView_photo">Photo</string>
|
||||
<string name="QuoteView_document">Document</string>
|
||||
<string name="QuoteView_you">You</string>
|
||||
<string name="QuoteView_original_missing">Original message not found</string>
|
||||
|
||||
<!-- conversation_fragment -->
|
||||
<string name="conversation_fragment__scroll_to_the_bottom_content_description">Scroll to the bottom</string>
|
||||
|
@ -243,6 +243,8 @@
|
||||
|
||||
<item name="pref_divider">@drawable/preference_divider_light</item>
|
||||
|
||||
<item name="quote_missing_icon_color">@color/core_light_60</item>
|
||||
|
||||
<item name="group_members_dialog_icon">@drawable/ic_group_grey600_24dp</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.Fix</item>
|
||||
|
||||
@ -386,6 +388,8 @@
|
||||
|
||||
<item name="pref_divider">@drawable/preference_divider_dark</item>
|
||||
|
||||
<item name="quote_missing_icon_color">@color/core_dark_05</item>
|
||||
|
||||
<item name="group_members_dialog_icon">@drawable/ic_group_white_24dp</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.Fix</item>
|
||||
<item name="search_toolbar_background">@color/black</item>
|
||||
|
@ -701,6 +701,12 @@ public class ConversationFragment extends Fragment
|
||||
return;
|
||||
}
|
||||
|
||||
if (messageRecord.getQuote().isOriginalMissing()) {
|
||||
Log.i(TAG, "Clicked on a quote whose original message we never had.");
|
||||
Toast.makeText(getContext(), R.string.ConversationFragment_quoted_message_not_found, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
new AsyncTask<Void, Void, Integer>() {
|
||||
@Override
|
||||
protected Integer doInBackground(Void... voids) {
|
||||
@ -711,8 +717,7 @@ public class ConversationFragment extends Fragment
|
||||
return DatabaseFactory.getMmsSmsDatabase(getContext())
|
||||
.getQuotedMessagePosition(threadId,
|
||||
messageRecord.getQuote().getId(),
|
||||
messageRecord.getQuote().getAuthor(),
|
||||
getListAdapter().getItemCount());
|
||||
messageRecord.getQuote().getAuthor());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -725,13 +730,15 @@ public class ConversationFragment extends Fragment
|
||||
if (position >= 0 && position < getListAdapter().getItemCount()) {
|
||||
list.scrollToPosition(position);
|
||||
getListAdapter().pulseHighlightItem(position);
|
||||
} else if (position < 0) {
|
||||
Log.w(TAG, "Tried to navigate to quoted message, but it was deleted.");
|
||||
Toast.makeText(getContext(), R.string.ConversationFragment_quoted_message_no_longer_available, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(getContext(), getResources().getText(R.string.ConversationFragment_quoted_message_not_found), Toast.LENGTH_SHORT).show();
|
||||
if (position < 0) {
|
||||
Log.w(TAG, "Tried to navigate to quoted message, but it was deleted.");
|
||||
} else {
|
||||
Log.w(TAG, "Tried to navigate to quoted message, but it was out of the bounds of the adapter.");
|
||||
}
|
||||
Log.i(TAG, "Quoted message was outside of the loaded range. Need to restart the loader.");
|
||||
|
||||
firstLoad = true;
|
||||
startingPosition = position;
|
||||
getLoaderManager().restartLoader(0, Bundle.EMPTY, ConversationFragment.this);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
|
@ -598,7 +598,7 @@ public class ConversationItem extends LinearLayout
|
||||
if (current.isMms() && !current.isMmsNotification() && ((MediaMmsMessageRecord)current).getQuote() != null) {
|
||||
Quote quote = ((MediaMmsMessageRecord)current).getQuote();
|
||||
assert quote != null;
|
||||
quoteView.setQuote(glideRequests, quote.getId(), Recipient.from(context, quote.getAuthor(), true), quote.getText(), quote.getAttachment());
|
||||
quoteView.setQuote(glideRequests, quote.getId(), Recipient.from(context, quote.getAuthor(), true), quote.getText(), quote.isOriginalMissing(), quote.getAttachment());
|
||||
quoteView.setVisibility(View.VISIBLE);
|
||||
quoteView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
|
@ -107,6 +107,17 @@ public enum MaterialColor {
|
||||
: R.color.transparent_white_aa);
|
||||
}
|
||||
|
||||
public int toQuoteFooterColor(@NonNull Context context, boolean outgoing) {
|
||||
if (outgoing) {
|
||||
int color = toConversationColor(context);
|
||||
int alpha = isDarkTheme(context) ? (int) (0.4 * 255) : (int) (0.6 * 255);
|
||||
|
||||
return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
|
||||
}
|
||||
return context.getResources().getColor(isDarkTheme(context) ? R.color.transparent_black_90
|
||||
: R.color.transparent_white_bb);
|
||||
}
|
||||
|
||||
public boolean represents(Context context, int colorValue) {
|
||||
return context.getResources().getColor(conversationColorDark) == colorValue ||
|
||||
context.getResources().getColor(conversationColorLight) == colorValue ||
|
||||
|
@ -121,7 +121,7 @@ public class InputPanel extends LinearLayout
|
||||
}
|
||||
|
||||
public void setQuote(@NonNull GlideRequests glideRequests, long id, @NonNull Recipient author, @NonNull String body, @NonNull SlideDeck attachments) {
|
||||
this.quoteView.setQuote(glideRequests, id, author, body, attachments);
|
||||
this.quoteView.setQuote(glideRequests, id, author, body, false, attachments);
|
||||
this.quoteView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ public class InputPanel extends LinearLayout
|
||||
|
||||
public Optional<QuoteModel> getQuote() {
|
||||
if (quoteView.getQuoteId() > 0 && quoteView.getVisibility() == View.VISIBLE) {
|
||||
return Optional.of(new QuoteModel(quoteView.getQuoteId(), quoteView.getAuthor().getAddress(), quoteView.getBody(), quoteView.getAttachments()));
|
||||
return Optional.of(new QuoteModel(quoteView.getQuoteId(), quoteView.getAuthor().getAddress(), quoteView.getBody(), false, quoteView.getAttachments()));
|
||||
} else {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
@ -42,7 +41,8 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
private static final int MESSAGE_TYPE_OUTGOING = 1;
|
||||
private static final int MESSAGE_TYPE_INCOMING = 2;
|
||||
|
||||
private ViewGroup rootView;
|
||||
private ViewGroup mainView;
|
||||
private ViewGroup footerView;
|
||||
private TextView authorView;
|
||||
private TextView bodyView;
|
||||
private ImageView quoteBarView;
|
||||
@ -56,6 +56,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
private Recipient author;
|
||||
private String body;
|
||||
private TextView mediaDescriptionText;
|
||||
private TextView missingLinkText;
|
||||
private SlideDeck attachments;
|
||||
private int messageType;
|
||||
private int largeCornerRadius;
|
||||
@ -87,7 +88,8 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
private void initialize(@Nullable AttributeSet attrs) {
|
||||
inflate(getContext(), R.layout.quote_view, this);
|
||||
|
||||
this.rootView = findViewById(R.id.quote_root);
|
||||
this.mainView = findViewById(R.id.quote_main);
|
||||
this.footerView = findViewById(R.id.quote_missing_footer);
|
||||
this.authorView = findViewById(R.id.quote_author);
|
||||
this.bodyView = findViewById(R.id.quote_text);
|
||||
this.quoteBarView = findViewById(R.id.quote_bar);
|
||||
@ -97,6 +99,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
this.attachmentNameView = findViewById(R.id.quote_attachment_name);
|
||||
this.dismissView = findViewById(R.id.quote_dismiss);
|
||||
this.mediaDescriptionText = findViewById(R.id.media_type);
|
||||
this.missingLinkText = findViewById(R.id.quote_missing_text);
|
||||
this.largeCornerRadius = getResources().getDimensionPixelSize(R.dimen.quote_corner_radius_large);
|
||||
this.smallCornerRadius = getResources().getDimensionPixelSize(R.dimen.quote_corner_radius_bottom);
|
||||
|
||||
@ -116,6 +119,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
bodyView.setTextColor(primaryColor);
|
||||
attachmentNameView.setTextColor(primaryColor);
|
||||
mediaDescriptionText.setTextColor(secondaryColor);
|
||||
missingLinkText.setTextColor(primaryColor);
|
||||
|
||||
if (messageType == MESSAGE_TYPE_PREVIEW) {
|
||||
int radius = getResources().getDimensionPixelOffset(R.dimen.quote_corner_radius_preview);
|
||||
@ -147,7 +151,13 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
}
|
||||
}
|
||||
|
||||
public void setQuote(GlideRequests glideRequests, long id, @NonNull Recipient author, @Nullable String body, @NonNull SlideDeck attachments) {
|
||||
public void setQuote(GlideRequests glideRequests,
|
||||
long id,
|
||||
@NonNull Recipient author,
|
||||
@Nullable String body,
|
||||
boolean originalMissing,
|
||||
@NonNull SlideDeck attachments)
|
||||
{
|
||||
if (this.author != null) this.author.removeListener(this);
|
||||
|
||||
this.id = id;
|
||||
@ -159,6 +169,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
setQuoteAuthor(author);
|
||||
setQuoteText(body, attachments);
|
||||
setQuoteAttachment(glideRequests, attachments);
|
||||
setQuoteMissingFooter(originalMissing);
|
||||
}
|
||||
|
||||
public void setTopCornerSizes(boolean topLeftLarge, boolean topRightLarge) {
|
||||
@ -194,7 +205,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
|
||||
// We use the raw color resource because Android 4.x was struggling with tints here
|
||||
quoteBarView.setImageResource(author.getColor().toQuoteBarColorResource(getContext(), outgoing));
|
||||
rootView.setBackgroundColor(author.getColor().toQuoteBackgroundColor(getContext(), outgoing));
|
||||
mainView.setBackgroundColor(author.getColor().toQuoteBackgroundColor(getContext(), outgoing));
|
||||
}
|
||||
|
||||
private void setQuoteText(@Nullable String body, @NonNull SlideDeck attachments) {
|
||||
@ -257,6 +268,11 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
|
||||
}
|
||||
}
|
||||
|
||||
private void setQuoteMissingFooter(boolean missing) {
|
||||
footerView.setVisibility(missing ? VISIBLE : GONE);
|
||||
footerView.setBackgroundColor(author.getColor().toQuoteFooterColor(getContext(), messageType != MESSAGE_TYPE_INCOMING));
|
||||
}
|
||||
|
||||
public long getQuoteId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
static final String QUOTE_AUTHOR = "quote_author";
|
||||
static final String QUOTE_BODY = "quote_body";
|
||||
static final String QUOTE_ATTACHMENT = "quote_attachment";
|
||||
static final String QUOTE_MISSING = "quote_missing";
|
||||
|
||||
static final String SHARED_CONTACTS = "shared_contacts";
|
||||
|
||||
@ -124,7 +125,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " INTEGER DEFAULT 0, " +
|
||||
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + QUOTE_ID + " INTEGER DEFAULT 0, " +
|
||||
QUOTE_AUTHOR + " TEXT, " + QUOTE_BODY + " TEXT, " + QUOTE_ATTACHMENT + " INTEGER DEFAULT -1, " +
|
||||
SHARED_CONTACTS + " TEXT);";
|
||||
QUOTE_MISSING + " INTEGER DEFAULT 0, " + SHARED_CONTACTS + " TEXT);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
"CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");",
|
||||
@ -144,7 +145,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
MESSAGE_SIZE, STATUS, TRANSACTION_ID,
|
||||
BODY, PART_COUNT, ADDRESS, ADDRESS_DEVICE_ID,
|
||||
DELIVERY_RECEIPT_COUNT, READ_RECEIPT_COUNT, MISMATCHED_IDENTITIES, NETWORK_FAILURE, SUBSCRIPTION_ID,
|
||||
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT, SHARED_CONTACTS,
|
||||
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT, QUOTE_MISSING, SHARED_CONTACTS,
|
||||
"json_group_array(json_object(" +
|
||||
"'" + AttachmentDatabase.ROW_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + ", " +
|
||||
"'" + AttachmentDatabase.UNIQUE_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", " +
|
||||
@ -578,6 +579,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID));
|
||||
String quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR));
|
||||
String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_BODY));
|
||||
boolean quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE_MISSING)) == 1;
|
||||
List<Attachment> quoteAttachments = Stream.of(associatedAttachments).filter(Attachment::isQuote).map(a -> (Attachment)a).toList();
|
||||
List<Contact> contacts = getSharedContacts(cursor, associatedAttachments);
|
||||
Set<Attachment> contactAttachments = new HashSet<>(Stream.of(contacts).map(Contact::getAvatarAttachment).filter(a -> a != null).toList());
|
||||
@ -587,7 +589,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
QuoteModel quote = null;
|
||||
|
||||
if (quoteId > 0 && (!TextUtils.isEmpty(quoteText) || !quoteAttachments.isEmpty())) {
|
||||
quote = new QuoteModel(quoteId, Address.fromSerialized(quoteAuthor), quoteText, quoteAttachments);
|
||||
quote = new QuoteModel(quoteId, Address.fromSerialized(quoteAuthor), quoteText, quoteMissing, quoteAttachments);
|
||||
}
|
||||
|
||||
if (body != null && (Types.isGroupQuit(outboxType) || Types.isGroupUpdate(outboxType))) {
|
||||
@ -739,6 +741,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
contentValues.put(QUOTE_ID, retrieved.getQuote().getId());
|
||||
contentValues.put(QUOTE_BODY, retrieved.getQuote().getText());
|
||||
contentValues.put(QUOTE_AUTHOR, retrieved.getQuote().getAuthor().serialize());
|
||||
contentValues.put(QUOTE_MISSING, retrieved.getQuote().isOriginalMissing() ? 1 : 0);
|
||||
|
||||
quoteAttachments = retrieved.getQuote().getAttachments();
|
||||
}
|
||||
@ -882,6 +885,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
contentValues.put(QUOTE_ID, message.getOutgoingQuote().getId());
|
||||
contentValues.put(QUOTE_AUTHOR, message.getOutgoingQuote().getAuthor().serialize());
|
||||
contentValues.put(QUOTE_BODY, message.getOutgoingQuote().getText());
|
||||
contentValues.put(QUOTE_MISSING, message.getOutgoingQuote().isOriginalMissing() ? 1 : 0);
|
||||
|
||||
quoteAttachments.addAll(message.getOutgoingQuote().getAttachments());
|
||||
}
|
||||
@ -1174,6 +1178,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
new Quote(message.getOutgoingQuote().getId(),
|
||||
message.getOutgoingQuote().getAuthor(),
|
||||
message.getOutgoingQuote().getText(),
|
||||
message.getOutgoingQuote().isOriginalMissing(),
|
||||
new SlideDeck(context, message.getOutgoingQuote().getAttachments())) :
|
||||
null,
|
||||
message.getSharedContacts());
|
||||
@ -1330,12 +1335,13 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_ID));
|
||||
String quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_AUTHOR));
|
||||
String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_BODY));
|
||||
boolean quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_MISSING)) == 1;
|
||||
List<DatabaseAttachment> attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachment(cursor);
|
||||
List<? extends Attachment> quoteAttachments = Stream.of(attachments).filter(Attachment::isQuote).toList();
|
||||
SlideDeck quoteDeck = new SlideDeck(context, quoteAttachments);
|
||||
|
||||
if (quoteId > 0 && !TextUtils.isEmpty(quoteAuthor)) {
|
||||
return new Quote(quoteId, Address.fromExternal(context, quoteAuthor), quoteText, quoteDeck);
|
||||
return new Quote(quoteId, Address.fromExternal(context, quoteAuthor), quoteText, quoteMissing, quoteDeck);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsDatabase.QUOTE_ID,
|
||||
MmsDatabase.QUOTE_AUTHOR,
|
||||
MmsDatabase.QUOTE_BODY,
|
||||
MmsDatabase.QUOTE_MISSING,
|
||||
MmsDatabase.QUOTE_ATTACHMENT,
|
||||
MmsDatabase.SHARED_CONTACTS};
|
||||
|
||||
@ -160,11 +161,11 @@ public class MmsSmsDatabase extends Database {
|
||||
DatabaseFactory.getMmsDatabase(context).incrementReceiptCount(syncMessageId, timestamp, false, true);
|
||||
}
|
||||
|
||||
public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull Address address, int limit) {
|
||||
public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull Address address) {
|
||||
String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
|
||||
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId;
|
||||
|
||||
try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.NORMALIZED_DATE_SENT, MmsSmsColumns.ADDRESS }, selection, order, String.valueOf(limit))) {
|
||||
try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.NORMALIZED_DATE_SENT, MmsSmsColumns.ADDRESS }, selection, order, null)) {
|
||||
String serializedAddress = address.serialize();
|
||||
boolean isOwnNumber = Util.isOwnNumber(context, address);
|
||||
|
||||
@ -239,6 +240,7 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsDatabase.QUOTE_ID,
|
||||
MmsDatabase.QUOTE_AUTHOR,
|
||||
MmsDatabase.QUOTE_BODY,
|
||||
MmsDatabase.QUOTE_MISSING,
|
||||
MmsDatabase.QUOTE_ATTACHMENT,
|
||||
MmsDatabase.SHARED_CONTACTS};
|
||||
|
||||
@ -262,6 +264,7 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsDatabase.QUOTE_ID,
|
||||
MmsDatabase.QUOTE_AUTHOR,
|
||||
MmsDatabase.QUOTE_BODY,
|
||||
MmsDatabase.QUOTE_MISSING,
|
||||
MmsDatabase.QUOTE_ATTACHMENT,
|
||||
MmsDatabase.SHARED_CONTACTS};
|
||||
|
||||
@ -325,6 +328,7 @@ public class MmsSmsDatabase extends Database {
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_ID);
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_AUTHOR);
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_BODY);
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_MISSING);
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_ATTACHMENT);
|
||||
mmsColumnsPresent.add(MmsDatabase.SHARED_CONTACTS);
|
||||
|
||||
|
@ -50,8 +50,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
private static final int SHARED_CONTACTS = 8;
|
||||
private static final int FULL_TEXT_SEARCH = 9;
|
||||
private static final int BAD_IMPORT_CLEANUP = 10;
|
||||
private static final int QUOTE_MISSING = 11;
|
||||
|
||||
private static final int DATABASE_VERSION = 10;
|
||||
private static final int DATABASE_VERSION = 11;
|
||||
private static final String DATABASE_NAME = "signal.db";
|
||||
|
||||
private final Context context;
|
||||
@ -235,6 +236,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
}
|
||||
}
|
||||
|
||||
if (oldVersion < QUOTE_MISSING) {
|
||||
db.execSQL("ALTER TABLE mms ADD COLUMN quote_missing INTEGER DEFAULT 0");
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
@ -12,12 +12,14 @@ public class Quote {
|
||||
private final long id;
|
||||
private final Address author;
|
||||
private final String text;
|
||||
private final boolean missing;
|
||||
private final SlideDeck attachment;
|
||||
|
||||
public Quote(long id, @NonNull Address author, @Nullable String text, @NonNull SlideDeck attachment) {
|
||||
public Quote(long id, @NonNull Address author, @Nullable String text, boolean missing, @NonNull SlideDeck attachment) {
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.text = text;
|
||||
this.missing = missing;
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
@ -33,6 +35,10 @@ public class Quote {
|
||||
return text;
|
||||
}
|
||||
|
||||
public boolean isOriginalMissing() {
|
||||
return missing;
|
||||
}
|
||||
|
||||
public @NonNull SlideDeck getAttachment() {
|
||||
return attachment;
|
||||
}
|
||||
|
@ -891,13 +891,14 @@ public class PushDecryptJob extends ContextJob {
|
||||
attachments = ((MmsMessageRecord) message).getSlideDeck().asAttachments();
|
||||
}
|
||||
|
||||
return Optional.of(new QuoteModel(quote.get().getId(), author, quote.get().getText(), attachments));
|
||||
return Optional.of(new QuoteModel(quote.get().getId(), author, message.getBody(), false, attachments));
|
||||
}
|
||||
|
||||
Log.w(TAG, "Didn't find matching message record...");
|
||||
return Optional.of(new QuoteModel(quote.get().getId(),
|
||||
author,
|
||||
quote.get().getText(),
|
||||
true,
|
||||
PointerAttachment.forPointers(quote.get().getAttachments())));
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,14 @@ public class QuoteModel {
|
||||
private final long id;
|
||||
private final Address author;
|
||||
private final String text;
|
||||
private final boolean missing;
|
||||
private final List<Attachment> attachments;
|
||||
|
||||
public QuoteModel(long id, Address author, String text, @Nullable List<Attachment> attachments) {
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.text = text;
|
||||
public QuoteModel(long id, Address author, String text, boolean missing, @Nullable List<Attachment> attachments) {
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.text = text;
|
||||
this.missing = missing;
|
||||
this.attachments = attachments;
|
||||
}
|
||||
|
||||
@ -34,6 +36,10 @@ public class QuoteModel {
|
||||
return text;
|
||||
}
|
||||
|
||||
public boolean isOriginalMissing() {
|
||||
return missing;
|
||||
}
|
||||
|
||||
public List<Attachment> getAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user