mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 20:15:21 +00:00
commit
0977ad7ba7
@ -123,7 +123,8 @@
|
|||||||
android:layout_height="50dp"
|
android:layout_height="50dp"
|
||||||
android:background="@color/transparent"
|
android:background="@color/transparent"
|
||||||
android:textColor="@color/signal_primary"
|
android:textColor="@color/signal_primary"
|
||||||
android:text="@string/activity_key_pair_toggle_mode_button_title_3"
|
android:text="Link Device (Coming Soon)"
|
||||||
|
android:alpha="0.24"
|
||||||
android:elevation="0dp"
|
android:elevation="0dp"
|
||||||
android:stateListAnimator="@null" />
|
android:stateListAnimator="@null" />
|
||||||
|
|
||||||
|
@ -1,233 +1,254 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<View
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
android:layout_width="match_parent"
|
||||||
android:orientation="vertical"
|
android:layout_height="4dp"
|
||||||
android:layout_width="match_parent"
|
android:background="@drawable/attachment_selector_shadow"/>
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<View android:layout_width="match_parent"
|
<LinearLayout
|
||||||
android:layout_height="4dp"
|
android:orientation="vertical"
|
||||||
android:background="@drawable/attachment_selector_shadow"/>
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
<LinearLayout android:orientation="vertical"
|
android:background="?attachment_type_selector_background">
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?attachment_type_selector_background">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.RecentPhotoViewRail
|
<org.thoughtcrime.securesms.components.RecentPhotoViewRail
|
||||||
android:id="@+id/recent_photos"
|
android:id="@+id/recent_photos"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="90dp"
|
||||||
|
android:padding="4dp"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="90dp"
|
android:layout_height="wrap_content"
|
||||||
android:padding="4dp"/>
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
<LinearLayout android:orientation="horizontal"
|
android:orientation="vertical">
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:weightSum="4">
|
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||||
android:id="@+id/gallery_button"
|
android:id="@+id/gallery_button"
|
||||||
android:layout_width="53dp"
|
android:layout_width="53dp"
|
||||||
android:layout_height="53dp"
|
android:layout_height="53dp"
|
||||||
android:src="@drawable/ic_image_white_24dp"
|
android:src="@drawable/ic_image_white_24dp"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:contentDescription="@string/attachment_type_selector__gallery_description"
|
android:contentDescription="@string/attachment_type_selector__gallery_description"
|
||||||
app:circleColor="@color/purple_400"/>
|
app:circleColor="@color/purple_400"/>
|
||||||
|
|
||||||
<TextView android:layout_marginTop="10dp"
|
<TextView
|
||||||
style="@style/AttachmentTypeLabel"
|
android:layout_marginTop="10dp"
|
||||||
android:layout_width="wrap_content"
|
style="@style/AttachmentTypeLabel"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:text="@string/attachment_type_selector__gallery"/>
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/attachment_type_selector__gallery"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
<LinearLayout android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:layout_weight="1"
|
||||||
android:layout_weight="1"
|
android:gravity="center"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||||
android:id="@+id/audio_button"
|
android:id="@+id/camera_button"
|
||||||
android:layout_width="53dp"
|
android:layout_width="53dp"
|
||||||
android:layout_height="53dp"
|
android:layout_height="53dp"
|
||||||
android:src="@drawable/ic_headset_white_24dp"
|
android:src="@drawable/ic_camera_white_24dp"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:contentDescription="@string/attachment_type_selector__audio_description"
|
android:contentDescription="@string/attachment_type_selector__camera_description"
|
||||||
app:circleColor="@color/orange_400"/>
|
app:circleColor="@color/green_400"/>
|
||||||
|
|
||||||
<TextView android:layout_marginTop="10dp"
|
<TextView android:layout_marginTop="10dp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/AttachmentTypeLabel"
|
android:gravity="center"
|
||||||
android:text="@string/attachment_type_selector__audio"/>
|
style="@style/AttachmentTypeLabel"
|
||||||
|
android:text="@string/attachment_type_selector__camera"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
<LinearLayout
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:gravity="center"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="vertical">
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||||
android:id="@+id/document_button"
|
android:id="@+id/audio_button"
|
||||||
android:layout_width="53dp"
|
android:layout_width="53dp"
|
||||||
android:layout_height="53dp"
|
android:layout_height="53dp"
|
||||||
android:src="@drawable/ic_insert_drive_file_white_24dp"
|
android:contentDescription="@string/attachment_type_selector__audio_description"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:contentDescription="@string/attachment_type_selector__file_description"
|
android:src="@drawable/ic_headset_white_24dp"
|
||||||
app:circleColor="@color/red_400"/>
|
app:circleColor="@color/orange_400" />
|
||||||
|
|
||||||
<TextView android:layout_marginTop="10dp"
|
<TextView
|
||||||
style="@style/AttachmentTypeLabel"
|
style="@style/AttachmentTypeLabel"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/attachment_type_selector__file"/>
|
android:layout_marginTop="10dp"
|
||||||
|
android:text="@string/attachment_type_selector__audio" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
<LinearLayout
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:gravity="center"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_weight="1">
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||||
android:id="@+id/contact_button"
|
android:id="@+id/document_button"
|
||||||
android:layout_width="53dp"
|
android:layout_width="53dp"
|
||||||
android:layout_height="53dp"
|
android:layout_height="53dp"
|
||||||
android:src="@drawable/ic_person_white_24dp"
|
android:contentDescription="@string/attachment_type_selector__file_description"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:contentDescription="@string/attachment_type_selector__contact_description"
|
android:src="@drawable/ic_insert_drive_file_white_24dp"
|
||||||
app:circleColor="@color/blue_400"/>
|
app:circleColor="@color/red_400" />
|
||||||
|
|
||||||
<TextView android:layout_marginTop="10dp"
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
style="@style/AttachmentTypeLabel"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
style="@style/AttachmentTypeLabel"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/attachment_type_selector__contact"/>
|
android:layout_marginTop="10dp"
|
||||||
|
android:text="@string/attachment_type_selector__file" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||||
|
android:id="@+id/contact_button"
|
||||||
|
android:layout_width="53dp"
|
||||||
|
android:layout_height="53dp"
|
||||||
|
android:src="@drawable/ic_person_white_24dp"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:contentDescription="@string/attachment_type_selector__contact_description"
|
||||||
|
app:circleColor="@color/blue_400"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/AttachmentTypeLabel"
|
||||||
|
android:text="@string/attachment_type_selector__contact"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout android:orientation="horizontal"
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:orientation="horizontal"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:weightSum="4">
|
android:layout_marginBottom="16dp"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
<LinearLayout
|
||||||
android:layout_height="wrap_content"
|
android:id="@+id/location_linear_layout"
|
||||||
android:layout_weight="1"
|
android:layout_width="match_parent"
|
||||||
android:gravity="center"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||||
android:id="@+id/camera_button"
|
android:id="@+id/location_button"
|
||||||
android:layout_width="53dp"
|
android:layout_width="53dp"
|
||||||
android:layout_height="53dp"
|
android:layout_height="53dp"
|
||||||
android:src="@drawable/ic_camera_white_24dp"
|
android:contentDescription="@string/attachment_type_selector__location_description"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:contentDescription="@string/attachment_type_selector__camera_description"
|
android:src="@drawable/ic_location_on_white_24dp"
|
||||||
app:circleColor="@color/green_400"/>
|
app:circleColor="@color/blue_grey_400" />
|
||||||
|
|
||||||
<TextView android:layout_marginTop="10dp"
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
style="@style/AttachmentTypeLabel"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:gravity="center"
|
android:layout_height="wrap_content"
|
||||||
style="@style/AttachmentTypeLabel"
|
android:layout_marginTop="10dp"
|
||||||
android:text="@string/attachment_type_selector__camera"/>
|
android:text="@string/attachment_type_selector__location" />
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/location_linear_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
|
||||||
android:id="@+id/location_button"
|
|
||||||
android:layout_width="53dp"
|
|
||||||
android:layout_height="53dp"
|
|
||||||
android:src="@drawable/ic_location_on_white_24dp"
|
|
||||||
android:scaleType="center"
|
|
||||||
android:contentDescription="@string/attachment_type_selector__location_description"
|
|
||||||
app:circleColor="@color/blue_grey_400"/>
|
|
||||||
|
|
||||||
<TextView android:layout_marginTop="10dp"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="@style/AttachmentTypeLabel"
|
|
||||||
android:text="@string/attachment_type_selector__location"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
<LinearLayout
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:layout_weight="1"
|
||||||
android:orientation="vertical">
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||||
android:id="@+id/giphy_button"
|
android:id="@+id/giphy_button"
|
||||||
android:layout_width="53dp"
|
android:layout_width="53dp"
|
||||||
android:layout_height="53dp"
|
android:layout_height="53dp"
|
||||||
android:src="@drawable/ic_gif_white_24dp"
|
android:src="@drawable/ic_gif_white_24dp"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:contentDescription="@string/attachment_type_selector__gif_description"
|
android:contentDescription="@string/attachment_type_selector__gif_description"
|
||||||
app:circleColor="@color/cyan_400"/>
|
app:circleColor="@color/cyan_400"/>
|
||||||
|
|
||||||
<TextView android:layout_marginTop="10dp"
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_marginTop="10dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
style="@style/AttachmentTypeLabel"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/attachment_type_selector__gif"/>
|
style="@style/AttachmentTypeLabel"
|
||||||
|
android:text="@string/attachment_type_selector__gif"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
<LinearLayout
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:layout_weight="1"
|
||||||
android:orientation="vertical">
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||||
android:id="@+id/close_button"
|
android:id="@+id/close_button"
|
||||||
android:layout_width="53dp"
|
android:layout_width="53dp"
|
||||||
android:layout_height="53dp"
|
android:layout_height="53dp"
|
||||||
android:src="@drawable/ic_keyboard_arrow_down_white_24dp"
|
android:src="@drawable/ic_keyboard_arrow_down_white_24dp"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:contentDescription="@string/attachment_type_selector__drawer_description"
|
android:contentDescription="@string/attachment_type_selector__drawer_description"
|
||||||
app:circleColor="@color/gray50"/>
|
app:circleColor="@color/gray50"/>
|
||||||
|
|
||||||
<TextView android:layout_marginTop="10dp"
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_marginTop="10dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
style="@style/AttachmentTypeLabel"
|
android:layout_height="wrap_content"
|
||||||
android:text=" "/>
|
style="@style/AttachmentTypeLabel"
|
||||||
|
android:text=""/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -125,7 +125,6 @@
|
|||||||
android:text="160/160 (1)"
|
android:text="160/160 (1)"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
|
||||||
<ViewStub
|
<ViewStub
|
||||||
android:id="@+id/emoji_drawer_stub"
|
android:id="@+id/emoji_drawer_stub"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -108,8 +108,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipChildren="false"
|
android:clipChildren="false"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false">
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.HidingLinearLayout
|
<org.thoughtcrime.securesms.components.HidingLinearLayout
|
||||||
android:id="@+id/quick_attachment_toggle"
|
android:id="@+id/quick_attachment_toggle"
|
||||||
@ -127,6 +126,7 @@
|
|||||||
android:src="?quick_camera_icon"
|
android:src="?quick_camera_icon"
|
||||||
android:paddingStart="6dp"
|
android:paddingStart="6dp"
|
||||||
android:paddingEnd="6dp"
|
android:paddingEnd="6dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
android:contentDescription="@string/conversation_activity__quick_attachment_drawer_toggle_camera_description" />
|
android:contentDescription="@string/conversation_activity__quick_attachment_drawer_toggle_camera_description" />
|
||||||
|
|
||||||
@ -136,7 +136,8 @@
|
|||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:clipChildren="false"
|
android:clipChildren="false"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
<include layout="@layout/microphone_recorder_view" />
|
<include layout="@layout/microphone_recorder_view" />
|
||||||
|
|
||||||
@ -148,8 +149,7 @@
|
|||||||
android:id="@+id/inline_attachment_container"
|
android:id="@+id/inline_attachment_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="right|end"
|
android:layout_gravity="right|end">
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/inline_attachment_button"
|
android:id="@+id/inline_attachment_button"
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<!-- <item android:title="@string/conversation__menu_view_all_media"
|
<item android:title="@string/conversation__menu_view_all_media"
|
||||||
android:id="@+id/menu_view_media" />
|
android:id="@+id/menu_view_media" />
|
||||||
|
|
||||||
<item android:title="@string/conversation__menu_conversation_settings"
|
<!-- <item android:title="@string/conversation__menu_conversation_settings"
|
||||||
android:id="@+id/menu_conversation_settings"/> -->
|
android:id="@+id/menu_conversation_settings"/> -->
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
android:icon="@drawable/icon_qr_code"/>
|
android:icon="@drawable/icon_qr_code"/>
|
||||||
|
|
||||||
<Preference android:key="preference_category_link_device"
|
<Preference android:key="preference_category_link_device"
|
||||||
android:title="@string/activity_settings_link_device_button_title"
|
android:title="Link Device (Coming Soon)"
|
||||||
android:icon="@drawable/icon_link"/>
|
android:icon="@drawable/icon_link"/>
|
||||||
|
|
||||||
<Preference android:key="preference_category_seed"
|
<Preference android:key="preference_category_seed"
|
||||||
|
@ -187,10 +187,14 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
|
|||||||
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_PUBLIC_KEY));
|
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_PUBLIC_KEY));
|
||||||
this.findPreference(PREFERENCE_CATEGORY_QR_CODE)
|
this.findPreference(PREFERENCE_CATEGORY_QR_CODE)
|
||||||
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_QR_CODE));
|
.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_QR_CODE));
|
||||||
|
|
||||||
|
// TODO: Enable this again later
|
||||||
|
/*
|
||||||
Preference linkDevicePreference = this.findPreference(PREFERENCE_CATEGORY_LINK_DEVICE);
|
Preference linkDevicePreference = this.findPreference(PREFERENCE_CATEGORY_LINK_DEVICE);
|
||||||
// Hide if this is a slave device
|
// Hide if this is a slave device
|
||||||
linkDevicePreference.setVisible(isMasterDevice);
|
linkDevicePreference.setVisible(isMasterDevice);
|
||||||
linkDevicePreference.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_LINK_DEVICE));
|
linkDevicePreference.setOnPreferenceClickListener(new CategoryClickListener(PREFERENCE_CATEGORY_LINK_DEVICE));
|
||||||
|
*/
|
||||||
Preference seedPreference = this.findPreference(PREFERENCE_CATEGORY_SEED);
|
Preference seedPreference = this.findPreference(PREFERENCE_CATEGORY_SEED);
|
||||||
// Hide if this is a slave device
|
// Hide if this is a slave device
|
||||||
seedPreference.setVisible(isMasterDevice);
|
seedPreference.setVisible(isMasterDevice);
|
||||||
|
@ -67,6 +67,8 @@ import java.io.IOException;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -227,9 +229,14 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
|||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
|
Pattern pattern = Pattern.compile("[a-zA-Z0-9_]+");
|
||||||
|
Matcher matcher = pattern.matcher(s.toString());
|
||||||
if (s.toString().isEmpty()) {
|
if (s.toString().isEmpty()) {
|
||||||
name.getInput().setError("Invalid");
|
name.getInput().setError("Invalid");
|
||||||
finishButton.setEnabled(false);
|
finishButton.setEnabled(false);
|
||||||
|
} else if (!matcher.matches()) {
|
||||||
|
name.getInput().setError("Invalid (a-z, A-Z, 0-9 and _ only)");
|
||||||
|
finishButton.setEnabled(false);
|
||||||
} else if (s.toString().getBytes().length > ProfileCipher.NAME_PADDED_LENGTH) {
|
} else if (s.toString().getBytes().length > ProfileCipher.NAME_PADDED_LENGTH) {
|
||||||
name.getInput().setError(getString(R.string.CreateProfileActivity_too_long));
|
name.getInput().setError(getString(R.string.CreateProfileActivity_too_long));
|
||||||
finishButton.setEnabled(false);
|
finishButton.setEnabled(false);
|
||||||
|
@ -44,10 +44,13 @@ public abstract class Attachment {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private final StickerLocator stickerLocator;
|
private final StickerLocator stickerLocator;
|
||||||
|
|
||||||
|
// Loki
|
||||||
|
private final String url;
|
||||||
|
|
||||||
public Attachment(@NonNull String contentType, int transferState, long size, @Nullable String fileName,
|
public Attachment(@NonNull String contentType, int transferState, long size, @Nullable String fileName,
|
||||||
@Nullable String location, @Nullable String key, @Nullable String relay,
|
@Nullable String location, @Nullable String key, @Nullable String relay,
|
||||||
@Nullable byte[] digest, @Nullable String fastPreflightId, boolean voiceNote,
|
@Nullable byte[] digest, @Nullable String fastPreflightId, boolean voiceNote,
|
||||||
int width, int height, boolean quote, @Nullable String caption, @Nullable StickerLocator stickerLocator)
|
int width, int height, boolean quote, @Nullable String caption, @Nullable StickerLocator stickerLocator, String url)
|
||||||
{
|
{
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
this.transferState = transferState;
|
this.transferState = transferState;
|
||||||
@ -64,6 +67,7 @@ public abstract class Attachment {
|
|||||||
this.quote = quote;
|
this.quote = quote;
|
||||||
this.stickerLocator = stickerLocator;
|
this.stickerLocator = stickerLocator;
|
||||||
this.caption = caption;
|
this.caption = caption;
|
||||||
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -147,4 +151,6 @@ public abstract class Attachment {
|
|||||||
public @Nullable String getCaption() {
|
public @Nullable String getCaption() {
|
||||||
return caption;
|
return caption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUrl() { return url; }
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ public class DatabaseAttachment extends Attachment {
|
|||||||
String fileName, String location, String key, String relay,
|
String fileName, String location, String key, String relay,
|
||||||
byte[] digest, String fastPreflightId, boolean voiceNote,
|
byte[] digest, String fastPreflightId, boolean voiceNote,
|
||||||
int width, int height, boolean quote, @Nullable String caption,
|
int width, int height, boolean quote, @Nullable String caption,
|
||||||
@Nullable StickerLocator stickerLocator)
|
@Nullable StickerLocator stickerLocator, String url)
|
||||||
{
|
{
|
||||||
super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator);
|
super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator, url);
|
||||||
this.attachmentId = attachmentId;
|
this.attachmentId = attachmentId;
|
||||||
this.hasData = hasData;
|
this.hasData = hasData;
|
||||||
this.hasThumbnail = hasThumbnail;
|
this.hasThumbnail = hasThumbnail;
|
||||||
|
@ -10,7 +10,7 @@ import org.thoughtcrime.securesms.database.MmsDatabase;
|
|||||||
public class MmsNotificationAttachment extends Attachment {
|
public class MmsNotificationAttachment extends Attachment {
|
||||||
|
|
||||||
public MmsNotificationAttachment(int status, long size) {
|
public MmsNotificationAttachment(int status, long size) {
|
||||||
super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null, false, 0, 0, false, null, null);
|
super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null, false, 0, 0, false, null, null, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -20,9 +20,9 @@ public class PointerAttachment extends Attachment {
|
|||||||
@Nullable String fileName, @NonNull String location,
|
@Nullable String fileName, @NonNull String location,
|
||||||
@Nullable String key, @Nullable String relay,
|
@Nullable String key, @Nullable String relay,
|
||||||
@Nullable byte[] digest, @Nullable String fastPreflightId, boolean voiceNote,
|
@Nullable byte[] digest, @Nullable String fastPreflightId, boolean voiceNote,
|
||||||
int width, int height, @Nullable String caption, @Nullable StickerLocator stickerLocator)
|
int width, int height, @Nullable String caption, @Nullable StickerLocator stickerLocator, String url)
|
||||||
{
|
{
|
||||||
super(contentType, transferState, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, false, caption, stickerLocator);
|
super(contentType, transferState, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, false, caption, stickerLocator, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -99,7 +99,8 @@ public class PointerAttachment extends Attachment {
|
|||||||
pointer.get().asPointer().getWidth(),
|
pointer.get().asPointer().getWidth(),
|
||||||
pointer.get().asPointer().getHeight(),
|
pointer.get().asPointer().getHeight(),
|
||||||
pointer.get().asPointer().getCaption().orNull(),
|
pointer.get().asPointer().getCaption().orNull(),
|
||||||
stickerLocator));
|
stickerLocator,
|
||||||
|
pointer.get().asPointer().getUrl()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +120,7 @@ public class PointerAttachment extends Attachment {
|
|||||||
thumbnail != null ? thumbnail.asPointer().getWidth() : 0,
|
thumbnail != null ? thumbnail.asPointer().getWidth() : 0,
|
||||||
thumbnail != null ? thumbnail.asPointer().getHeight() : 0,
|
thumbnail != null ? thumbnail.asPointer().getHeight() : 0,
|
||||||
thumbnail != null ? thumbnail.asPointer().getCaption().orNull() : null,
|
thumbnail != null ? thumbnail.asPointer().getCaption().orNull() : null,
|
||||||
null));
|
null,
|
||||||
|
thumbnail != null ? thumbnail.asPointer().getUrl() : ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ public class UriAttachment extends Attachment {
|
|||||||
@Nullable String fileName, @Nullable String fastPreflightId,
|
@Nullable String fileName, @Nullable String fastPreflightId,
|
||||||
boolean voiceNote, boolean quote, @Nullable String caption, @Nullable StickerLocator stickerLocator)
|
boolean voiceNote, boolean quote, @Nullable String caption, @Nullable StickerLocator stickerLocator)
|
||||||
{
|
{
|
||||||
super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator);
|
super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator, "");
|
||||||
this.dataUri = dataUri;
|
this.dataUri = dataUri;
|
||||||
this.thumbnailUri = thumbnailUri;
|
this.thumbnailUri = thumbnailUri;
|
||||||
}
|
}
|
||||||
|
@ -792,7 +792,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.menu_call_secure: handleDial(getRecipient(), true); return true;
|
case R.id.menu_call_secure: handleDial(getRecipient(), true); return true;
|
||||||
case R.id.menu_call_insecure: handleDial(getRecipient(), false); return true;
|
case R.id.menu_call_insecure: handleDial(getRecipient(), false); return true;
|
||||||
// case R.id.menu_view_media: handleViewMedia(); return true;
|
case R.id.menu_view_media: handleViewMedia(); return true;
|
||||||
case R.id.menu_add_shortcut: handleAddShortcut(); return true;
|
case R.id.menu_add_shortcut: handleAddShortcut(); return true;
|
||||||
case R.id.menu_search: handleSearch(); return true;
|
case R.id.menu_search: handleSearch(); return true;
|
||||||
case R.id.menu_add_to_contacts: handleAddToContacts(); return true;
|
case R.id.menu_add_to_contacts: handleAddToContacts(); return true;
|
||||||
@ -2189,6 +2189,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
|
|
||||||
private void updateInputPanel() {
|
private void updateInputPanel() {
|
||||||
boolean hasPendingFriendRequest = !recipient.isGroupRecipient() && DatabaseFactory.getLokiThreadDatabase(this).hasPendingFriendRequest(threadId);
|
boolean hasPendingFriendRequest = !recipient.isGroupRecipient() && DatabaseFactory.getLokiThreadDatabase(this).hasPendingFriendRequest(threadId);
|
||||||
|
updateToggleButtonState();
|
||||||
inputPanel.setEnabled(!hasPendingFriendRequest);
|
inputPanel.setEnabled(!hasPendingFriendRequest);
|
||||||
int hintID = hasPendingFriendRequest ? R.string.activity_conversation_pending_friend_request_hint : R.string.activity_conversation_default_hint;
|
int hintID = hasPendingFriendRequest ? R.string.activity_conversation_pending_friend_request_hint : R.string.activity_conversation_default_hint;
|
||||||
inputPanel.setHint(getResources().getString(hintID));
|
inputPanel.setHint(getResources().getString(hintID));
|
||||||
@ -2400,6 +2401,15 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateToggleButtonState() {
|
private void updateToggleButtonState() {
|
||||||
|
// Don't allow attachments if we're not friends
|
||||||
|
LokiThreadFriendRequestStatus friendRequestStatus = DatabaseFactory.getLokiThreadDatabase(this).getFriendRequestStatus(threadId);
|
||||||
|
if (!recipient.isGroupRecipient() && friendRequestStatus != LokiThreadFriendRequestStatus.FRIENDS) {
|
||||||
|
buttonToggle.display(sendButton);
|
||||||
|
quickAttachmentToggle.hide();
|
||||||
|
inlineAttachmentToggle.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (inputPanel.isRecordingInLockedMode()) {
|
if (inputPanel.isRecordingInLockedMode()) {
|
||||||
buttonToggle.display(sendButton);
|
buttonToggle.display(sendButton);
|
||||||
quickAttachmentToggle.show();
|
quickAttachmentToggle.show();
|
||||||
@ -2408,7 +2418,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (composeText.getText().length() == 0 && !attachmentManager.isAttachmentPresent()) {
|
if (composeText.getText().length() == 0 && !attachmentManager.isAttachmentPresent()) {
|
||||||
buttonToggle.display(sendButton);
|
buttonToggle.display(attachButton);
|
||||||
quickAttachmentToggle.show();
|
quickAttachmentToggle.show();
|
||||||
inlineAttachmentToggle.hide();
|
inlineAttachmentToggle.hide();
|
||||||
} else {
|
} else {
|
||||||
|
@ -473,7 +473,7 @@ public class ConversationItem extends LinearLayout
|
|||||||
|
|
||||||
if (isCaptionlessMms(messageRecord)) {
|
if (isCaptionlessMms(messageRecord)) {
|
||||||
bodyText.setVisibility(View.GONE);
|
bodyText.setVisibility(View.GONE);
|
||||||
} else { ;
|
} else {
|
||||||
Spannable text = MentionUtilities.highlightMentions(linkifyMessageBody(messageRecord.getDisplayBody(context), batchSelected.isEmpty()), messageRecord.isOutgoing(), messageRecord.getThreadId(), context);
|
Spannable text = MentionUtilities.highlightMentions(linkifyMessageBody(messageRecord.getDisplayBody(context), batchSelected.isEmpty()), messageRecord.isOutgoing(), messageRecord.getThreadId(), context);
|
||||||
text = SearchUtil.getHighlightedSpan(locale, () -> new BackgroundColorSpan(Color.YELLOW), text, searchQuery);
|
text = SearchUtil.getHighlightedSpan(locale, () -> new BackgroundColorSpan(Color.YELLOW), text, searchQuery);
|
||||||
text = SearchUtil.getHighlightedSpan(locale, () -> new ForegroundColorSpan(Color.BLACK), text, searchQuery);
|
text = SearchUtil.getHighlightedSpan(locale, () -> new ForegroundColorSpan(Color.BLACK), text, searchQuery);
|
||||||
|
@ -103,7 +103,7 @@ public class AttachmentDatabase extends Database {
|
|||||||
static final String WIDTH = "width";
|
static final String WIDTH = "width";
|
||||||
static final String HEIGHT = "height";
|
static final String HEIGHT = "height";
|
||||||
static final String CAPTION = "caption";
|
static final String CAPTION = "caption";
|
||||||
|
public static final String URL = "url";
|
||||||
public static final String DIRECTORY = "parts";
|
public static final String DIRECTORY = "parts";
|
||||||
|
|
||||||
public static final int TRANSFER_PROGRESS_DONE = 0;
|
public static final int TRANSFER_PROGRESS_DONE = 0;
|
||||||
@ -119,7 +119,7 @@ public class AttachmentDatabase extends Database {
|
|||||||
SIZE, FILE_NAME, THUMBNAIL, THUMBNAIL_ASPECT_RATIO,
|
SIZE, FILE_NAME, THUMBNAIL, THUMBNAIL_ASPECT_RATIO,
|
||||||
UNIQUE_ID, DIGEST, FAST_PREFLIGHT_ID, VOICE_NOTE,
|
UNIQUE_ID, DIGEST, FAST_PREFLIGHT_ID, VOICE_NOTE,
|
||||||
QUOTE, DATA_RANDOM, THUMBNAIL_RANDOM, WIDTH, HEIGHT,
|
QUOTE, DATA_RANDOM, THUMBNAIL_RANDOM, WIDTH, HEIGHT,
|
||||||
CAPTION, STICKER_PACK_ID, STICKER_PACK_KEY, STICKER_ID};
|
CAPTION, STICKER_PACK_ID, STICKER_PACK_KEY, STICKER_ID, URL};
|
||||||
|
|
||||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " +
|
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " +
|
||||||
MMS_ID + " INTEGER, " + "seq" + " INTEGER DEFAULT 0, " +
|
MMS_ID + " INTEGER, " + "seq" + " INTEGER DEFAULT 0, " +
|
||||||
@ -132,7 +132,7 @@ public class AttachmentDatabase extends Database {
|
|||||||
UNIQUE_ID + " INTEGER NOT NULL, " + DIGEST + " BLOB, " + FAST_PREFLIGHT_ID + " TEXT, " +
|
UNIQUE_ID + " INTEGER NOT NULL, " + DIGEST + " BLOB, " + FAST_PREFLIGHT_ID + " TEXT, " +
|
||||||
VOICE_NOTE + " INTEGER DEFAULT 0, " + DATA_RANDOM + " BLOB, " + THUMBNAIL_RANDOM + " BLOB, " +
|
VOICE_NOTE + " INTEGER DEFAULT 0, " + DATA_RANDOM + " BLOB, " + THUMBNAIL_RANDOM + " BLOB, " +
|
||||||
QUOTE + " INTEGER DEFAULT 0, " + WIDTH + " INTEGER DEFAULT 0, " + HEIGHT + " INTEGER DEFAULT 0, " +
|
QUOTE + " INTEGER DEFAULT 0, " + WIDTH + " INTEGER DEFAULT 0, " + HEIGHT + " INTEGER DEFAULT 0, " +
|
||||||
CAPTION + " TEXT DEFAULT NULL, " + STICKER_PACK_ID + " TEXT DEFAULT NULL, " +
|
CAPTION + " TEXT DEFAULT NULL, " + URL + " TEXT, " + STICKER_PACK_ID + " TEXT DEFAULT NULL, " +
|
||||||
STICKER_PACK_KEY + " DEFAULT NULL, " + STICKER_ID + " INTEGER DEFAULT -1);";
|
STICKER_PACK_KEY + " DEFAULT NULL, " + STICKER_ID + " INTEGER DEFAULT -1);";
|
||||||
|
|
||||||
public static final String[] CREATE_INDEXS = {
|
public static final String[] CREATE_INDEXS = {
|
||||||
@ -361,6 +361,7 @@ public class AttachmentDatabase extends Database {
|
|||||||
values.put(DIGEST, (byte[])null);
|
values.put(DIGEST, (byte[])null);
|
||||||
values.put(NAME, (String) null);
|
values.put(NAME, (String) null);
|
||||||
values.put(FAST_PREFLIGHT_ID, (String)null);
|
values.put(FAST_PREFLIGHT_ID, (String)null);
|
||||||
|
values.put(URL, "");
|
||||||
|
|
||||||
if (database.update(TABLE_NAME, values, PART_ID_WHERE, attachmentId.toStrings()) == 0) {
|
if (database.update(TABLE_NAME, values, PART_ID_WHERE, attachmentId.toStrings()) == 0) {
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
@ -384,6 +385,7 @@ public class AttachmentDatabase extends Database {
|
|||||||
values.put(NAME, attachment.getRelay());
|
values.put(NAME, attachment.getRelay());
|
||||||
values.put(SIZE, attachment.getSize());
|
values.put(SIZE, attachment.getSize());
|
||||||
values.put(FAST_PREFLIGHT_ID, attachment.getFastPreflightId());
|
values.put(FAST_PREFLIGHT_ID, attachment.getFastPreflightId());
|
||||||
|
values.put(URL, attachment.getUrl());
|
||||||
|
|
||||||
database.update(TABLE_NAME, values, PART_ID_WHERE, id.toStrings());
|
database.update(TABLE_NAME, values, PART_ID_WHERE, id.toStrings());
|
||||||
}
|
}
|
||||||
@ -451,7 +453,8 @@ public class AttachmentDatabase extends Database {
|
|||||||
mediaStream.getHeight(),
|
mediaStream.getHeight(),
|
||||||
databaseAttachment.isQuote(),
|
databaseAttachment.isQuote(),
|
||||||
databaseAttachment.getCaption(),
|
databaseAttachment.getCaption(),
|
||||||
databaseAttachment.getSticker());
|
databaseAttachment.getSticker(),
|
||||||
|
databaseAttachment.getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -650,12 +653,13 @@ public class AttachmentDatabase extends Database {
|
|||||||
? new StickerLocator(object.getString(STICKER_PACK_ID),
|
? new StickerLocator(object.getString(STICKER_PACK_ID),
|
||||||
object.getString(STICKER_PACK_KEY),
|
object.getString(STICKER_PACK_KEY),
|
||||||
object.getInt(STICKER_ID))
|
object.getInt(STICKER_ID))
|
||||||
: null));
|
: null, "")); // TODO: Not sure if this will break something
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
int urlIndex = cursor.getColumnIndex(URL);
|
||||||
return Collections.singletonList(new DatabaseAttachment(new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(ROW_ID)),
|
return Collections.singletonList(new DatabaseAttachment(new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(ROW_ID)),
|
||||||
cursor.getLong(cursor.getColumnIndexOrThrow(UNIQUE_ID))),
|
cursor.getLong(cursor.getColumnIndexOrThrow(UNIQUE_ID))),
|
||||||
cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID)),
|
cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID)),
|
||||||
@ -679,7 +683,8 @@ public class AttachmentDatabase extends Database {
|
|||||||
? new StickerLocator(cursor.getString(cursor.getColumnIndexOrThrow(STICKER_PACK_ID)),
|
? new StickerLocator(cursor.getString(cursor.getColumnIndexOrThrow(STICKER_PACK_ID)),
|
||||||
cursor.getString(cursor.getColumnIndexOrThrow(STICKER_PACK_KEY)),
|
cursor.getString(cursor.getColumnIndexOrThrow(STICKER_PACK_KEY)),
|
||||||
cursor.getInt(cursor.getColumnIndexOrThrow(STICKER_ID)))
|
cursor.getInt(cursor.getColumnIndexOrThrow(STICKER_ID)))
|
||||||
: null));
|
: null,
|
||||||
|
urlIndex > 0 ? cursor.getString(urlIndex) : ""));
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
@ -718,6 +723,7 @@ public class AttachmentDatabase extends Database {
|
|||||||
contentValues.put(HEIGHT, attachment.getHeight());
|
contentValues.put(HEIGHT, attachment.getHeight());
|
||||||
contentValues.put(QUOTE, quote);
|
contentValues.put(QUOTE, quote);
|
||||||
contentValues.put(CAPTION, attachment.getCaption());
|
contentValues.put(CAPTION, attachment.getCaption());
|
||||||
|
contentValues.put(URL, attachment.getUrl());
|
||||||
|
|
||||||
if (attachment.isSticker()) {
|
if (attachment.isSticker()) {
|
||||||
contentValues.put(STICKER_PACK_ID, attachment.getSticker().getPackId());
|
contentValues.put(STICKER_PACK_ID, attachment.getSticker().getPackId());
|
||||||
|
@ -50,6 +50,9 @@ public class GroupDatabase extends Database {
|
|||||||
private static final String ACTIVE = "active";
|
private static final String ACTIVE = "active";
|
||||||
private static final String MMS = "mms";
|
private static final String MMS = "mms";
|
||||||
|
|
||||||
|
// Loki
|
||||||
|
private static final String AVATAR_URL = "avatar_url";
|
||||||
|
|
||||||
public static final String CREATE_TABLE =
|
public static final String CREATE_TABLE =
|
||||||
"CREATE TABLE " + TABLE_NAME +
|
"CREATE TABLE " + TABLE_NAME +
|
||||||
" (" + ID + " INTEGER PRIMARY KEY, " +
|
" (" + ID + " INTEGER PRIMARY KEY, " +
|
||||||
@ -64,6 +67,7 @@ public class GroupDatabase extends Database {
|
|||||||
TIMESTAMP + " INTEGER, " +
|
TIMESTAMP + " INTEGER, " +
|
||||||
ACTIVE + " INTEGER DEFAULT 1, " +
|
ACTIVE + " INTEGER DEFAULT 1, " +
|
||||||
AVATAR_DIGEST + " BLOB, " +
|
AVATAR_DIGEST + " BLOB, " +
|
||||||
|
AVATAR_URL + " TEXT, " +
|
||||||
MMS + " INTEGER DEFAULT 0);";
|
MMS + " INTEGER DEFAULT 0);";
|
||||||
|
|
||||||
public static final String[] CREATE_INDEXS = {
|
public static final String[] CREATE_INDEXS = {
|
||||||
@ -72,7 +76,7 @@ public class GroupDatabase extends Database {
|
|||||||
|
|
||||||
private static final String[] GROUP_PROJECTION = {
|
private static final String[] GROUP_PROJECTION = {
|
||||||
GROUP_ID, TITLE, MEMBERS, AVATAR, AVATAR_ID, AVATAR_KEY, AVATAR_CONTENT_TYPE, AVATAR_RELAY, AVATAR_DIGEST,
|
GROUP_ID, TITLE, MEMBERS, AVATAR, AVATAR_ID, AVATAR_KEY, AVATAR_CONTENT_TYPE, AVATAR_RELAY, AVATAR_DIGEST,
|
||||||
TIMESTAMP, ACTIVE, MMS
|
TIMESTAMP, ACTIVE, MMS, AVATAR_URL
|
||||||
};
|
};
|
||||||
|
|
||||||
static final List<String> TYPED_GROUP_PROJECTION = Stream.of(GROUP_PROJECTION).map(columnName -> TABLE_NAME + "." + columnName).toList();
|
static final List<String> TYPED_GROUP_PROJECTION = Stream.of(GROUP_PROJECTION).map(columnName -> TABLE_NAME + "." + columnName).toList();
|
||||||
@ -167,6 +171,7 @@ public class GroupDatabase extends Database {
|
|||||||
contentValues.put(AVATAR_KEY, avatar.getKey());
|
contentValues.put(AVATAR_KEY, avatar.getKey());
|
||||||
contentValues.put(AVATAR_CONTENT_TYPE, avatar.getContentType());
|
contentValues.put(AVATAR_CONTENT_TYPE, avatar.getContentType());
|
||||||
contentValues.put(AVATAR_DIGEST, avatar.getDigest().orNull());
|
contentValues.put(AVATAR_DIGEST, avatar.getDigest().orNull());
|
||||||
|
contentValues.put(AVATAR_URL, avatar.getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
contentValues.put(AVATAR_RELAY, relay);
|
contentValues.put(AVATAR_RELAY, relay);
|
||||||
@ -194,6 +199,7 @@ public class GroupDatabase extends Database {
|
|||||||
contentValues.put(AVATAR_CONTENT_TYPE, avatar.getContentType());
|
contentValues.put(AVATAR_CONTENT_TYPE, avatar.getContentType());
|
||||||
contentValues.put(AVATAR_KEY, avatar.getKey());
|
contentValues.put(AVATAR_KEY, avatar.getKey());
|
||||||
contentValues.put(AVATAR_DIGEST, avatar.getDigest().orNull());
|
contentValues.put(AVATAR_DIGEST, avatar.getDigest().orNull());
|
||||||
|
contentValues.put(AVATAR_URL, avatar.getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues,
|
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues,
|
||||||
@ -344,7 +350,8 @@ public class GroupDatabase extends Database {
|
|||||||
cursor.getString(cursor.getColumnIndexOrThrow(AVATAR_RELAY)),
|
cursor.getString(cursor.getColumnIndexOrThrow(AVATAR_RELAY)),
|
||||||
cursor.getInt(cursor.getColumnIndexOrThrow(ACTIVE)) == 1,
|
cursor.getInt(cursor.getColumnIndexOrThrow(ACTIVE)) == 1,
|
||||||
cursor.getBlob(cursor.getColumnIndexOrThrow(AVATAR_DIGEST)),
|
cursor.getBlob(cursor.getColumnIndexOrThrow(AVATAR_DIGEST)),
|
||||||
cursor.getInt(cursor.getColumnIndexOrThrow(MMS)) == 1);
|
cursor.getInt(cursor.getColumnIndexOrThrow(MMS)) == 1,
|
||||||
|
cursor.getString(cursor.getColumnIndexOrThrow(AVATAR_URL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -367,10 +374,11 @@ public class GroupDatabase extends Database {
|
|||||||
private final String relay;
|
private final String relay;
|
||||||
private final boolean active;
|
private final boolean active;
|
||||||
private final boolean mms;
|
private final boolean mms;
|
||||||
|
private final String url;
|
||||||
|
|
||||||
public GroupRecord(String id, String title, String members, byte[] avatar,
|
public GroupRecord(String id, String title, String members, byte[] avatar,
|
||||||
long avatarId, byte[] avatarKey, String avatarContentType,
|
long avatarId, byte[] avatarKey, String avatarContentType,
|
||||||
String relay, boolean active, byte[] avatarDigest, boolean mms)
|
String relay, boolean active, byte[] avatarDigest, boolean mms, String url)
|
||||||
{
|
{
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
@ -382,6 +390,7 @@ public class GroupDatabase extends Database {
|
|||||||
this.relay = relay;
|
this.relay = relay;
|
||||||
this.active = active;
|
this.active = active;
|
||||||
this.mms = mms;
|
this.mms = mms;
|
||||||
|
this.url = url;
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(members)) this.members = Address.fromSerializedList(members, ',');
|
if (!TextUtils.isEmpty(members)) this.members = Address.fromSerializedList(members, ',');
|
||||||
else this.members = new LinkedList<>();
|
else this.members = new LinkedList<>();
|
||||||
@ -438,5 +447,7 @@ public class GroupDatabase extends Database {
|
|||||||
public boolean isMms() {
|
public boolean isMms() {
|
||||||
return mms;
|
return mms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUrl() { return url; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -778,7 +778,8 @@ public class MmsDatabase extends MessagingDatabase {
|
|||||||
databaseAttachment.getHeight(),
|
databaseAttachment.getHeight(),
|
||||||
databaseAttachment.isQuote(),
|
databaseAttachment.isQuote(),
|
||||||
databaseAttachment.getCaption(),
|
databaseAttachment.getCaption(),
|
||||||
databaseAttachment.getSticker()));
|
databaseAttachment.getSticker(),
|
||||||
|
databaseAttachment.getUrl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return insertMediaMessage(request.getBody(),
|
return insertMediaMessage(request.getBody(),
|
||||||
|
@ -98,7 +98,7 @@ public class MmsSmsDatabase extends Database {
|
|||||||
|
|
||||||
public Cursor getConversation(long threadId, long offset, long limit) {
|
public Cursor getConversation(long threadId, long offset, long limit) {
|
||||||
String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
|
String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
|
||||||
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND LENGTH(" + MmsSmsColumns.BODY + ") > 0";
|
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId;
|
||||||
String limitStr = limit > 0 || offset > 0 ? offset + ", " + limit : null;
|
String limitStr = limit > 0 || offset > 0 ? offset + ", " + limit : null;
|
||||||
|
|
||||||
Cursor cursor = queryTables(PROJECTION, selection, order, limitStr);
|
Cursor cursor = queryTables(PROJECTION, selection, order, limitStr);
|
||||||
|
@ -499,6 +499,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
if (oldVersion < lokiV3) {
|
if (oldVersion < lokiV3) {
|
||||||
db.execSQL(LokiAPIDatabase.getCreatePairingAuthorisationTableCommand());
|
db.execSQL(LokiAPIDatabase.getCreatePairingAuthorisationTableCommand());
|
||||||
db.execSQL(LokiThreadDatabase.getCreatePublicChatTableCommand());
|
db.execSQL(LokiThreadDatabase.getCreatePublicChatTableCommand());
|
||||||
|
|
||||||
|
db.execSQL("ALTER TABLE groups ADD COLUMN avatar_url TEXT");
|
||||||
|
db.execSQL("ALTER TABLE part ADD COLUMN url TEXT");
|
||||||
}
|
}
|
||||||
|
|
||||||
db.setTransactionSuccessful();
|
db.setTransactionSuccessful();
|
||||||
|
@ -183,16 +183,29 @@ public class AttachmentDownloadJob extends BaseJob implements InjectableType {
|
|||||||
SignalServiceAttachmentPointer createAttachmentPointer(Attachment attachment)
|
SignalServiceAttachmentPointer createAttachmentPointer(Attachment attachment)
|
||||||
throws InvalidPartException
|
throws InvalidPartException
|
||||||
{
|
{
|
||||||
|
boolean isPublicAttachment = TextUtils.isEmpty(attachment.getKey()) && attachment.getDigest() == null;
|
||||||
|
|
||||||
if (TextUtils.isEmpty(attachment.getLocation())) {
|
if (TextUtils.isEmpty(attachment.getLocation())) {
|
||||||
throw new InvalidPartException("empty content id");
|
throw new InvalidPartException("empty content id");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextUtils.isEmpty(attachment.getKey())) {
|
if (TextUtils.isEmpty(attachment.getKey()) && !isPublicAttachment) {
|
||||||
throw new InvalidPartException("empty encrypted key");
|
throw new InvalidPartException("empty encrypted key");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
long id = Long.parseLong(attachment.getLocation());
|
long id = Long.parseLong(attachment.getLocation());
|
||||||
|
if (isPublicAttachment) {
|
||||||
|
return new SignalServiceAttachmentPointer(id, null, new byte[0],
|
||||||
|
Optional.of(Util.toIntExact(attachment.getSize())),
|
||||||
|
Optional.absent(),
|
||||||
|
0, 0,
|
||||||
|
Optional.fromNullable(attachment.getDigest()),
|
||||||
|
Optional.fromNullable(attachment.getFileName()),
|
||||||
|
attachment.isVoiceNote(),
|
||||||
|
Optional.absent(), attachment.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
byte[] key = Base64.decode(attachment.getKey());
|
byte[] key = Base64.decode(attachment.getKey());
|
||||||
String relay = null;
|
String relay = null;
|
||||||
|
|
||||||
@ -213,7 +226,7 @@ public class AttachmentDownloadJob extends BaseJob implements InjectableType {
|
|||||||
Optional.fromNullable(attachment.getDigest()),
|
Optional.fromNullable(attachment.getDigest()),
|
||||||
Optional.fromNullable(attachment.getFileName()),
|
Optional.fromNullable(attachment.getFileName()),
|
||||||
attachment.isVoiceNote(),
|
attachment.isVoiceNote(),
|
||||||
Optional.absent());
|
Optional.absent(), attachment.getUrl());
|
||||||
} catch (IOException | ArithmeticException e) {
|
} catch (IOException | ArithmeticException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
throw new InvalidPartException(e);
|
throw new InvalidPartException(e);
|
||||||
|
@ -7,6 +7,7 @@ import org.thoughtcrime.securesms.attachments.Attachment;
|
|||||||
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
||||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||||
import org.thoughtcrime.securesms.attachments.PointerAttachment;
|
import org.thoughtcrime.securesms.attachments.PointerAttachment;
|
||||||
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
@ -25,6 +26,7 @@ import org.whispersystems.libsignal.util.guava.Optional;
|
|||||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
||||||
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -38,30 +40,34 @@ public class AttachmentUploadJob extends BaseJob implements InjectableType {
|
|||||||
|
|
||||||
private static final String TAG = AttachmentUploadJob.class.getSimpleName();
|
private static final String TAG = AttachmentUploadJob.class.getSimpleName();
|
||||||
|
|
||||||
private static final String KEY_ROW_ID = "row_id";
|
private static final String KEY_ROW_ID = "row_id";
|
||||||
private static final String KEY_UNIQUE_ID = "unique_id";
|
private static final String KEY_UNIQUE_ID = "unique_id";
|
||||||
|
private static final String KEY_DESTINATION = "destination";
|
||||||
|
|
||||||
private AttachmentId attachmentId;
|
private AttachmentId attachmentId;
|
||||||
|
private Address destination;
|
||||||
@Inject SignalServiceMessageSender messageSender;
|
@Inject SignalServiceMessageSender messageSender;
|
||||||
|
|
||||||
public AttachmentUploadJob(AttachmentId attachmentId) {
|
public AttachmentUploadJob(AttachmentId attachmentId, Address destination) {
|
||||||
this(new Job.Parameters.Builder()
|
this(new Job.Parameters.Builder()
|
||||||
.addConstraint(NetworkConstraint.KEY)
|
.addConstraint(NetworkConstraint.KEY)
|
||||||
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
||||||
.setMaxAttempts(Parameters.UNLIMITED)
|
.setMaxAttempts(3)
|
||||||
.build(),
|
.build(),
|
||||||
attachmentId);
|
attachmentId, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AttachmentUploadJob(@NonNull Job.Parameters parameters, @NonNull AttachmentId attachmentId) {
|
private AttachmentUploadJob(@NonNull Job.Parameters parameters, @NonNull AttachmentId attachmentId, Address destination) {
|
||||||
super(parameters);
|
super(parameters);
|
||||||
this.attachmentId = attachmentId;
|
this.attachmentId = attachmentId;
|
||||||
|
this.destination = destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull Data serialize() {
|
public @NonNull Data serialize() {
|
||||||
return new Data.Builder().putLong(KEY_ROW_ID, attachmentId.getRowId())
|
return new Data.Builder().putLong(KEY_ROW_ID, attachmentId.getRowId())
|
||||||
.putLong(KEY_UNIQUE_ID, attachmentId.getUniqueId())
|
.putLong(KEY_UNIQUE_ID, attachmentId.getUniqueId())
|
||||||
|
.putString(KEY_DESTINATION, destination.serialize())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +88,7 @@ public class AttachmentUploadJob extends BaseJob implements InjectableType {
|
|||||||
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
|
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
|
||||||
Attachment scaledAttachment = scaleAndStripExif(database, mediaConstraints, databaseAttachment);
|
Attachment scaledAttachment = scaleAndStripExif(database, mediaConstraints, databaseAttachment);
|
||||||
SignalServiceAttachment localAttachment = getAttachmentFor(scaledAttachment);
|
SignalServiceAttachment localAttachment = getAttachmentFor(scaledAttachment);
|
||||||
SignalServiceAttachmentPointer remoteAttachment = messageSender.uploadAttachment(localAttachment.asStream(), databaseAttachment.isSticker());
|
SignalServiceAttachmentPointer remoteAttachment = messageSender.uploadAttachment(localAttachment.asStream(), databaseAttachment.isSticker(), new SignalServiceAddress(destination.serialize()));
|
||||||
Attachment attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.getFastPreflightId()).get();
|
Attachment attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.getFastPreflightId()).get();
|
||||||
|
|
||||||
database.updateAttachmentAfterUpload(databaseAttachment.getAttachmentId(), attachment);
|
database.updateAttachmentAfterUpload(databaseAttachment.getAttachmentId(), attachment);
|
||||||
@ -144,7 +150,7 @@ public class AttachmentUploadJob extends BaseJob implements InjectableType {
|
|||||||
public static final class Factory implements Job.Factory<AttachmentUploadJob> {
|
public static final class Factory implements Job.Factory<AttachmentUploadJob> {
|
||||||
@Override
|
@Override
|
||||||
public @NonNull AttachmentUploadJob create(@NonNull Parameters parameters, @NonNull org.thoughtcrime.securesms.jobmanager.Data data) {
|
public @NonNull AttachmentUploadJob create(@NonNull Parameters parameters, @NonNull org.thoughtcrime.securesms.jobmanager.Data data) {
|
||||||
return new AttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)));
|
return new AttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)), Address.fromSerialized(data.getString(KEY_DESTINATION)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,9 @@ public class AvatarDownloadJob extends BaseJob implements InjectableType {
|
|||||||
String relay = record.get().getRelay();
|
String relay = record.get().getRelay();
|
||||||
Optional<byte[]> digest = Optional.fromNullable(record.get().getAvatarDigest());
|
Optional<byte[]> digest = Optional.fromNullable(record.get().getAvatarDigest());
|
||||||
Optional<String> fileName = Optional.absent();
|
Optional<String> fileName = Optional.absent();
|
||||||
|
String url = record.get().getUrl();
|
||||||
|
|
||||||
if (avatarId == -1 || key == null) {
|
if (avatarId == -1 || key == null || url.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ public class AvatarDownloadJob extends BaseJob implements InjectableType {
|
|||||||
attachment = File.createTempFile("avatar", "tmp", context.getCacheDir());
|
attachment = File.createTempFile("avatar", "tmp", context.getCacheDir());
|
||||||
attachment.deleteOnExit();
|
attachment.deleteOnExit();
|
||||||
|
|
||||||
SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, Optional.absent());
|
SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, Optional.absent(), url);
|
||||||
InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, MAX_AVATAR_SIZE);
|
InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, MAX_AVATAR_SIZE);
|
||||||
Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key, 0, digest), 500, 500);
|
Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key, 0, digest), 500, 500);
|
||||||
|
|
||||||
|
@ -64,7 +64,6 @@ import org.thoughtcrime.securesms.jobmanager.Job;
|
|||||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||||
import org.thoughtcrime.securesms.linkpreview.Link;
|
import org.thoughtcrime.securesms.linkpreview.Link;
|
||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
|
|
||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
|
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
import org.thoughtcrime.securesms.loki.LokiAPIUtilities;
|
import org.thoughtcrime.securesms.loki.LokiAPIUtilities;
|
||||||
@ -760,41 +759,14 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
message.getExpiresInSeconds() * 1000L, false, content.isNeedsReceipt(), message.getBody(), message.getGroupInfo(), message.getAttachments(),
|
message.getExpiresInSeconds() * 1000L, false, content.isNeedsReceipt(), message.getBody(), message.getGroupInfo(), message.getAttachments(),
|
||||||
quote, sharedContacts, linkPreviews, sticker);
|
quote, sharedContacts, linkPreviews, sticker);
|
||||||
|
|
||||||
if (linkPreviews.isPresent()) {
|
|
||||||
int linkPreviewCount = linkPreviews.get().size();
|
|
||||||
if (linkPreviewCount != 0) {
|
|
||||||
LinkPreviewRepository lpr = new LinkPreviewRepository(context);
|
|
||||||
final int[] count = { 0 };
|
|
||||||
for (LinkPreview linkPreview : linkPreviews.get()) {
|
|
||||||
lpr.getLinkPreview(context, linkPreview.getUrl(), lp -> Util.runOnMain(() -> {
|
|
||||||
int c = count[0];
|
|
||||||
c = c + 1;
|
|
||||||
count[0] = c;
|
|
||||||
if (lp.isPresent() && lp.get().getThumbnail().isPresent()) {
|
|
||||||
Attachment thumbnail = lp.get().getThumbnail().get();
|
|
||||||
linkPreview.thumbnail = Optional.of(thumbnail);
|
|
||||||
}
|
|
||||||
if (c == linkPreviewCount) {
|
|
||||||
try {
|
|
||||||
handleMediaMessage(content, mediaMessage, smsMessageId, messageServerIDOrNull);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// TODO: Handle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
handleMediaMessage(content, mediaMessage, smsMessageId, messageServerIDOrNull);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
handleMediaMessage(content, mediaMessage, smsMessageId, messageServerIDOrNull);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleMediaMessage(@NonNull SignalServiceContent content, @NonNull IncomingMediaMessage mediaMessage, @NonNull Optional<Long> smsMessageID, @Nullable Optional<Long> messageServerIDOrNull) throws StorageFailedException {
|
|
||||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||||
database.beginTransaction();
|
database.beginTransaction();
|
||||||
|
|
||||||
|
// Ignore message if it has no body and no attachments or anything
|
||||||
|
if (mediaMessage.getBody().isEmpty() && mediaMessage.getAttachments().isEmpty() && mediaMessage.getSharedContacts().isEmpty() && mediaMessage.getLinkPreviews().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Optional<InsertResult> insertResult;
|
Optional<InsertResult> insertResult;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -811,8 +783,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
ApplicationContext.getInstance(context).getJobManager().add(new AttachmentDownloadJob(insertResult.get().getMessageId(), attachment.getAttachmentId(), false));
|
ApplicationContext.getInstance(context).getJobManager().add(new AttachmentDownloadJob(insertResult.get().getMessageId(), attachment.getAttachmentId(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smsMessageID.isPresent()) {
|
if (smsMessageId.isPresent()) {
|
||||||
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageID.get());
|
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
database.setTransactionSuccessful();
|
database.setTransactionSuccessful();
|
||||||
@ -962,79 +934,30 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
|
|
||||||
IncomingEncryptedMessage textMessage = new IncomingEncryptedMessage(_textMessage, body);
|
IncomingEncryptedMessage textMessage = new IncomingEncryptedMessage(_textMessage, body);
|
||||||
|
|
||||||
List<Link> urls = LinkPreviewUtil.findWhitelistedUrls(body);
|
// Ignore the message if the body is empty
|
||||||
int urlCount = urls.size();
|
if (textMessage.getMessageBody().length() == 0) { return; }
|
||||||
if (urlCount != 0) {
|
|
||||||
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(Address.fromExternal(context, content.getSender()), message.getTimestamp(), -1,
|
// Insert the message into the database
|
||||||
message.getExpiresInSeconds() * 1000L, false, content.isNeedsReceipt(), message.getBody(), message.getGroupInfo(), message.getAttachments(),
|
Optional<InsertResult> insertResult = database.insertMessageInbox(textMessage);
|
||||||
Optional.absent(), Optional.absent(), Optional.of(new ArrayList<>()), Optional.absent());
|
|
||||||
LinkPreviewRepository lpr = new LinkPreviewRepository(context);
|
if (insertResult.isPresent()) threadId = insertResult.get().getThreadId();
|
||||||
final int[] count = { 0 };
|
else threadId = null;
|
||||||
for (Link url : urls) {
|
|
||||||
lpr.getLinkPreview(context, url.getUrl(), lp -> Util.runOnMain(() -> {
|
if (smsMessageId.isPresent()) database.deleteMessage(smsMessageId.get());
|
||||||
int c = count[0];
|
|
||||||
c = c + 1;
|
// Loki - Cache the user hex encoded public key (for mentions)
|
||||||
count[0] = c;
|
if (threadId != null) {
|
||||||
if (lp.isPresent()) { mediaMessage.getLinkPreviews().add(lp.get()); }
|
LokiAPIUtilities.INSTANCE.populateUserHexEncodedPublicKeyCacheIfNeeded(threadId, context);
|
||||||
if (c == urlCount) {
|
LokiAPI.Companion.cache(textMessage.getSender().serialize(), threadId);
|
||||||
try {
|
|
||||||
handleMediaMessage(content, mediaMessage, smsMessageId, messageServerIDOrNull);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// TODO: Handle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
} else if (LinkPreviewUtil.isWhitelistedMediaUrl(body)) {
|
|
||||||
new LinkPreviewRepository(context).fetchGIF(context, body, attachmentOrNull -> Util.runOnMain(() -> {
|
|
||||||
if (attachmentOrNull.isPresent()) {
|
|
||||||
Attachment attachment = attachmentOrNull.get();
|
|
||||||
try {
|
|
||||||
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(Address.fromExternal(context, content.getSender()), message.getTimestamp(), -1,
|
|
||||||
message.getExpiresInSeconds() * 1000L, false, content.isNeedsReceipt(), message.getBody(), message.getGroupInfo(), Optional.of(new ArrayList<>()),
|
|
||||||
Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent());
|
|
||||||
mediaMessage.getAttachments().add(attachment);
|
|
||||||
handleMediaMessage(content, mediaMessage, smsMessageId, messageServerIDOrNull);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// TODO: Handle
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
handleTextMessage(message, textMessage, smsMessageId, messageServerIDOrNull);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
handleTextMessage(message, textMessage, smsMessageId, messageServerIDOrNull);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleTextMessage(@NonNull SignalServiceDataMessage message, @NonNull IncomingTextMessage textMessage, @NonNull Optional<Long> smsMessageId, @NonNull Optional<Long> messageServerIDOrNull) {
|
// Loki - Store message server ID
|
||||||
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
|
updateGroupChatMessageServerID(messageServerIDOrNull, insertResult);
|
||||||
|
|
||||||
// Ignore the message if the body is empty
|
boolean isGroupMessage = message.getGroupInfo().isPresent();
|
||||||
if (textMessage.getMessageBody().length() == 0) { return; }
|
if (threadId != null && !isGroupMessage) {
|
||||||
|
MessageNotifier.updateNotification(context, threadId);
|
||||||
// Insert the message into the database
|
}
|
||||||
Optional<InsertResult> insertResult = database.insertMessageInbox(textMessage);
|
|
||||||
|
|
||||||
Long threadId;
|
|
||||||
if (insertResult.isPresent()) threadId = insertResult.get().getThreadId();
|
|
||||||
else threadId = null;
|
|
||||||
|
|
||||||
if (smsMessageId.isPresent()) database.deleteMessage(smsMessageId.get());
|
|
||||||
|
|
||||||
// Loki - Cache the user hex encoded public key (for mentions)
|
|
||||||
if (threadId != null) {
|
|
||||||
LokiAPIUtilities.INSTANCE.populateUserHexEncodedPublicKeyCacheIfNeeded(threadId, context);
|
|
||||||
LokiAPI.Companion.cache(textMessage.getSender().serialize(), threadId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loki - Store message server ID
|
|
||||||
updateGroupChatMessageServerID(messageServerIDOrNull, insertResult);
|
|
||||||
|
|
||||||
boolean isGroupMessage = message.getGroupInfo().isPresent();
|
|
||||||
if (threadId != null && !isGroupMessage) {
|
|
||||||
MessageNotifier.updateNotification(context, threadId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,12 +96,11 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
|||||||
OutgoingMediaMessage message = database.getOutgoingMessage(messageId);
|
OutgoingMediaMessage message = database.getOutgoingMessage(messageId);
|
||||||
List<Attachment> attachments = new LinkedList<>();
|
List<Attachment> attachments = new LinkedList<>();
|
||||||
|
|
||||||
// Loki - For now all attachments are re-fetched by the receiver
|
attachments.addAll(message.getAttachments());
|
||||||
// attachments.addAll(message.getAttachments());
|
attachments.addAll(Stream.of(message.getLinkPreviews()).filter(p -> p.getThumbnail().isPresent()).map(p -> p.getThumbnail().get()).toList());
|
||||||
// attachments.addAll(Stream.of(message.getLinkPreviews()).filter(p -> p.getThumbnail().isPresent()).map(p -> p.getThumbnail().get()).toList());
|
|
||||||
attachments.addAll(Stream.of(message.getSharedContacts()).filter(c -> c.getAvatar() != null).map(c -> c.getAvatar().getAttachment()).withoutNulls().toList());
|
attachments.addAll(Stream.of(message.getSharedContacts()).filter(c -> c.getAvatar() != null).map(c -> c.getAvatar().getAttachment()).withoutNulls().toList());
|
||||||
|
|
||||||
List<AttachmentUploadJob> attachmentJobs = Stream.of(attachments).map(a -> new AttachmentUploadJob(((DatabaseAttachment) a).getAttachmentId())).toList();
|
List<AttachmentUploadJob> attachmentJobs = Stream.of(attachments).map(a -> new AttachmentUploadJob(((DatabaseAttachment) a).getAttachmentId(), destination)).toList();
|
||||||
|
|
||||||
if (attachmentJobs.isEmpty()) {
|
if (attachmentJobs.isEmpty()) {
|
||||||
jobManager.add(new PushGroupSendJob(messageId, destination, filterAddress));
|
jobManager.add(new PushGroupSendJob(messageId, destination, filterAddress));
|
||||||
|
@ -104,12 +104,11 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
|||||||
OutgoingMediaMessage message = database.getOutgoingMessage(messageId);
|
OutgoingMediaMessage message = database.getOutgoingMessage(messageId);
|
||||||
List<Attachment> attachments = new LinkedList<>();
|
List<Attachment> attachments = new LinkedList<>();
|
||||||
|
|
||||||
// Loki - For now all attachments are re-fetched by the receiver
|
attachments.addAll(message.getAttachments());
|
||||||
// attachments.addAll(message.getAttachments());
|
attachments.addAll(Stream.of(message.getLinkPreviews()).filter(p -> p.getThumbnail().isPresent()).map(p -> p.getThumbnail().get()).toList());
|
||||||
// attachments.addAll(Stream.of(message.getLinkPreviews()).filter(p -> p.getThumbnail().isPresent()).map(p -> p.getThumbnail().get()).toList());
|
|
||||||
attachments.addAll(Stream.of(message.getSharedContacts()).filter(c -> c.getAvatar() != null).map(c -> c.getAvatar().getAttachment()).withoutNulls().toList());
|
attachments.addAll(Stream.of(message.getSharedContacts()).filter(c -> c.getAvatar() != null).map(c -> c.getAvatar().getAttachment()).withoutNulls().toList());
|
||||||
|
|
||||||
List<AttachmentUploadJob> attachmentJobs = Stream.of(attachments).map(a -> new AttachmentUploadJob(((DatabaseAttachment) a).getAttachmentId())).toList();
|
List<AttachmentUploadJob> attachmentJobs = Stream.of(attachments).map(a -> new AttachmentUploadJob(((DatabaseAttachment) a).getAttachmentId(), destination)).toList();
|
||||||
|
|
||||||
if (attachmentJobs.isEmpty()) {
|
if (attachmentJobs.isEmpty()) {
|
||||||
jobManager.add(new PushMediaSendJob(templateMessageId, messageId, destination, isFriendRequest, customFriendRequestMessage));
|
jobManager.add(new PushMediaSendJob(templateMessageId, messageId, destination, isFriendRequest, customFriendRequestMessage));
|
||||||
|
@ -172,7 +172,7 @@ public abstract class PushSendJob extends SendJob {
|
|||||||
Optional.fromNullable(attachment.getDigest()),
|
Optional.fromNullable(attachment.getDigest()),
|
||||||
Optional.fromNullable(attachment.getFileName()),
|
Optional.fromNullable(attachment.getFileName()),
|
||||||
attachment.isVoiceNote(),
|
attachment.isVoiceNote(),
|
||||||
Optional.fromNullable(attachment.getCaption()));
|
Optional.fromNullable(attachment.getCaption()), attachment.getUrl());
|
||||||
} catch (IOException | ArithmeticException e) {
|
} catch (IOException | ArithmeticException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
return null;
|
return null;
|
||||||
|
@ -77,12 +77,15 @@ public class RetrieveProfileJob extends BaseJob implements InjectableType {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRun() throws IOException, InvalidKeyException {
|
public void onRun() throws IOException, InvalidKeyException {
|
||||||
|
// Loki - Disable retrieve profile
|
||||||
|
/*
|
||||||
try {
|
try {
|
||||||
if (recipient.isGroupRecipient()) handleGroupRecipient(recipient);
|
if (recipient.isGroupRecipient()) handleGroupRecipient(recipient);
|
||||||
else handleIndividualRecipient(recipient);
|
else handleIndividualRecipient(recipient);
|
||||||
} catch (InvalidNumberException e) {
|
} catch (InvalidNumberException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,6 +27,9 @@ class DisplayNameActivity : BaseActionBarActivity() {
|
|||||||
if (name.isEmpty()) {
|
if (name.isEmpty()) {
|
||||||
return nameEditText.input.setError("Invalid")
|
return nameEditText.input.setError("Invalid")
|
||||||
}
|
}
|
||||||
|
if (!name.matches(Regex("[a-zA-Z0-9_]+"))) {
|
||||||
|
return nameEditText.input.setError("Invalid (a-z, A-Z, 0-9 and _ only)")
|
||||||
|
}
|
||||||
if (name.toByteArray().size > ProfileCipher.NAME_PADDED_LENGTH) {
|
if (name.toByteArray().size > ProfileCipher.NAME_PADDED_LENGTH) {
|
||||||
return nameEditText.input.setError("Too Long")
|
return nameEditText.input.setError("Too Long")
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.util.GroupUtil
|
|||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.thoughtcrime.securesms.util.Util
|
import org.thoughtcrime.securesms.util.Util
|
||||||
import org.whispersystems.libsignal.util.guava.Optional
|
import org.whispersystems.libsignal.util.guava.Optional
|
||||||
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
|
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup
|
import org.whispersystems.signalservice.api.messages.SignalServiceGroup
|
||||||
@ -96,21 +97,53 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
|
|||||||
private fun pollForNewMessages() {
|
private fun pollForNewMessages() {
|
||||||
fun processIncomingMessage(message: LokiPublicChatMessage) {
|
fun processIncomingMessage(message: LokiPublicChatMessage) {
|
||||||
val id = group.id.toByteArray()
|
val id = group.id.toByteArray()
|
||||||
val x1 = SignalServiceGroup(SignalServiceGroup.Type.UPDATE, id, null, null, null)
|
val serviceGroup = SignalServiceGroup(SignalServiceGroup.Type.UPDATE, id, null, null, null)
|
||||||
val quote: SignalServiceDataMessage.Quote?
|
val quote = if (message.quote != null) {
|
||||||
if (message.quote != null) {
|
SignalServiceDataMessage.Quote(message.quote!!.quotedMessageTimestamp, SignalServiceAddress(message.quote!!.quoteeHexEncodedPublicKey), message.quote!!.quotedMessageBody, listOf())
|
||||||
quote = SignalServiceDataMessage.Quote(message.quote!!.quotedMessageTimestamp, SignalServiceAddress(message.quote!!.quoteeHexEncodedPublicKey), message.quote!!.quotedMessageBody, listOf())
|
|
||||||
} else {
|
} else {
|
||||||
quote = null
|
null
|
||||||
}
|
}
|
||||||
val x2 = SignalServiceDataMessage(message.timestamp, x1, listOf(), message.body, false, 0, false, null, false, quote, null, null, null)
|
val attachments = message.attachments.mapNotNull { attachment ->
|
||||||
val x3 = SignalServiceContent(x2, message.hexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false)
|
if (attachment.kind != LokiPublicChatMessage.Attachment.Kind.Attachment) { return@mapNotNull null }
|
||||||
|
SignalServiceAttachmentPointer(
|
||||||
|
attachment.serverID,
|
||||||
|
attachment.contentType,
|
||||||
|
ByteArray(0),
|
||||||
|
Optional.of(attachment.size),
|
||||||
|
Optional.absent(),
|
||||||
|
attachment.width, attachment.height,
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.of(attachment.fileName),
|
||||||
|
false,
|
||||||
|
Optional.fromNullable(attachment.caption),
|
||||||
|
attachment.url)
|
||||||
|
}
|
||||||
|
val linkPreview = message.attachments.firstOrNull { it.kind == LokiPublicChatMessage.Attachment.Kind.LinkPreview }
|
||||||
|
val signalLinkPreviews = mutableListOf<SignalServiceDataMessage.Preview>()
|
||||||
|
if (linkPreview != null) {
|
||||||
|
val attachment = SignalServiceAttachmentPointer(
|
||||||
|
linkPreview.serverID,
|
||||||
|
linkPreview.contentType,
|
||||||
|
ByteArray(0),
|
||||||
|
Optional.of(linkPreview.size),
|
||||||
|
Optional.absent(),
|
||||||
|
linkPreview.width, linkPreview.height,
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.of(linkPreview.fileName),
|
||||||
|
false,
|
||||||
|
Optional.fromNullable(linkPreview.caption),
|
||||||
|
linkPreview.url)
|
||||||
|
signalLinkPreviews.add(SignalServiceDataMessage.Preview(linkPreview.linkPreviewURL!!, linkPreview.linkPreviewTitle!!, Optional.of(attachment)))
|
||||||
|
}
|
||||||
|
val body = if (message.body == message.timestamp.toString()) "" else message.body // Workaround for the fact that the back-end doesn't accept messages without a body
|
||||||
|
val serviceDataMessage = SignalServiceDataMessage(message.timestamp, serviceGroup, attachments, body, false, 0, false, null, false, quote, null, signalLinkPreviews, null)
|
||||||
|
val serviceContent = SignalServiceContent(serviceDataMessage, message.hexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false)
|
||||||
val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})"
|
val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})"
|
||||||
DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName)
|
DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName)
|
||||||
if (quote != null) {
|
if (quote != null || attachments.count() > 0 || linkPreview != null) {
|
||||||
PushDecryptJob(context).handleMediaMessage(x3, x2, Optional.absent(), Optional.of(message.serverID))
|
PushDecryptJob(context).handleMediaMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID))
|
||||||
} else {
|
} else {
|
||||||
PushDecryptJob(context).handleTextMessage(x3, x2, Optional.absent(), Optional.of(message.serverID))
|
PushDecryptJob(context).handleTextMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun processOutgoingMessage(message: LokiPublicChatMessage) {
|
fun processOutgoingMessage(message: LokiPublicChatMessage) {
|
||||||
@ -118,6 +151,7 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
|
|||||||
val lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context)
|
val lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context)
|
||||||
val isDuplicate = lokiMessageDatabase.getMessageID(messageServerID) != null
|
val isDuplicate = lokiMessageDatabase.getMessageID(messageServerID) != null
|
||||||
if (isDuplicate) { return }
|
if (isDuplicate) { return }
|
||||||
|
if (message.body.isEmpty() && message.attachments.isEmpty() && message.quote == null) { return }
|
||||||
val id = group.id.toByteArray()
|
val id = group.id.toByteArray()
|
||||||
val mmsDatabase = DatabaseFactory.getMmsDatabase(context)
|
val mmsDatabase = DatabaseFactory.getMmsDatabase(context)
|
||||||
val recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedId(id, false)), false)
|
val recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedId(id, false)), false)
|
||||||
@ -127,7 +161,9 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
|
|||||||
} else {
|
} else {
|
||||||
quote = null
|
quote = null
|
||||||
}
|
}
|
||||||
val signalMessage = OutgoingMediaMessage(recipient, message.body, listOf(), message.timestamp, 0, 0,
|
// TODO: Handle attachments correctly for our previous messages
|
||||||
|
val body = if (message.body == message.timestamp.toString()) "" else message.body // Workaround for the fact that the back-end doesn't accept messages without a body
|
||||||
|
val signalMessage = OutgoingMediaMessage(recipient, body, listOf(), message.timestamp, 0, 0,
|
||||||
ThreadDatabase.DistributionTypes.DEFAULT, quote, listOf(), listOf(), listOf(), listOf())
|
ThreadDatabase.DistributionTypes.DEFAULT, quote, listOf(), listOf(), listOf(), listOf())
|
||||||
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient)
|
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient)
|
||||||
fun finalize() {
|
fun finalize() {
|
||||||
|
@ -54,7 +54,8 @@ class SeedActivity : BaseActionBarActivity(), DeviceLinkingDialogDelegate {
|
|||||||
copyButton.setOnClickListener { copy() }
|
copyButton.setOnClickListener { copy() }
|
||||||
toggleRegisterModeButton.setOnClickListener { mode = Mode.Register }
|
toggleRegisterModeButton.setOnClickListener { mode = Mode.Register }
|
||||||
toggleRestoreModeButton.setOnClickListener { mode = Mode.Restore }
|
toggleRestoreModeButton.setOnClickListener { mode = Mode.Restore }
|
||||||
toggleLinkModeButton.setOnClickListener { mode = Mode.Link }
|
// TODO: Enable this again later
|
||||||
|
// toggleLinkModeButton.setOnClickListener { mode = Mode.Link }
|
||||||
mainButton.setOnClickListener { handleMainButtonTapped() }
|
mainButton.setOnClickListener { handleMainButtonTapped() }
|
||||||
Analytics.shared.track("Seed Screen Viewed")
|
Analytics.shared.track("Seed Screen Viewed")
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
|||||||
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
|
|
||||||
@ -117,32 +118,18 @@ public class MessageSender {
|
|||||||
// Loki - Turn into a GIF message if possible
|
// Loki - Turn into a GIF message if possible
|
||||||
if (message.getLinkPreviews().isEmpty() && message.getAttachments().isEmpty() && LinkPreviewUtil.isWhitelistedMediaUrl(message.getBody())) {
|
if (message.getLinkPreviews().isEmpty() && message.getAttachments().isEmpty() && LinkPreviewUtil.isWhitelistedMediaUrl(message.getBody())) {
|
||||||
new LinkPreviewRepository(context).fetchGIF(context, message.getBody(), attachmentOrNull -> Util.runOnMain(() -> {
|
new LinkPreviewRepository(context).fetchGIF(context, message.getBody(), attachmentOrNull -> Util.runOnMain(() -> {
|
||||||
if (attachmentOrNull.isPresent()) {
|
Attachment attachment = attachmentOrNull.orNull();
|
||||||
Attachment attachment = attachmentOrNull.get();
|
try {
|
||||||
try {
|
if (attachment != null) { message.getAttachments().add(attachment); }
|
||||||
message.getAttachments().add(attachment);
|
long messageID = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener);
|
||||||
long messageID = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener);
|
// Loki - Set the message's friend request status as soon as it has hit the database
|
||||||
// Loki - Set the message's friend request status as soon as it has hit the database
|
if (message.isFriendRequest) {
|
||||||
if (message.isFriendRequest) {
|
DatabaseFactory.getLokiMessageDatabase(context).setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_SENDING);
|
||||||
DatabaseFactory.getLokiMessageDatabase(context).setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_SENDING);
|
|
||||||
}
|
|
||||||
sendMediaMessage(context, recipient, forceSms, messageID, message.getExpiresIn());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.w(TAG, e);
|
|
||||||
// TODO: Handle
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
long messageID = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener);
|
|
||||||
// Loki - Set the message's friend request status as soon as it has hit the database
|
|
||||||
if (message.isFriendRequest) {
|
|
||||||
DatabaseFactory.getLokiMessageDatabase(context).setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_SENDING);
|
|
||||||
}
|
|
||||||
sendMediaMessage(context, recipient, forceSms, messageID, message.getExpiresIn());
|
|
||||||
} catch (MmsException e) {
|
|
||||||
Log.w(TAG, e);
|
|
||||||
// TODO: Handle
|
|
||||||
}
|
}
|
||||||
|
sendMediaMessage(context, recipient, forceSms, messageID, message.getExpiresIn());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
// TODO: Handle
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
|||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
|
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -106,14 +107,21 @@ public class AttachmentUtil {
|
|||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
private static boolean isFromUnknownContact(@NonNull Context context, @NonNull DatabaseAttachment attachment) {
|
private static boolean isFromUnknownContact(@NonNull Context context, @NonNull DatabaseAttachment attachment) {
|
||||||
|
MessageRecord message;
|
||||||
try (Cursor messageCursor = DatabaseFactory.getMmsDatabase(context).getMessage(attachment.getMmsId())) {
|
try (Cursor messageCursor = DatabaseFactory.getMmsDatabase(context).getMessage(attachment.getMmsId())) {
|
||||||
final MessageRecord message = DatabaseFactory.getMmsDatabase(context).readerFor(messageCursor).getNext();
|
message = DatabaseFactory.getMmsDatabase(context).readerFor(messageCursor).getNext();
|
||||||
|
|
||||||
if (message == null || (!message.getRecipient().isSystemContact() && !message.isOutgoing() && !Util.isOwnNumber(context, message.getRecipient().getAddress()))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message == null) { return true; }
|
||||||
|
|
||||||
|
// TODO: Fix this so we can detect whether attachment is from a public group or not
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// check to see if we're friends with the person
|
||||||
|
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(message.getRecipient());
|
||||||
|
boolean isFriend = threadId >= 0 && DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadId) == LokiThreadFriendRequestStatus.FRIENDS;
|
||||||
|
return (!isFriend && !message.isOutgoing() && !Util.isOwnNumber(context, message.getRecipient().getAddress()));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user