mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Refactor ConversationAdapter and its ConversationItems
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/msgLayout"
|
android:id="@+id/layout"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
android:id="@+id/msgBody"
|
android:id="@+id/text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/briar_text_primary"
|
android:textColor="@color/briar_text_primary"
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
tools:text="Short message"/>
|
tools:text="Short message"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/msgTime"
|
android:id="@+id/time"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right|end"
|
android:layout_gravity="right|end"
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/msgLayout"
|
android:id="@+id/layout"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right|end"
|
android:layout_gravity="right|end"
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
android:background="@drawable/msg_out">
|
android:background="@drawable/msg_out">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
android:id="@+id/msgBody"
|
android:id="@+id/text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/briar_text_primary_inverse"
|
android:textColor="@color/briar_text_primary_inverse"
|
||||||
@@ -25,12 +25,12 @@
|
|||||||
tools:text="This is a long long long message that spans over several lines.\n\nIt ends here."/>
|
tools:text="This is a long long long message that spans over several lines.\n\nIt ends here."/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/msgTime"
|
android:id="@+id/time"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_below="@+id/msgBody"
|
android:layout_below="@+id/text"
|
||||||
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textColor="@color/private_message_date_inverse"
|
android:textColor="@color/private_message_date_inverse"
|
||||||
@@ -38,13 +38,13 @@
|
|||||||
tools:text="Dec 24, 13:37"/>
|
tools:text="Dec 24, 13:37"/>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/msgStatus"
|
android:id="@+id/status"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignBottom="@+id/msgTime"
|
android:layout_alignBottom="@+id/time"
|
||||||
android:layout_marginLeft="@dimen/margin_medium"
|
android:layout_marginLeft="@dimen/margin_medium"
|
||||||
android:layout_toEndOf="@+id/msgTime"
|
android:layout_toEndOf="@+id/time"
|
||||||
android:layout_toRightOf="@+id/msgTime"
|
android:layout_toRightOf="@+id/time"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
tools:src="@drawable/message_delivered_white"/>
|
tools:src="@drawable/message_delivered_white"/>
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
android:id="@+id/msgBody"
|
android:id="@+id/msgText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="left|start"
|
android:layout_gravity="left|start"
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
tools:text="Short message"/>
|
tools:text="Short message"/>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/noticeLayout"
|
android:id="@+id/layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
|
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
android:background="@drawable/notice_in_bottom">
|
android:background="@drawable/notice_in_bottom">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
android:id="@+id/introductionText"
|
android:id="@+id/text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minWidth="80dp"
|
android:minWidth="80dp"
|
||||||
@@ -39,28 +39,17 @@
|
|||||||
tools:text="@string/forum_invitation_received"/>
|
tools:text="@string/forum_invitation_received"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/introductionTime"
|
android:id="@+id/time"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignEnd="@+id/introductionText"
|
android:layout_alignEnd="@+id/text"
|
||||||
android:layout_alignRight="@+id/introductionText"
|
android:layout_alignRight="@+id/text"
|
||||||
android:layout_below="@+id/showInvitationsButton"
|
android:layout_below="@+id/text"
|
||||||
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
||||||
android:textColor="@color/private_message_date"
|
android:textColor="@color/private_message_date"
|
||||||
android:textSize="@dimen/text_size_tiny"
|
android:textSize="@dimen/text_size_tiny"
|
||||||
tools:text="Dec 24, 13:37"/>
|
tools:text="Dec 24, 13:37"/>
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/showInvitationsButton"
|
|
||||||
style="@style/BriarButtonFlat.Positive"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignEnd="@+id/introductionText"
|
|
||||||
android:layout_alignRight="@+id/introductionText"
|
|
||||||
android:layout_below="@+id/introductionText"
|
|
||||||
android:layout_marginBottom="-15dp"
|
|
||||||
tools:text="@string/forum_show_invitations"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
android:id="@+id/msgBody"
|
android:id="@+id/msgText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
|
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
tools:text="This is a long long long message that spans over several lines.\n\nIt ends here."/>
|
tools:text="This is a long long long message that spans over several lines.\n\nIt ends here."/>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/noticeLayout"
|
android:id="@+id/layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
|
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
android:background="@drawable/notice_out_bottom">
|
android:background="@drawable/notice_out_bottom">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
android:id="@+id/introductionText"
|
android:id="@+id/text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/briar_text_secondary"
|
android:textColor="@color/briar_text_secondary"
|
||||||
@@ -37,25 +37,25 @@
|
|||||||
tools:text="@string/introduction_request_received"/>
|
tools:text="@string/introduction_request_received"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/introductionTime"
|
android:id="@+id/time"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_below="@+id/introductionText"
|
android:layout_below="@+id/text"
|
||||||
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
||||||
android:textColor="@color/private_message_date"
|
android:textColor="@color/private_message_date"
|
||||||
android:textSize="@dimen/text_size_tiny"
|
android:textSize="@dimen/text_size_tiny"
|
||||||
tools:text="Dec 24, 13:37"/>
|
tools:text="Dec 24, 13:37"/>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/introductionStatus"
|
android:id="@+id/status"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignBottom="@+id/introductionTime"
|
android:layout_alignBottom="@+id/time"
|
||||||
android:layout_marginLeft="@dimen/margin_medium"
|
android:layout_marginLeft="@dimen/margin_medium"
|
||||||
android:layout_toEndOf="@+id/introductionTime"
|
android:layout_toEndOf="@+id/time"
|
||||||
android:layout_toRightOf="@+id/introductionTime"
|
android:layout_toRightOf="@+id/time"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
tools:src="@drawable/message_delivered"/>
|
tools:src="@drawable/message_delivered"/>
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
android:id="@+id/msgBody"
|
android:id="@+id/msgText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
|
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
tools:text="Short message"/>
|
tools:text="Short message"/>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/noticeLayout"
|
android:id="@+id/layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
|
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
android:background="@drawable/notice_in_bottom">
|
android:background="@drawable/notice_in_bottom">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
android:id="@+id/introductionText"
|
android:id="@+id/text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minWidth="80dp"
|
android:minWidth="80dp"
|
||||||
@@ -38,11 +38,11 @@
|
|||||||
tools:text="@string/introduction_request_received"/>
|
tools:text="@string/introduction_request_received"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/introductionTime"
|
android:id="@+id/time"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignEnd="@+id/introductionText"
|
android:layout_alignEnd="@+id/text"
|
||||||
android:layout_alignRight="@+id/introductionText"
|
android:layout_alignRight="@+id/text"
|
||||||
android:layout_below="@+id/declineButton"
|
android:layout_below="@+id/declineButton"
|
||||||
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
||||||
android:textColor="@color/private_message_date"
|
android:textColor="@color/private_message_date"
|
||||||
@@ -54,9 +54,9 @@
|
|||||||
style="@style/BriarButtonFlat.Positive"
|
style="@style/BriarButtonFlat.Positive"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignEnd="@+id/introductionText"
|
android:layout_alignEnd="@+id/text"
|
||||||
android:layout_alignRight="@+id/introductionText"
|
android:layout_alignRight="@+id/text"
|
||||||
android:layout_below="@+id/introductionText"
|
android:layout_below="@+id/text"
|
||||||
android:text="@string/accept"/>
|
android:text="@string/accept"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
style="@style/BriarButtonFlat.Negative"
|
style="@style/BriarButtonFlat.Negative"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/introductionText"
|
android:layout_below="@+id/text"
|
||||||
android:layout_marginBottom="-15dp"
|
android:layout_marginBottom="-15dp"
|
||||||
android:layout_toLeftOf="@+id/acceptButton"
|
android:layout_toLeftOf="@+id/acceptButton"
|
||||||
android:layout_toStartOf="@+id/acceptButton"
|
android:layout_toStartOf="@+id/acceptButton"
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/notice_in"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
|
|
||||||
android:layout_marginRight="@dimen/message_bubble_margin_non_tail">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
|
||||||
android:id="@+id/noticeText"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="@dimen/text_size_medium"
|
|
||||||
android:textStyle="italic"
|
|
||||||
android:textColor="@color/briar_text_secondary"
|
|
||||||
tools:text="@string/introduction_response_accepted_received"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/noticeTime"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="right|end"
|
|
||||||
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:textColor="@color/private_message_date"
|
|
||||||
android:textSize="@dimen/text_size_tiny"
|
|
||||||
tools:text="Dec 24, 13:37"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="right|end"
|
|
||||||
android:background="@drawable/notice_out"
|
|
||||||
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
|
|
||||||
android:layout_marginRight="@dimen/message_bubble_margin_tail">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
|
||||||
android:id="@+id/noticeText"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="@dimen/text_size_medium"
|
|
||||||
android:textStyle="italic"
|
|
||||||
android:textColor="@color/briar_text_secondary"
|
|
||||||
tools:text="@string/introduction_response_accepted_sent"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/noticeTime"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_below="@+id/noticeText"
|
|
||||||
android:textColor="@color/private_message_date"
|
|
||||||
android:textSize="@dimen/text_size_tiny"
|
|
||||||
tools:text="Dec 24, 13:37"/>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/noticeStatus"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignBottom="@+id/noticeTime"
|
|
||||||
android:layout_marginLeft="@dimen/margin_medium"
|
|
||||||
android:layout_toEndOf="@+id/noticeTime"
|
|
||||||
android:layout_toRightOf="@+id/noticeTime"
|
|
||||||
tools:ignore="ContentDescription"
|
|
||||||
tools:src="@drawable/message_delivered"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -133,7 +133,6 @@
|
|||||||
<string name="introduction_request_sent">You have asked to introduce %1$s to %2$s.</string>
|
<string name="introduction_request_sent">You have asked to introduce %1$s to %2$s.</string>
|
||||||
<string name="introduction_request_received">%1$s has asked to introduce you to %2$s. Do you want to add %2$s to your contact list?</string>
|
<string name="introduction_request_received">%1$s has asked to introduce you to %2$s. Do you want to add %2$s to your contact list?</string>
|
||||||
<string name="introduction_request_exists_received">%1$s has asked to introduce you to %2$s, but %2$s is already in your contact list. Since %1$s might not know that, you can still respond:</string>
|
<string name="introduction_request_exists_received">%1$s has asked to introduce you to %2$s, but %2$s is already in your contact list. Since %1$s might not know that, you can still respond:</string>
|
||||||
<string name="introduction_request_for_our_identity_received">%1$s has asked to introduce you to %2$s, but %2$s is one of your other identities, so you cannot accept the introduction:</string>
|
|
||||||
<string name="introduction_request_answered_received">%1$s has asked to introduce you to %2$s.</string>
|
<string name="introduction_request_answered_received">%1$s has asked to introduce you to %2$s.</string>
|
||||||
<string name="introduction_response_accepted_sent">You accepted the introduction to %1$s.</string>
|
<string name="introduction_response_accepted_sent">You accepted the introduction to %1$s.</string>
|
||||||
<string name="introduction_response_declined_sent">You declined the introduction to %1$s.</string>
|
<string name="introduction_response_declined_sent">You declined the introduction to %1$s.</string>
|
||||||
@@ -215,7 +214,6 @@
|
|||||||
<string name="forum_share_error">There was an error sharing this forum.</string>
|
<string name="forum_share_error">There was an error sharing this forum.</string>
|
||||||
<string name="forum_invitation_received">%1$s has shared the forum \"%2$s\" with you.</string>
|
<string name="forum_invitation_received">%1$s has shared the forum \"%2$s\" with you.</string>
|
||||||
<string name="forum_invitation_sent">You have shared the forum \"%1$s\" with %2$s.</string>
|
<string name="forum_invitation_sent">You have shared the forum \"%1$s\" with %2$s.</string>
|
||||||
<string name="forum_show_invitations">Show Forum Invitations</string>
|
|
||||||
<string name="forum_invitations_title">Forum Invitations</string>
|
<string name="forum_invitations_title">Forum Invitations</string>
|
||||||
<string name="forum_invitation_exists">You accepted an invitation to this forum already. Accepting more invitations will grow and strengthen the communication in the forum.</string>
|
<string name="forum_invitation_exists">You accepted an invitation to this forum already. Accepting more invitations will grow and strengthen the communication in the forum.</string>
|
||||||
<string name="forum_joined_toast">Joined Forum</string>
|
<string name="forum_joined_toast">Joined Forum</string>
|
||||||
@@ -279,7 +277,6 @@
|
|||||||
<string name="blogs_sharing_response_declined_received">%s declined the blog invitation.</string>
|
<string name="blogs_sharing_response_declined_received">%s declined the blog invitation.</string>
|
||||||
<string name="blogs_sharing_invitation_received">%1$s has shared the personal blog of %2$s with you.</string>
|
<string name="blogs_sharing_invitation_received">%1$s has shared the personal blog of %2$s with you.</string>
|
||||||
<string name="blogs_sharing_invitation_sent">You have shared the personal blog of %1$s with %2$s.</string>
|
<string name="blogs_sharing_invitation_sent">You have shared the personal blog of %1$s with %2$s.</string>
|
||||||
<string name="blogs_sharing_show_invitations">Show Blog Invitations</string>
|
|
||||||
<string name="blogs_sharing_invitations_title">Blog Invitations</string>
|
<string name="blogs_sharing_invitations_title">Blog Invitations</string>
|
||||||
<string name="blogs_sharing_exists">You are subscribed to this blog already. Accepting again can lead to faster blog post delivery.</string>
|
<string name="blogs_sharing_exists">You are subscribed to this blog already. Accepting again can lead to faster blog post delivery.</string>
|
||||||
<string name="blogs_sharing_joined_toast">Subscribed to Blog</string>
|
<string name="blogs_sharing_joined_toast">Subscribed to Blog</string>
|
||||||
|
|||||||
@@ -276,24 +276,28 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
IntroductionRequestReceivedEvent m =
|
IntroductionRequestReceivedEvent m =
|
||||||
(IntroductionRequestReceivedEvent) e;
|
(IntroductionRequestReceivedEvent) e;
|
||||||
IntroductionRequest ir = m.getIntroductionRequest();
|
IntroductionRequest ir = m.getIntroductionRequest();
|
||||||
updateItem(m.getContactId(), ConversationItem.from(ir));
|
updateItem(m.getContactId(),
|
||||||
|
ConversationItem.from(getContext(), "", ir));
|
||||||
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
||||||
LOG.info("Introduction response received, updating item");
|
LOG.info("Introduction response received, updating item");
|
||||||
IntroductionResponseReceivedEvent m =
|
IntroductionResponseReceivedEvent m =
|
||||||
(IntroductionResponseReceivedEvent) e;
|
(IntroductionResponseReceivedEvent) e;
|
||||||
IntroductionResponse ir = m.getIntroductionResponse();
|
IntroductionResponse ir = m.getIntroductionResponse();
|
||||||
updateItem(m.getContactId(), ConversationItem.from(ir));
|
updateItem(m.getContactId(),
|
||||||
|
ConversationItem.from(getContext(), "", ir));
|
||||||
} else if (e instanceof InvitationRequestReceivedEvent) {
|
} else if (e instanceof InvitationRequestReceivedEvent) {
|
||||||
LOG.info("Invitation request received, updating item");
|
LOG.info("Invitation request received, updating item");
|
||||||
InvitationRequestReceivedEvent m = (InvitationRequestReceivedEvent) e;
|
InvitationRequestReceivedEvent m = (InvitationRequestReceivedEvent) e;
|
||||||
InvitationRequest ir = m.getRequest();
|
InvitationRequest ir = m.getRequest();
|
||||||
updateItem(m.getContactId(), ConversationItem.from(ir));
|
updateItem(m.getContactId(),
|
||||||
|
ConversationItem.from(getContext(), "", ir));
|
||||||
} else if (e instanceof InvitationResponseReceivedEvent) {
|
} else if (e instanceof InvitationResponseReceivedEvent) {
|
||||||
LOG.info("Invitation response received, updating item");
|
LOG.info("Invitation response received, updating item");
|
||||||
InvitationResponseReceivedEvent m =
|
InvitationResponseReceivedEvent m =
|
||||||
(InvitationResponseReceivedEvent) e;
|
(InvitationResponseReceivedEvent) e;
|
||||||
InvitationResponse ir = m.getResponse();
|
InvitationResponse ir = m.getResponse();
|
||||||
updateItem(m.getContactId(), ConversationItem.from(ir));
|
updateItem(m.getContactId(),
|
||||||
|
ConversationItem.from(getContext(), "", ir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import org.briarproject.api.identity.LocalAuthor;
|
|||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.IncomingItem;
|
|
||||||
|
|
||||||
// This class is NOT thread-safe
|
// This class is NOT thread-safe
|
||||||
public class ContactListItem {
|
public class ContactListItem {
|
||||||
|
|
||||||
@@ -34,8 +32,8 @@ public class ContactListItem {
|
|||||||
empty = empty && message == null;
|
empty = empty && message == null;
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
if (message.getTime() > timestamp) timestamp = message.getTime();
|
if (message.getTime() > timestamp) timestamp = message.getTime();
|
||||||
if (message instanceof IncomingItem &&
|
if (message instanceof ConversationInItem &&
|
||||||
!((IncomingItem) message).isRead())
|
!((ConversationInItem) message).isRead())
|
||||||
unread++;
|
unread++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.android.contact;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.ActivityOptionsCompat;
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
@@ -27,7 +28,8 @@ import org.briarproject.R;
|
|||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
import org.briarproject.android.BriarActivity;
|
import org.briarproject.android.BriarActivity;
|
||||||
import org.briarproject.android.api.AndroidNotificationManager;
|
import org.briarproject.android.api.AndroidNotificationManager;
|
||||||
import org.briarproject.android.contact.ConversationAdapter.IntroductionHandler;
|
import org.briarproject.android.contact.ConversationAdapter.RequestListener;
|
||||||
|
import org.briarproject.android.contact.ConversationItem.PartialItem;
|
||||||
import org.briarproject.android.introduction.IntroductionActivity;
|
import org.briarproject.android.introduction.IntroductionActivity;
|
||||||
import org.briarproject.android.view.BriarRecyclerView;
|
import org.briarproject.android.view.BriarRecyclerView;
|
||||||
import org.briarproject.android.view.TextInputView;
|
import org.briarproject.android.view.TextInputView;
|
||||||
@@ -39,6 +41,7 @@ import org.briarproject.api.contact.Contact;
|
|||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
import org.briarproject.api.crypto.CryptoExecutor;
|
import org.briarproject.api.crypto.CryptoExecutor;
|
||||||
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.NoSuchContactException;
|
import org.briarproject.api.db.NoSuchContactException;
|
||||||
import org.briarproject.api.event.ContactConnectedEvent;
|
import org.briarproject.api.event.ContactConnectedEvent;
|
||||||
@@ -92,16 +95,15 @@ import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
|
|||||||
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.OnHidePromptListener;
|
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.OnHidePromptListener;
|
||||||
|
|
||||||
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
||||||
|
import static android.support.v7.util.SortedList.INVALID_POSITION;
|
||||||
import static android.widget.Toast.LENGTH_SHORT;
|
import static android.widget.Toast.LENGTH_SHORT;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.android.contact.ConversationItem.IncomingItem;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.OutgoingItem;
|
|
||||||
import static org.briarproject.android.fragment.SettingsFragment.SETTINGS_NAMESPACE;
|
import static org.briarproject.android.fragment.SettingsFragment.SETTINGS_NAMESPACE;
|
||||||
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
||||||
|
|
||||||
public class ConversationActivity extends BriarActivity
|
public class ConversationActivity extends BriarActivity
|
||||||
implements EventListener, IntroductionHandler, TextInputListener {
|
implements EventListener, RequestListener, TextInputListener {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(ConversationActivity.class.getName());
|
Logger.getLogger(ConversationActivity.class.getName());
|
||||||
@@ -117,7 +119,7 @@ public class ConversationActivity extends BriarActivity
|
|||||||
@CryptoExecutor
|
@CryptoExecutor
|
||||||
Executor cryptoExecutor;
|
Executor cryptoExecutor;
|
||||||
|
|
||||||
private final Map<MessageId, byte[]> bodyCache = new ConcurrentHashMap<>();
|
private final Map<MessageId, String> bodyCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private ConversationAdapter adapter;
|
private ConversationAdapter adapter;
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
@@ -325,7 +327,6 @@ public class ConversationActivity extends BriarActivity
|
|||||||
toolbarStatus
|
toolbarStatus
|
||||||
.setContentDescription(getString(R.string.offline));
|
.setContentDescription(getString(R.string.offline));
|
||||||
}
|
}
|
||||||
adapter.setContactName(contactName);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -399,33 +400,42 @@ public class ConversationActivity extends BriarActivity
|
|||||||
Collection<InvitationMessage> invitations) {
|
Collection<InvitationMessage> invitations) {
|
||||||
int size = headers.size() + introductions.size() + invitations.size();
|
int size = headers.size() + introductions.size() + invitations.size();
|
||||||
List<ConversationItem> items = new ArrayList<>(size);
|
List<ConversationItem> items = new ArrayList<>(size);
|
||||||
for (PrivateMessageHeader h : headers) {
|
|
||||||
ConversationMessageItem item = ConversationItem.from(h);
|
for (PrivateMessageHeader h : headers) {
|
||||||
byte[] body = bodyCache.get(h.getId());
|
ConversationItem item = ConversationItem.from(h);
|
||||||
if (body == null) loadMessageBody(h.getId());
|
String body = bodyCache.get(h.getId());
|
||||||
else item.setBody(body);
|
if (body == null) loadMessageBody(h.getId());
|
||||||
items.add(item);
|
else ((PartialItem) item).setText(body);
|
||||||
}
|
items.add(item);
|
||||||
for (IntroductionMessage im : introductions) {
|
|
||||||
if (im instanceof IntroductionRequest) {
|
|
||||||
IntroductionRequest ir = (IntroductionRequest) im;
|
|
||||||
items.add(ConversationItem.from(ir));
|
|
||||||
} else {
|
|
||||||
IntroductionResponse ir = (IntroductionResponse) im;
|
|
||||||
items.add(ConversationItem.from(ConversationActivity.this,
|
|
||||||
contactName, ir));
|
|
||||||
}
|
}
|
||||||
}
|
for (IntroductionMessage m : introductions) {
|
||||||
for (InvitationMessage im : invitations) {
|
ConversationItem item;
|
||||||
if (im instanceof InvitationRequest) {
|
if (m instanceof IntroductionRequest) {
|
||||||
InvitationRequest ir = (InvitationRequest) im;
|
item = ConversationItem
|
||||||
items.add(ConversationItem.from(ir));
|
.from(ConversationActivity.this,
|
||||||
} else if (im instanceof InvitationResponse) {
|
contactName,
|
||||||
InvitationResponse ir = (InvitationResponse) im;
|
(IntroductionRequest) m);
|
||||||
items.add(ConversationItem.from(ConversationActivity.this,
|
} else {
|
||||||
contactName, ir));
|
item = ConversationItem
|
||||||
|
.from(ConversationActivity.this,
|
||||||
|
contactName,
|
||||||
|
(IntroductionResponse) m);
|
||||||
|
}
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
for (InvitationMessage i : invitations) {
|
||||||
|
if (i instanceof InvitationRequest) {
|
||||||
|
InvitationRequest r = (InvitationRequest) i;
|
||||||
|
items.add(ConversationItem
|
||||||
|
.from(ConversationActivity.this,
|
||||||
|
contactName, r));
|
||||||
|
} else if (i instanceof InvitationResponse) {
|
||||||
|
InvitationResponse r = (InvitationResponse) i;
|
||||||
|
items.add(ConversationItem
|
||||||
|
.from(ConversationActivity.this,
|
||||||
|
contactName, r));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,7 +449,7 @@ public class ConversationActivity extends BriarActivity
|
|||||||
long duration = System.currentTimeMillis() - now;
|
long duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Loading body took " + duration + " ms");
|
LOG.info("Loading body took " + duration + " ms");
|
||||||
displayMessageBody(m, body);
|
displayMessageBody(m, StringUtils.fromUtf8(body));
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
@@ -448,17 +458,17 @@ public class ConversationActivity extends BriarActivity
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayMessageBody(final MessageId m, final byte[] body) {
|
private void displayMessageBody(final MessageId m, final String body) {
|
||||||
runOnUiThreadUnlessDestroyed(new Runnable() {
|
runOnUiThreadUnlessDestroyed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
bodyCache.put(m, body);
|
bodyCache.put(m, body);
|
||||||
SparseArray<ConversationMessageItem> messages =
|
SparseArray<ConversationItem> messages =
|
||||||
adapter.getPrivateMessages();
|
adapter.getPrivateMessages();
|
||||||
for (int i = 0; i < messages.size(); i++) {
|
for (int i = 0; i < messages.size(); i++) {
|
||||||
ConversationMessageItem item = messages.valueAt(i);
|
ConversationItem item = messages.valueAt(i);
|
||||||
if (item.getId().equals(m)) {
|
if (item.getId().equals(m)) {
|
||||||
item.setBody(body);
|
((PartialItem) item).setText(body);
|
||||||
adapter.notifyItemChanged(messages.keyAt(i));
|
adapter.notifyItemChanged(messages.keyAt(i));
|
||||||
list.scrollToPosition(adapter.getItemCount() - 1);
|
list.scrollToPosition(adapter.getItemCount() - 1);
|
||||||
return;
|
return;
|
||||||
@@ -482,9 +492,9 @@ public class ConversationActivity extends BriarActivity
|
|||||||
|
|
||||||
private void markMessagesRead() {
|
private void markMessagesRead() {
|
||||||
Map<MessageId, GroupId> unread = new HashMap<>();
|
Map<MessageId, GroupId> unread = new HashMap<>();
|
||||||
SparseArray<IncomingItem> list = adapter.getIncomingMessages();
|
SparseArray<ConversationInItem> list = adapter.getIncomingMessages();
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
IncomingItem item = list.valueAt(i);
|
ConversationInItem item = list.valueAt(i);
|
||||||
if (!item.isRead())
|
if (!item.isRead())
|
||||||
unread.put(item.getId(), item.getGroupId());
|
unread.put(item.getId(), item.getGroupId());
|
||||||
}
|
}
|
||||||
@@ -561,7 +571,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
if (event.getContactId().equals(contactId)) {
|
if (event.getContactId().equals(contactId)) {
|
||||||
LOG.info("Introduction request received, adding...");
|
LOG.info("Introduction request received, adding...");
|
||||||
IntroductionRequest ir = event.getIntroductionRequest();
|
IntroductionRequest ir = event.getIntroductionRequest();
|
||||||
ConversationItem item = new ConversationIntroductionInItem(ir);
|
ConversationItem item =
|
||||||
|
ConversationRequestItem.from(this, contactName, ir);
|
||||||
addConversationItem(item);
|
addConversationItem(item);
|
||||||
}
|
}
|
||||||
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
||||||
@@ -580,7 +591,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
if (event.getContactId().equals(contactId)) {
|
if (event.getContactId().equals(contactId)) {
|
||||||
LOG.info("Invitation received, adding...");
|
LOG.info("Invitation received, adding...");
|
||||||
InvitationRequest ir = event.getRequest();
|
InvitationRequest ir = event.getRequest();
|
||||||
ConversationItem item = ConversationItem.from(ir);
|
ConversationItem item =
|
||||||
|
ConversationItem.from(this, contactName, ir);
|
||||||
addConversationItem(item);
|
addConversationItem(item);
|
||||||
}
|
}
|
||||||
} else if (e instanceof InvitationResponseReceivedEvent) {
|
} else if (e instanceof InvitationResponseReceivedEvent) {
|
||||||
@@ -603,9 +615,10 @@ public class ConversationActivity extends BriarActivity
|
|||||||
public void run() {
|
public void run() {
|
||||||
adapter.incrementRevision();
|
adapter.incrementRevision();
|
||||||
Set<MessageId> messages = new HashSet<>(messageIds);
|
Set<MessageId> messages = new HashSet<>(messageIds);
|
||||||
SparseArray<OutgoingItem> list = adapter.getOutgoingMessages();
|
SparseArray<ConversationOutItem> list =
|
||||||
|
adapter.getOutgoingMessages();
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
OutgoingItem item = list.valueAt(i);
|
ConversationOutItem item = list.valueAt(i);
|
||||||
if (messages.contains(item.getId())) {
|
if (messages.contains(item.getId())) {
|
||||||
item.setSent(sent);
|
item.setSent(sent);
|
||||||
item.setSeen(seen);
|
item.setSeen(seen);
|
||||||
@@ -622,7 +635,7 @@ public class ConversationActivity extends BriarActivity
|
|||||||
text = StringUtils.truncateUtf8(text, MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
text = StringUtils.truncateUtf8(text, MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
||||||
long timestamp = System.currentTimeMillis();
|
long timestamp = System.currentTimeMillis();
|
||||||
timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
|
timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
|
||||||
createMessage(StringUtils.toUtf8(text), timestamp);
|
createMessage(text, timestamp);
|
||||||
textInputView.setText("");
|
textInputView.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,14 +645,14 @@ public class ConversationActivity extends BriarActivity
|
|||||||
return item == null ? 0 : item.getTime() + 1;
|
return item == null ? 0 : item.getTime() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMessage(final byte[] body, final long timestamp) {
|
private void createMessage(final String body, final long timestamp) {
|
||||||
cryptoExecutor.execute(new Runnable() {
|
cryptoExecutor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
storeMessage(privateMessageFactory.createPrivateMessage(
|
storeMessage(privateMessageFactory.createPrivateMessage(
|
||||||
groupId, timestamp, null, "text/plain", body),
|
groupId, timestamp, null, "text/plain",
|
||||||
body);
|
StringUtils.toUtf8(body)), body);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@@ -647,7 +660,7 @@ public class ConversationActivity extends BriarActivity
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeMessage(final PrivateMessage m, final byte[] body) {
|
private void storeMessage(final PrivateMessage m, final String body) {
|
||||||
runOnDbThread(new Runnable() {
|
runOnDbThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -661,8 +674,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
PrivateMessageHeader h = new PrivateMessageHeader(id,
|
PrivateMessageHeader h = new PrivateMessageHeader(id,
|
||||||
groupId, m.getMessage().getTimestamp(),
|
groupId, m.getMessage().getTimestamp(),
|
||||||
m.getContentType(), true, false, false, false);
|
m.getContentType(), true, false, false, false);
|
||||||
ConversationMessageItem item = ConversationItem.from(h);
|
ConversationItem item = ConversationItem.from(h);
|
||||||
item.setBody(body);
|
((PartialItem) item).setText(body);
|
||||||
bodyCache.put(id, body);
|
bodyCache.put(id, body);
|
||||||
addConversationItem(item);
|
addConversationItem(item);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
@@ -812,23 +825,35 @@ public class ConversationActivity extends BriarActivity
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
@Override
|
@Override
|
||||||
public void respondToIntroduction(final SessionId sessionId,
|
public void respondToRequest(final ConversationRequestItem item,
|
||||||
final boolean accept) {
|
final boolean accept) {
|
||||||
|
int position = adapter.findItemPosition(item);
|
||||||
|
if (position != INVALID_POSITION) {
|
||||||
|
adapter.notifyItemChanged(position, item);
|
||||||
|
}
|
||||||
runOnDbThread(new Runnable() {
|
runOnDbThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
long timestamp = System.currentTimeMillis();
|
long timestamp = System.currentTimeMillis();
|
||||||
timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
|
timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
|
||||||
try {
|
try {
|
||||||
if (accept) {
|
switch (item.getRequestType()) {
|
||||||
introductionManager.acceptIntroduction(contactId,
|
case INTRODUCTION:
|
||||||
sessionId, timestamp);
|
respondToIntroductionRequest(item.getSessionId(),
|
||||||
} else {
|
accept, timestamp);
|
||||||
introductionManager.declineIntroduction(contactId,
|
break;
|
||||||
sessionId, timestamp);
|
case FORUM:
|
||||||
|
respondToForumRequest(item.getSessionId(), accept);
|
||||||
|
break;
|
||||||
|
case BLOG:
|
||||||
|
respondToBlogRequest(item.getSessionId(), accept);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unknown Request Type");
|
||||||
}
|
}
|
||||||
loadMessages();
|
|
||||||
} catch (DbException | FormatException e) {
|
} catch (DbException | FormatException e) {
|
||||||
introductionResponseError();
|
introductionResponseError();
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
@@ -839,6 +864,31 @@ public class ConversationActivity extends BriarActivity
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DatabaseExecutor
|
||||||
|
private void respondToIntroductionRequest(SessionId sessionId,
|
||||||
|
boolean accept, long time) throws DbException, FormatException {
|
||||||
|
if (accept) {
|
||||||
|
introductionManager.acceptIntroduction(contactId, sessionId, time);
|
||||||
|
} else {
|
||||||
|
introductionManager.declineIntroduction(contactId, sessionId, time);
|
||||||
|
}
|
||||||
|
loadMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DatabaseExecutor
|
||||||
|
private void respondToForumRequest(SessionId id, boolean accept)
|
||||||
|
throws DbException {
|
||||||
|
forumSharingManager.respondToInvitation(id, accept);
|
||||||
|
loadMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DatabaseExecutor
|
||||||
|
private void respondToBlogRequest(SessionId id, boolean accept)
|
||||||
|
throws DbException {
|
||||||
|
blogSharingManager.respondToInvitation(id, accept);
|
||||||
|
loadMessages();
|
||||||
|
}
|
||||||
|
|
||||||
private void introductionResponseError() {
|
private void introductionResponseError() {
|
||||||
runOnUiThreadUnlessDestroyed(new Runnable() {
|
runOnUiThreadUnlessDestroyed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,365 +1,74 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.sharing.InvitationsBlogActivity;
|
|
||||||
import org.briarproject.android.sharing.InvitationsForumActivity;
|
|
||||||
import org.briarproject.android.util.AndroidUtils;
|
|
||||||
import org.briarproject.android.util.BriarAdapter;
|
import org.briarproject.android.util.BriarAdapter;
|
||||||
import org.briarproject.api.blogs.BlogInvitationRequest;
|
|
||||||
import org.briarproject.api.clients.SessionId;
|
|
||||||
import org.briarproject.api.forum.ForumInvitationRequest;
|
|
||||||
import org.briarproject.api.introduction.IntroductionRequest;
|
|
||||||
import org.briarproject.api.messaging.PrivateMessageHeader;
|
|
||||||
import org.briarproject.api.sharing.InvitationRequest;
|
|
||||||
import org.briarproject.util.StringUtils;
|
|
||||||
|
|
||||||
import static android.support.v7.widget.RecyclerView.ViewHolder;
|
class ConversationAdapter
|
||||||
import static android.view.View.GONE;
|
extends BriarAdapter<ConversationItem, ConversationItemViewHolder> {
|
||||||
import static android.view.View.VISIBLE;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.BLOG_INVITATION_IN;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.BLOG_INVITATION_OUT;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.FORUM_INVITATION_IN;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.FORUM_INVITATION_OUT;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.INTRODUCTION_IN;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.INTRODUCTION_OUT;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.IncomingItem;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.MSG_IN_UNREAD;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.MSG_OUT;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.NOTICE_IN;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.NOTICE_OUT;
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.OutgoingItem;
|
|
||||||
|
|
||||||
class ConversationAdapter extends BriarAdapter<ConversationItem, ViewHolder> {
|
private RequestListener listener;
|
||||||
|
|
||||||
private IntroductionHandler intro;
|
ConversationAdapter(Context ctx, RequestListener requestListener) {
|
||||||
private String contactName;
|
|
||||||
|
|
||||||
ConversationAdapter(Context ctx, IntroductionHandler introductionHandler) {
|
|
||||||
super(ctx, ConversationItem.class);
|
super(ctx, ConversationItem.class);
|
||||||
intro = introductionHandler;
|
listener = requestListener;
|
||||||
}
|
|
||||||
|
|
||||||
void setContactName(String contactName) {
|
|
||||||
this.contactName = contactName;
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@LayoutRes
|
||||||
@Override
|
@Override
|
||||||
public int getItemViewType(int position) {
|
public int getItemViewType(int position) {
|
||||||
return items.get(position).getType();
|
ConversationItem item = items.get(position);
|
||||||
}
|
if (item instanceof ConversationRequestItem) {
|
||||||
|
return R.layout.list_item_conversation_request;
|
||||||
@Override
|
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
|
|
||||||
View v;
|
|
||||||
|
|
||||||
// outgoing message (local)
|
|
||||||
if (type == MSG_OUT) {
|
|
||||||
v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
|
||||||
R.layout.list_item_msg_out, viewGroup, false);
|
|
||||||
return new MessageHolder(v, type);
|
|
||||||
} else if (type == INTRODUCTION_IN) {
|
|
||||||
v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
|
||||||
R.layout.list_item_introduction_in, viewGroup, false);
|
|
||||||
return new IntroductionHolder(v, type);
|
|
||||||
} else if (type == INTRODUCTION_OUT) {
|
|
||||||
v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
|
||||||
R.layout.list_item_msg_notice_out, viewGroup, false);
|
|
||||||
return new IntroductionHolder(v, type);
|
|
||||||
} else if (type == NOTICE_IN) {
|
|
||||||
v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
|
||||||
R.layout.list_item_notice_in, viewGroup, false);
|
|
||||||
return new NoticeHolder(v, type);
|
|
||||||
} else if (type == NOTICE_OUT) {
|
|
||||||
v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
|
||||||
R.layout.list_item_notice_out, viewGroup, false);
|
|
||||||
return new NoticeHolder(v, type);
|
|
||||||
} else if (type == FORUM_INVITATION_IN || type == BLOG_INVITATION_IN) {
|
|
||||||
v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
|
||||||
R.layout.list_item_shareable_invitation_in, viewGroup,
|
|
||||||
false);
|
|
||||||
return new InvitationHolder(v, type);
|
|
||||||
} else if (type == FORUM_INVITATION_OUT ||
|
|
||||||
type == BLOG_INVITATION_OUT) {
|
|
||||||
v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
|
||||||
R.layout.list_item_msg_notice_out, viewGroup, false);
|
|
||||||
return new InvitationHolder(v, type);
|
|
||||||
}
|
|
||||||
// incoming message (non-local)
|
|
||||||
else {
|
|
||||||
v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
|
||||||
R.layout.list_item_msg_in, viewGroup, false);
|
|
||||||
return new MessageHolder(v, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(ViewHolder ui, int position) {
|
|
||||||
ConversationItem item = getItemAt(position);
|
|
||||||
if (item instanceof ConversationMessageItem) {
|
|
||||||
bindMessage((MessageHolder) ui, (ConversationMessageItem) item);
|
|
||||||
} else if (item instanceof ConversationIntroductionOutItem) {
|
|
||||||
bindIntroduction((IntroductionHolder) ui,
|
|
||||||
(ConversationIntroductionOutItem) item, position);
|
|
||||||
} else if (item instanceof ConversationIntroductionInItem) {
|
|
||||||
bindIntroduction((IntroductionHolder) ui,
|
|
||||||
(ConversationIntroductionInItem) item, position);
|
|
||||||
} else if (item instanceof ConversationNoticeOutItem) {
|
} else if (item instanceof ConversationNoticeOutItem) {
|
||||||
bindNotice((NoticeHolder) ui, (ConversationNoticeOutItem) item);
|
return R.layout.list_item_conversation_notice_out;
|
||||||
} else if (item instanceof ConversationNoticeInItem) {
|
} else if (item instanceof ConversationNoticeInItem) {
|
||||||
bindNotice((NoticeHolder) ui, (ConversationNoticeInItem) item);
|
return R.layout.list_item_conversation_notice_in;
|
||||||
} else if (item instanceof ConversationShareableInvitationOutItem) {
|
} else if (item instanceof ConversationMessageOutItem) {
|
||||||
bindInvitation((InvitationHolder) ui,
|
return R.layout.list_item_conversation_msg_out;
|
||||||
(ConversationShareableInvitationOutItem) item);
|
} else if (item instanceof ConversationMessageInItem) {
|
||||||
} else if (item instanceof ConversationShareableInvitationInItem) {
|
return R.layout.list_item_conversation_msg_in;
|
||||||
bindInvitation((InvitationHolder) ui,
|
|
||||||
(ConversationShareableInvitationInItem) item);
|
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unhandled Conversation Item");
|
throw new IllegalArgumentException("Unknown ConversationItem");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindMessage(MessageHolder ui, ConversationMessageItem item) {
|
@Override
|
||||||
PrivateMessageHeader header = item.getHeader();
|
public ConversationItemViewHolder onCreateViewHolder(ViewGroup viewGroup,
|
||||||
|
@LayoutRes int type) {
|
||||||
if (item instanceof ConversationItem.OutgoingItem) {
|
View v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
||||||
if (((OutgoingItem) item).isSeen()) {
|
type, viewGroup, false);
|
||||||
ui.status.setImageResource(R.drawable.message_delivered_white);
|
switch (type) {
|
||||||
} else if (((OutgoingItem) item).isSent()) {
|
case R.layout.list_item_conversation_msg_in:
|
||||||
ui.status.setImageResource(R.drawable.message_sent_white);
|
return new ConversationItemViewHolder(v);
|
||||||
} else {
|
case R.layout.list_item_conversation_msg_out:
|
||||||
ui.status.setImageResource(R.drawable.message_stored_white);
|
return new ConversationMessageOutViewHolder(v);
|
||||||
}
|
case R.layout.list_item_conversation_notice_in:
|
||||||
} else {
|
return new ConversationNoticeInViewHolder(v);
|
||||||
if (item.getType() == MSG_IN_UNREAD) {
|
case R.layout.list_item_conversation_notice_out:
|
||||||
// TODO implement new unread message highlight according to #232
|
return new ConversationNoticeOutViewHolder(v);
|
||||||
/* int left = ui.layout.getPaddingLeft();
|
case R.layout.list_item_conversation_request:
|
||||||
int top = ui.layout.getPaddingTop();
|
return new ConversationRequestViewHolder(v);
|
||||||
int right = ui.layout.getPaddingRight();
|
default:
|
||||||
int bottom = ui.layout.getPaddingBottom();
|
throw new IllegalArgumentException("Unknown ConversationItem");
|
||||||
|
|
||||||
// show unread messages in different color to not miss them
|
|
||||||
ui.layout.setBackgroundResource(R.drawable.msg_in_unread);
|
|
||||||
|
|
||||||
// re-apply the previous padding due to bug in some Android versions
|
|
||||||
// see: https://code.google.com/p/android/issues/detail?id=17885
|
|
||||||
ui.layout.setPadding(left, top, right, bottom);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.getBody() == null) {
|
|
||||||
ui.body.setText("\u2026");
|
|
||||||
} else if (header.getContentType().equals("text/plain")) {
|
|
||||||
ui.body.setText(
|
|
||||||
StringUtils.trim(StringUtils.fromUtf8(item.getBody())));
|
|
||||||
} else {
|
|
||||||
// TODO support other content types
|
|
||||||
}
|
|
||||||
|
|
||||||
long timestamp = header.getTimestamp();
|
|
||||||
ui.date.setText(AndroidUtils.formatDate(ctx, timestamp));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void bindIntroduction(IntroductionHolder ui,
|
|
||||||
final ConversationIntroductionItem item, final int position) {
|
|
||||||
|
|
||||||
final IntroductionRequest ir = item.getIntroductionRequest();
|
|
||||||
int backgroundRes;
|
|
||||||
|
|
||||||
String message = ir.getMessage();
|
|
||||||
if (StringUtils.isNullOrEmpty(message)) {
|
|
||||||
ui.message.setVisibility(GONE);
|
|
||||||
if (item instanceof ConversationIntroductionOutItem) {
|
|
||||||
backgroundRes = R.drawable.notice_out;
|
|
||||||
} else {
|
|
||||||
backgroundRes = R.drawable.notice_in;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ui.message.setText(StringUtils.trim(message));
|
|
||||||
ui.message.setVisibility(VISIBLE);
|
|
||||||
if (item instanceof ConversationIntroductionOutItem) {
|
|
||||||
backgroundRes = R.drawable.notice_out_bottom;
|
|
||||||
} else {
|
|
||||||
backgroundRes = R.drawable.notice_in_bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outgoing Introduction Request
|
|
||||||
if (item instanceof ConversationIntroductionOutItem) {
|
|
||||||
ui.text.setText(ctx.getString(R.string.introduction_request_sent,
|
|
||||||
contactName, ir.getName()));
|
|
||||||
ConversationIntroductionOutItem i =
|
|
||||||
(ConversationIntroductionOutItem) item;
|
|
||||||
if (i.isSeen()) {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
ui.status.setImageResource(R.drawable.message_delivered);
|
|
||||||
} else if (i.isSent()) {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
ui.status.setImageResource(R.drawable.message_sent);
|
|
||||||
} else {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
ui.status.setImageResource(R.drawable.message_stored);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Incoming Introduction Request (Answered)
|
|
||||||
else if (item.wasAnswered()) {
|
|
||||||
ui.text.setText(ctx.getString(
|
|
||||||
R.string.introduction_request_answered_received,
|
|
||||||
contactName, ir.getName()));
|
|
||||||
ui.acceptButton.setVisibility(GONE);
|
|
||||||
ui.declineButton.setVisibility(GONE);
|
|
||||||
}
|
|
||||||
// Incoming Introduction Request (Not Answered)
|
|
||||||
else {
|
|
||||||
if (item.getIntroductionRequest().contactExists()) {
|
|
||||||
ui.text.setText(ctx.getString(
|
|
||||||
R.string.introduction_request_exists_received,
|
|
||||||
contactName, ir.getName()));
|
|
||||||
} else {
|
|
||||||
ui.text.setText(
|
|
||||||
ctx.getString(R.string.introduction_request_received,
|
|
||||||
contactName, ir.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.getIntroductionRequest().doesIntroduceOtherIdentity()) {
|
|
||||||
// don't allow accept when one of our identities is introduced
|
|
||||||
ui.acceptButton.setVisibility(GONE);
|
|
||||||
ui.text.setText(ctx.getString(
|
|
||||||
R.string.introduction_request_for_our_identity_received,
|
|
||||||
contactName, ir.getName()));
|
|
||||||
} else {
|
|
||||||
ui.acceptButton.setVisibility(VISIBLE);
|
|
||||||
ui.acceptButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
intro.respondToIntroduction(ir.getSessionId(), true);
|
|
||||||
item.setAnswered(true);
|
|
||||||
notifyItemChanged(position);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ui.declineButton.setVisibility(VISIBLE);
|
|
||||||
ui.declineButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
intro.respondToIntroduction(ir.getSessionId(), false);
|
|
||||||
item.setAnswered(true);
|
|
||||||
notifyItemChanged(position);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ui.date.setText(AndroidUtils.formatDate(ctx, item.getTime()));
|
|
||||||
ui.notice.setBackgroundResource(backgroundRes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void bindNotice(NoticeHolder ui, ConversationNoticeItem item) {
|
|
||||||
ui.text.setText(item.getText());
|
|
||||||
ui.date.setText(AndroidUtils.formatDate(ctx, item.getTime()));
|
|
||||||
|
|
||||||
if (item instanceof ConversationNoticeOutItem) {
|
|
||||||
ConversationNoticeOutItem n = (ConversationNoticeOutItem) item;
|
|
||||||
if (n.isSeen()) {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
ui.status.setImageResource(R.drawable.message_delivered);
|
|
||||||
} else if (n.isSent()) {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
ui.status.setImageResource(R.drawable.message_sent);
|
|
||||||
} else {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
ui.status.setImageResource(R.drawable.message_stored);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindInvitation(InvitationHolder ui,
|
@Override
|
||||||
final ConversationShareableInvitationItem item) {
|
public void onBindViewHolder(ConversationItemViewHolder ui, int position) {
|
||||||
|
ConversationItem item = items.get(position);
|
||||||
final InvitationRequest ir = item.getInvitationRequest();
|
if (item instanceof ConversationRequestItem) {
|
||||||
String name = "";
|
((ConversationRequestViewHolder) ui).bind(item, listener);
|
||||||
int receivedRes = 0, sentRes = 0, buttonRes = 0, backgroundRes;
|
|
||||||
if (ir instanceof ForumInvitationRequest) {
|
|
||||||
name = ((ForumInvitationRequest) ir).getForumName();
|
|
||||||
receivedRes = R.string.forum_invitation_received;
|
|
||||||
sentRes = R.string.forum_invitation_sent;
|
|
||||||
buttonRes = R.string.forum_show_invitations;
|
|
||||||
} else if (ir instanceof BlogInvitationRequest) {
|
|
||||||
name = ((BlogInvitationRequest) ir).getBlogAuthorName();
|
|
||||||
receivedRes = R.string.blogs_sharing_invitation_received;
|
|
||||||
sentRes = R.string.blogs_sharing_invitation_sent;
|
|
||||||
buttonRes = R.string.blogs_sharing_show_invitations;
|
|
||||||
}
|
|
||||||
|
|
||||||
String message = ir.getMessage();
|
|
||||||
if (StringUtils.isNullOrEmpty(message)) {
|
|
||||||
ui.message.setVisibility(GONE);
|
|
||||||
if (item instanceof ConversationShareableInvitationOutItem) {
|
|
||||||
backgroundRes = R.drawable.notice_out;
|
|
||||||
} else {
|
|
||||||
backgroundRes = R.drawable.notice_in;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ui.message.setVisibility(VISIBLE);
|
ui.bind(item);
|
||||||
ui.message.setText(StringUtils.trim(message));
|
|
||||||
if (item instanceof ConversationShareableInvitationOutItem) {
|
|
||||||
backgroundRes = R.drawable.notice_out_bottom;
|
|
||||||
} else {
|
|
||||||
backgroundRes = R.drawable.notice_in_bottom;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outgoing Invitation
|
|
||||||
if (item instanceof ConversationShareableInvitationOutItem) {
|
|
||||||
ui.text.setText(ctx.getString(sentRes, name, contactName));
|
|
||||||
ConversationShareableInvitationOutItem i =
|
|
||||||
(ConversationShareableInvitationOutItem) item;
|
|
||||||
if (i.isSeen()) {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
ui.status.setImageResource(R.drawable.message_delivered);
|
|
||||||
} else if (i.isSent()) {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
ui.status.setImageResource(R.drawable.message_sent);
|
|
||||||
} else {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
ui.status.setImageResource(R.drawable.message_stored);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Incoming Invitation
|
|
||||||
else {
|
|
||||||
ui.text.setText(ctx.getString(receivedRes, contactName, name));
|
|
||||||
|
|
||||||
if (ir.isAvailable()) {
|
|
||||||
final Class c = ir instanceof ForumInvitationRequest ?
|
|
||||||
InvitationsForumActivity.class :
|
|
||||||
InvitationsBlogActivity.class;
|
|
||||||
ui.showInvitationsButton.setText(ctx.getString(buttonRes));
|
|
||||||
ui.showInvitationsButton.setVisibility(VISIBLE);
|
|
||||||
ui.showInvitationsButton
|
|
||||||
.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Intent i = new Intent(ctx, c);
|
|
||||||
ctx.startActivity(i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ui.showInvitationsButton.setVisibility(GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui.date.setText(AndroidUtils.formatDate(ctx, item.getTime()));
|
|
||||||
ui.notice.setBackgroundResource(backgroundRes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -393,138 +102,46 @@ class ConversationAdapter extends BriarAdapter<ConversationItem, ViewHolder> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SparseArray<IncomingItem> getIncomingMessages() {
|
SparseArray<ConversationInItem> getIncomingMessages() {
|
||||||
SparseArray<IncomingItem> messages = new SparseArray<>();
|
SparseArray<ConversationInItem> messages = new SparseArray<>();
|
||||||
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
ConversationItem item = items.get(i);
|
ConversationItem item = items.get(i);
|
||||||
if (item instanceof IncomingItem) {
|
if (item instanceof ConversationInItem) {
|
||||||
messages.put(i, (IncomingItem) item);
|
messages.put(i, (ConversationInItem) item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
SparseArray<OutgoingItem> getOutgoingMessages() {
|
SparseArray<ConversationOutItem> getOutgoingMessages() {
|
||||||
SparseArray<OutgoingItem> messages = new SparseArray<>();
|
SparseArray<ConversationOutItem> messages = new SparseArray<>();
|
||||||
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
ConversationItem item = items.get(i);
|
ConversationItem item = items.get(i);
|
||||||
if (item instanceof OutgoingItem) {
|
if (item instanceof ConversationOutItem) {
|
||||||
messages.put(i, (OutgoingItem) item);
|
messages.put(i, (ConversationOutItem) item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
SparseArray<ConversationMessageItem> getPrivateMessages() {
|
SparseArray<ConversationItem> getPrivateMessages() {
|
||||||
SparseArray<ConversationMessageItem> messages = new SparseArray<>();
|
SparseArray<ConversationItem> messages = new SparseArray<>();
|
||||||
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
ConversationItem item = items.get(i);
|
ConversationItem item = items.get(i);
|
||||||
if (item instanceof ConversationMessageItem) {
|
if (item instanceof ConversationMessageInItem) {
|
||||||
messages.put(i, (ConversationMessageItem) item);
|
messages.put(i, item);
|
||||||
|
} else if (item instanceof ConversationMessageOutItem) {
|
||||||
|
messages.put(i, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MessageHolder extends RecyclerView.ViewHolder {
|
interface RequestListener {
|
||||||
|
void respondToRequest(ConversationRequestItem item, boolean accept);
|
||||||
public ViewGroup layout;
|
|
||||||
public TextView body;
|
|
||||||
private TextView date;
|
|
||||||
public ImageView status;
|
|
||||||
|
|
||||||
private MessageHolder(View v, int type) {
|
|
||||||
super(v);
|
|
||||||
|
|
||||||
layout = (ViewGroup) v.findViewById(R.id.msgLayout);
|
|
||||||
body = (TextView) v.findViewById(R.id.msgBody);
|
|
||||||
date = (TextView) v.findViewById(R.id.msgTime);
|
|
||||||
|
|
||||||
// outgoing message (local)
|
|
||||||
if (type == MSG_OUT) {
|
|
||||||
status = (ImageView) v.findViewById(R.id.msgStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class IntroductionHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
private final TextView message;
|
|
||||||
private final ViewGroup notice;
|
|
||||||
private final TextView text;
|
|
||||||
private final Button acceptButton;
|
|
||||||
private final Button declineButton;
|
|
||||||
private final TextView date;
|
|
||||||
private final ImageView status;
|
|
||||||
|
|
||||||
private IntroductionHolder(View v, int type) {
|
|
||||||
super(v);
|
|
||||||
|
|
||||||
message = (TextView) v.findViewById(R.id.msgBody);
|
|
||||||
notice = (ViewGroup) v.findViewById(R.id.noticeLayout);
|
|
||||||
text = (TextView) v.findViewById(R.id.introductionText);
|
|
||||||
acceptButton = (Button) v.findViewById(R.id.acceptButton);
|
|
||||||
declineButton = (Button) v.findViewById(R.id.declineButton);
|
|
||||||
date = (TextView) v.findViewById(R.id.introductionTime);
|
|
||||||
|
|
||||||
if (type == INTRODUCTION_OUT) {
|
|
||||||
status = (ImageView) v.findViewById(R.id.introductionStatus);
|
|
||||||
} else {
|
|
||||||
status = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class NoticeHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
private final TextView text;
|
|
||||||
private final TextView date;
|
|
||||||
private final ImageView status;
|
|
||||||
|
|
||||||
private NoticeHolder(View v, int type) {
|
|
||||||
super(v);
|
|
||||||
|
|
||||||
text = (TextView) v.findViewById(R.id.noticeText);
|
|
||||||
date = (TextView) v.findViewById(R.id.noticeTime);
|
|
||||||
|
|
||||||
if (type == NOTICE_OUT) {
|
|
||||||
status = (ImageView) v.findViewById(R.id.noticeStatus);
|
|
||||||
} else {
|
|
||||||
status = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class InvitationHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
private final TextView message;
|
|
||||||
private final View notice;
|
|
||||||
private final TextView text;
|
|
||||||
private final Button showInvitationsButton;
|
|
||||||
private final TextView date;
|
|
||||||
private final ImageView status;
|
|
||||||
|
|
||||||
private InvitationHolder(View v, int type) {
|
|
||||||
super(v);
|
|
||||||
|
|
||||||
message = (TextView) v.findViewById(R.id.msgBody);
|
|
||||||
text = (TextView) v.findViewById(R.id.introductionText);
|
|
||||||
notice = v.findViewById(R.id.noticeLayout);
|
|
||||||
showInvitationsButton = (Button) v.findViewById(R.id.showInvitationsButton);
|
|
||||||
date = (TextView) v.findViewById(R.id.introductionTime);
|
|
||||||
|
|
||||||
if (type == FORUM_INVITATION_OUT || type == BLOG_INVITATION_OUT) {
|
|
||||||
status = (ImageView) v.findViewById(R.id.introductionStatus);
|
|
||||||
} else {
|
|
||||||
status = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IntroductionHandler {
|
|
||||||
void respondToIntroduction(SessionId sessionId, boolean accept);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
abstract class ConversationInItem extends ConversationItem {
|
||||||
|
|
||||||
|
private boolean read;
|
||||||
|
|
||||||
|
ConversationInItem(MessageId id, GroupId groupId, @Nullable String text,
|
||||||
|
long time, boolean read) {
|
||||||
|
super(id, groupId, text, time);
|
||||||
|
|
||||||
|
this.read = read;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRead() {
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRead(boolean read) {
|
||||||
|
this.read = read;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package org.briarproject.android.contact;
|
|
||||||
|
|
||||||
import org.briarproject.android.contact.ConversationItem.IncomingItem;
|
|
||||||
import org.briarproject.api.introduction.IntroductionRequest;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
// This class is not thread-safe
|
|
||||||
class ConversationIntroductionInItem extends ConversationIntroductionItem
|
|
||||||
implements IncomingItem {
|
|
||||||
|
|
||||||
private boolean read;
|
|
||||||
|
|
||||||
ConversationIntroductionInItem(@NotNull IntroductionRequest ir) {
|
|
||||||
super(ir);
|
|
||||||
|
|
||||||
this.read = ir.isRead();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
int getType() {
|
|
||||||
return INTRODUCTION_IN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRead() {
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRead(boolean read) {
|
|
||||||
this.read = read;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package org.briarproject.android.contact;
|
|
||||||
|
|
||||||
import org.briarproject.api.introduction.IntroductionRequest;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
// This class is not thread-safe
|
|
||||||
abstract class ConversationIntroductionItem extends ConversationItem {
|
|
||||||
|
|
||||||
private final IntroductionRequest ir;
|
|
||||||
private boolean answered;
|
|
||||||
|
|
||||||
ConversationIntroductionItem(@NotNull IntroductionRequest ir) {
|
|
||||||
super(ir.getMessageId(), ir.getGroupId(), ir.getTimestamp());
|
|
||||||
|
|
||||||
this.ir = ir;
|
|
||||||
this.answered = ir.wasAnswered();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
IntroductionRequest getIntroductionRequest() {
|
|
||||||
return ir;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean wasAnswered() {
|
|
||||||
return answered;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAnswered(boolean answered) {
|
|
||||||
this.answered = answered;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package org.briarproject.android.contact;
|
|
||||||
|
|
||||||
import org.briarproject.api.introduction.IntroductionRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is needed and can not be replaced by an ConversationNoticeOutItem,
|
|
||||||
* because it carries the optional introduction message
|
|
||||||
* to be displayed as a regular private message.
|
|
||||||
*
|
|
||||||
* This class is not thread-safe
|
|
||||||
*/
|
|
||||||
class ConversationIntroductionOutItem extends ConversationIntroductionItem
|
|
||||||
implements ConversationItem.OutgoingItem {
|
|
||||||
|
|
||||||
private boolean sent, seen;
|
|
||||||
|
|
||||||
ConversationIntroductionOutItem(IntroductionRequest ir) {
|
|
||||||
super(ir);
|
|
||||||
this.sent = ir.isSent();
|
|
||||||
this.seen = ir.isSeen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
int getType() {
|
|
||||||
return INTRODUCTION_OUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSent() {
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSent(boolean sent) {
|
|
||||||
this.sent = sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSeen() {
|
|
||||||
return seen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSeen(boolean seen) {
|
|
||||||
this.seen = seen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +1,64 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.api.blogs.BlogInvitationResponse;
|
import org.briarproject.android.contact.ConversationRequestItem.RequestType;
|
||||||
|
import org.briarproject.api.blogs.BlogInvitationRequest;
|
||||||
|
import org.briarproject.api.forum.ForumInvitationRequest;
|
||||||
import org.briarproject.api.forum.ForumInvitationResponse;
|
import org.briarproject.api.forum.ForumInvitationResponse;
|
||||||
import org.briarproject.api.introduction.IntroductionMessage;
|
|
||||||
import org.briarproject.api.introduction.IntroductionRequest;
|
import org.briarproject.api.introduction.IntroductionRequest;
|
||||||
import org.briarproject.api.introduction.IntroductionResponse;
|
import org.briarproject.api.introduction.IntroductionResponse;
|
||||||
import org.briarproject.api.messaging.PrivateMessageHeader;
|
import org.briarproject.api.messaging.PrivateMessageHeader;
|
||||||
import org.briarproject.api.sharing.InvitationMessage;
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.api.sharing.InvitationRequest;
|
import org.briarproject.api.sharing.InvitationRequest;
|
||||||
import org.briarproject.api.sharing.InvitationResponse;
|
import org.briarproject.api.sharing.InvitationResponse;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
// This class is not thread-safe
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
public abstract class ConversationItem {
|
|
||||||
|
|
||||||
// this is needed for RecyclerView adapter which requires an int type
|
import static org.briarproject.android.contact.ConversationRequestItem.RequestType.BLOG;
|
||||||
final static int MSG_IN = 0;
|
import static org.briarproject.android.contact.ConversationRequestItem.RequestType.FORUM;
|
||||||
final static int MSG_IN_UNREAD = 1;
|
import static org.briarproject.android.contact.ConversationRequestItem.RequestType.INTRODUCTION;
|
||||||
final static int MSG_OUT = 2;
|
|
||||||
final static int INTRODUCTION_IN = 3;
|
@NotThreadSafe
|
||||||
final static int INTRODUCTION_OUT = 4;
|
@NotNullByDefault
|
||||||
final static int NOTICE_IN = 5;
|
abstract class ConversationItem {
|
||||||
final static int NOTICE_OUT = 6;
|
|
||||||
final static int FORUM_INVITATION_IN = 7;
|
|
||||||
final static int FORUM_INVITATION_OUT = 8;
|
|
||||||
final static int BLOG_INVITATION_IN = 9;
|
|
||||||
final static int BLOG_INVITATION_OUT = 10;
|
|
||||||
|
|
||||||
final private MessageId id;
|
final private MessageId id;
|
||||||
final private GroupId groupId;
|
final private GroupId groupId;
|
||||||
|
protected @Nullable String text;
|
||||||
final private long time;
|
final private long time;
|
||||||
|
|
||||||
public ConversationItem(@NotNull MessageId id, @NotNull GroupId groupId,
|
ConversationItem(MessageId id, GroupId groupId,
|
||||||
long time) {
|
@Nullable String text, long time) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.groupId = groupId;
|
this.groupId = groupId;
|
||||||
|
this.text = text;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract int getType();
|
MessageId getId() {
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public MessageId getId() {
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
GroupId getGroupId() {
|
||||||
public GroupId getGroupId() {
|
|
||||||
return groupId;
|
return groupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
long getTime() {
|
long getTime() {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConversationMessageItem from(PrivateMessageHeader h) {
|
static ConversationItem from(PrivateMessageHeader h) {
|
||||||
if (h.isLocal()) {
|
if (h.isLocal()) {
|
||||||
return new ConversationMessageOutItem(h);
|
return new ConversationMessageOutItem(h);
|
||||||
} else {
|
} else {
|
||||||
@@ -67,17 +66,40 @@ public abstract class ConversationItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConversationIntroductionItem from(IntroductionRequest ir) {
|
static ConversationItem from(Context ctx, String contactName,
|
||||||
|
IntroductionRequest ir) {
|
||||||
if (ir.isLocal()) {
|
if (ir.isLocal()) {
|
||||||
return new ConversationIntroductionOutItem(ir);
|
String text = ctx.getString(R.string.introduction_request_sent,
|
||||||
|
contactName, ir.getName());
|
||||||
|
return new ConversationNoticeOutItem(ir.getMessageId(),
|
||||||
|
ir.getGroupId(), text, ir.getMessage(), ir.getTimestamp(),
|
||||||
|
ir.isSent(), ir.isSeen());
|
||||||
} else {
|
} else {
|
||||||
return new ConversationIntroductionInItem(ir);
|
String text;
|
||||||
|
if (ir.wasAnswered()) {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.introduction_request_answered_received,
|
||||||
|
contactName, ir.getName());
|
||||||
|
return new ConversationNoticeInItem(ir.getMessageId(),
|
||||||
|
ir.getGroupId(), text, ir.getMessage(), ir.getTimestamp(),
|
||||||
|
ir.isRead());
|
||||||
|
} else if (ir.contactExists()){
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.introduction_request_exists_received,
|
||||||
|
contactName, ir.getName());
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(R.string.introduction_request_received,
|
||||||
|
contactName, ir.getName());
|
||||||
|
}
|
||||||
|
return new ConversationRequestItem(ir.getMessageId(),
|
||||||
|
ir.getGroupId(), INTRODUCTION, ir.getSessionId(), text,
|
||||||
|
ir.getMessage(), ir.getTimestamp(), ir.isRead(),
|
||||||
|
ir.wasAnswered());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConversationNoticeItem from(Context ctx, String contactName,
|
static ConversationItem from(Context ctx, String contactName,
|
||||||
IntroductionResponse ir) {
|
IntroductionResponse ir) {
|
||||||
|
|
||||||
if (ir.isLocal()) {
|
if (ir.isLocal()) {
|
||||||
String text;
|
String text;
|
||||||
if (ir.wasAccepted()) {
|
if (ir.wasAccepted()) {
|
||||||
@@ -90,7 +112,7 @@ public abstract class ConversationItem {
|
|||||||
ir.getName());
|
ir.getName());
|
||||||
}
|
}
|
||||||
return new ConversationNoticeOutItem(ir.getMessageId(),
|
return new ConversationNoticeOutItem(ir.getMessageId(),
|
||||||
ir.getGroupId(), text, ir.getTimestamp(), ir.isSent(),
|
ir.getGroupId(), text, null, ir.getTimestamp(), ir.isSent(),
|
||||||
ir.isSeen());
|
ir.isSeen());
|
||||||
} else {
|
} else {
|
||||||
String text;
|
String text;
|
||||||
@@ -110,143 +132,99 @@ public abstract class ConversationItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ConversationNoticeInItem(ir.getMessageId(),
|
return new ConversationNoticeInItem(ir.getMessageId(),
|
||||||
ir.getGroupId(), text, ir.getTimestamp(), ir.isRead());
|
ir.getGroupId(), text, null, ir.getTimestamp(),
|
||||||
|
ir.isRead());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConversationShareableInvitationItem from(
|
static ConversationItem from(Context ctx, String contactName,
|
||||||
InvitationRequest fim) {
|
InvitationRequest ir) {
|
||||||
if (fim.isLocal()) {
|
if (ir.isLocal()) {
|
||||||
return new ConversationShareableInvitationOutItem(fim);
|
String text;
|
||||||
|
if (ir instanceof ForumInvitationRequest) {
|
||||||
|
text = ctx.getString(R.string.forum_invitation_sent,
|
||||||
|
((ForumInvitationRequest) ir).getForumName(),
|
||||||
|
contactName);
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(R.string.blogs_sharing_invitation_sent,
|
||||||
|
((BlogInvitationRequest) ir).getBlogAuthorName(),
|
||||||
|
contactName);
|
||||||
|
}
|
||||||
|
return new ConversationNoticeOutItem(ir.getId(), ir.getGroupId(),
|
||||||
|
text, ir.getMessage(), ir.getTimestamp(), ir.isSent(),
|
||||||
|
ir.isSeen());
|
||||||
} else {
|
} else {
|
||||||
return new ConversationShareableInvitationInItem(fim);
|
String text;
|
||||||
|
RequestType type;
|
||||||
|
if (ir instanceof ForumInvitationRequest) {
|
||||||
|
text = ctx.getString(R.string.forum_invitation_received,
|
||||||
|
contactName,
|
||||||
|
((ForumInvitationRequest) ir).getForumName());
|
||||||
|
type = FORUM;
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(R.string.blogs_sharing_invitation_received,
|
||||||
|
contactName,
|
||||||
|
((BlogInvitationRequest) ir).getBlogAuthorName());
|
||||||
|
type = BLOG;
|
||||||
|
}
|
||||||
|
if (!ir.isAvailable()) {
|
||||||
|
return new ConversationNoticeInItem(ir.getId(), ir.getGroupId(),
|
||||||
|
text, ir.getMessage(), ir.getTimestamp(), ir.isRead());
|
||||||
|
}
|
||||||
|
return new ConversationRequestItem(ir.getId(),
|
||||||
|
ir.getGroupId(), type, ir.getSessionId(), text,
|
||||||
|
ir.getMessage(), ir.getTimestamp(), ir.isRead(),
|
||||||
|
!ir.isAvailable());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConversationNoticeItem from(Context ctx, String contactName,
|
static ConversationItem from(Context ctx, String contactName,
|
||||||
InvitationResponse ir) {
|
InvitationResponse ir) {
|
||||||
|
@StringRes int res;
|
||||||
if (ir instanceof ForumInvitationResponse) {
|
if (ir.isLocal()) {
|
||||||
return from(ctx, contactName, (ForumInvitationResponse) ir);
|
if (ir.wasAccepted()) {
|
||||||
} else if (ir instanceof BlogInvitationResponse) {
|
if (ir instanceof ForumInvitationResponse) {
|
||||||
return from(ctx, contactName, (BlogInvitationResponse) ir);
|
res = R.string.forum_invitation_response_accepted_sent;
|
||||||
|
} else {
|
||||||
|
res = R.string.blogs_sharing_response_accepted_sent;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ir instanceof ForumInvitationResponse) {
|
||||||
|
res = R.string.forum_invitation_response_declined_sent;
|
||||||
|
} else {
|
||||||
|
res = R.string.blogs_sharing_response_declined_sent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String text = ctx.getString(res, contactName);
|
||||||
|
return new ConversationNoticeOutItem(ir.getId(), ir.getGroupId(),
|
||||||
|
text, null, ir.getTimestamp(), ir.isSent(), ir.isSeen());
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unknown Invitation Response.");
|
if (ir.wasAccepted()) {
|
||||||
|
if (ir instanceof ForumInvitationResponse) {
|
||||||
|
res = R.string.forum_invitation_response_accepted_received;
|
||||||
|
} else {
|
||||||
|
res = R.string.blogs_sharing_response_accepted_received;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ir instanceof ForumInvitationResponse) {
|
||||||
|
res = R.string.forum_invitation_response_declined_received;
|
||||||
|
} else {
|
||||||
|
res = R.string.blogs_sharing_response_declined_received;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String text = ctx.getString(res, contactName);
|
||||||
|
return new ConversationNoticeInItem(ir.getId(), ir.getGroupId(),
|
||||||
|
text, null, ir.getTimestamp(), ir.isRead());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ConversationNoticeItem from(Context ctx, String contactName,
|
interface PartialItem {
|
||||||
ForumInvitationResponse fir) {
|
|
||||||
|
@Nullable
|
||||||
|
String getText();
|
||||||
|
|
||||||
|
void setText(String text);
|
||||||
|
|
||||||
if (fir.isLocal()) {
|
|
||||||
String text;
|
|
||||||
if (fir.wasAccepted()) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.forum_invitation_response_accepted_sent,
|
|
||||||
contactName);
|
|
||||||
} else {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.forum_invitation_response_declined_sent,
|
|
||||||
contactName);
|
|
||||||
}
|
|
||||||
return new ConversationNoticeOutItem(fir.getId(), fir.getGroupId(),
|
|
||||||
text, fir.getTimestamp(), fir.isSent(), fir.isSeen());
|
|
||||||
} else {
|
|
||||||
String text;
|
|
||||||
if (fir.wasAccepted()) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.forum_invitation_response_accepted_received,
|
|
||||||
contactName);
|
|
||||||
} else {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.forum_invitation_response_declined_received,
|
|
||||||
contactName);
|
|
||||||
}
|
|
||||||
return new ConversationNoticeInItem(fir.getId(), fir.getGroupId(),
|
|
||||||
text, fir.getTimestamp(), fir.isRead());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ConversationNoticeItem from(Context ctx, String contactName,
|
|
||||||
BlogInvitationResponse fir) {
|
|
||||||
|
|
||||||
if (fir.isLocal()) {
|
|
||||||
String text;
|
|
||||||
if (fir.wasAccepted()) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.blogs_sharing_response_accepted_sent,
|
|
||||||
contactName);
|
|
||||||
} else {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.blogs_sharing_response_declined_sent,
|
|
||||||
contactName);
|
|
||||||
}
|
|
||||||
return new ConversationNoticeOutItem(fir.getId(), fir.getGroupId(),
|
|
||||||
text, fir.getTimestamp(), fir.isSent(), fir.isSeen());
|
|
||||||
} else {
|
|
||||||
String text;
|
|
||||||
if (fir.wasAccepted()) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.blogs_sharing_response_accepted_received,
|
|
||||||
contactName);
|
|
||||||
} else {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.blogs_sharing_response_declined_received,
|
|
||||||
contactName);
|
|
||||||
}
|
|
||||||
return new ConversationNoticeInItem(fir.getId(), fir.getGroupId(),
|
|
||||||
text, fir.getTimestamp(), fir.isRead());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method should not be used to get user-facing objects,
|
|
||||||
* Its purpose is only to provide data for the contact list.
|
|
||||||
*/
|
|
||||||
public static ConversationItem from(IntroductionMessage im) {
|
|
||||||
if (im.isLocal())
|
|
||||||
return new ConversationNoticeOutItem(im.getMessageId(),
|
|
||||||
im.getGroupId(), "", im.getTimestamp(), false, false);
|
|
||||||
return new ConversationNoticeInItem(im.getMessageId(), im.getGroupId(),
|
|
||||||
"", im.getTimestamp(), im.isRead());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method should not be used to get user-facing objects,
|
|
||||||
* Its purpose is only to provide data for the contact list.
|
|
||||||
*/
|
|
||||||
public static ConversationItem from(InvitationMessage im) {
|
|
||||||
if (im.isLocal())
|
|
||||||
return new ConversationNoticeOutItem(im.getId(), im.getGroupId(),
|
|
||||||
"", im.getTimestamp(), false, false);
|
|
||||||
return new ConversationNoticeInItem(im.getId(), im.getGroupId(), "",
|
|
||||||
im.getTimestamp(), im.isRead());
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OutgoingItem {
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
MessageId getId();
|
|
||||||
|
|
||||||
boolean isSent();
|
|
||||||
|
|
||||||
void setSent(boolean sent);
|
|
||||||
|
|
||||||
boolean isSeen();
|
|
||||||
|
|
||||||
void setSeen(boolean seen);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IncomingItem {
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
MessageId getId();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
GroupId getGroupId();
|
|
||||||
|
|
||||||
boolean isRead();
|
|
||||||
|
|
||||||
void setRead(boolean read);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import android.support.annotation.CallSuper;
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.util.AndroidUtils;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationItemViewHolder extends ViewHolder {
|
||||||
|
|
||||||
|
protected final ViewGroup layout;
|
||||||
|
private final TextView text;
|
||||||
|
private final TextView time;
|
||||||
|
|
||||||
|
ConversationItemViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
layout = (ViewGroup) v.findViewById(R.id.layout);
|
||||||
|
text = (TextView) v.findViewById(R.id.text);
|
||||||
|
time = (TextView) v.findViewById(R.id.time);
|
||||||
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
void bind(ConversationItem item) {
|
||||||
|
if (item.getText() == null) {
|
||||||
|
text.setText("\u2026");
|
||||||
|
} else {
|
||||||
|
text.setText(StringUtils.trim(item.getText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
long timestamp = item.getTime();
|
||||||
|
time.setText(AndroidUtils.formatDate(time.getContext(), timestamp));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,31 +1,22 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.android.contact.ConversationItem.PartialItem;
|
||||||
import org.briarproject.api.messaging.PrivateMessageHeader;
|
import org.briarproject.api.messaging.PrivateMessageHeader;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
// This class is not thread-safe
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
class ConversationMessageInItem extends ConversationMessageItem
|
|
||||||
implements ConversationItem.IncomingItem {
|
|
||||||
|
|
||||||
private boolean read;
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationMessageInItem extends ConversationInItem
|
||||||
|
implements PartialItem {
|
||||||
|
|
||||||
ConversationMessageInItem(PrivateMessageHeader header) {
|
ConversationMessageInItem(PrivateMessageHeader h) {
|
||||||
super(header);
|
super(h.getId(), h.getGroupId(), null, h.getTimestamp(), h.isRead());
|
||||||
|
|
||||||
read = header.isRead();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setText(String body) {
|
||||||
int getType() {
|
text = body;
|
||||||
return MSG_IN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRead() {
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRead(boolean read) {
|
|
||||||
this.read = read;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
package org.briarproject.android.contact;
|
|
||||||
|
|
||||||
import org.briarproject.api.messaging.PrivateMessageHeader;
|
|
||||||
|
|
||||||
// This class is not thread-safe
|
|
||||||
abstract class ConversationMessageItem extends ConversationItem {
|
|
||||||
|
|
||||||
private final PrivateMessageHeader header;
|
|
||||||
private byte[] body;
|
|
||||||
|
|
||||||
ConversationMessageItem(PrivateMessageHeader header) {
|
|
||||||
super(header.getId(), header.getGroupId(), header.getTimestamp());
|
|
||||||
|
|
||||||
this.header = header;
|
|
||||||
body = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivateMessageHeader getHeader() {
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] getBody() {
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBody(byte[] body) {
|
|
||||||
this.body = body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +1,23 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.android.contact.ConversationItem.PartialItem;
|
||||||
import org.briarproject.api.messaging.PrivateMessageHeader;
|
import org.briarproject.api.messaging.PrivateMessageHeader;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
// This class is not thread-safe
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
class ConversationMessageOutItem extends ConversationMessageItem
|
|
||||||
implements ConversationItem.OutgoingItem {
|
|
||||||
|
|
||||||
private boolean sent, seen;
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationMessageOutItem extends ConversationOutItem
|
||||||
|
implements PartialItem {
|
||||||
|
|
||||||
ConversationMessageOutItem(PrivateMessageHeader header) {
|
ConversationMessageOutItem(PrivateMessageHeader h) {
|
||||||
super(header);
|
super(h.getId(), h.getGroupId(), null, h.getTimestamp(), h.isSent(),
|
||||||
|
h.isSeen());
|
||||||
sent = header.isSent();
|
|
||||||
seen = header.isSeen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setText(String body) {
|
||||||
int getType() {
|
text = body;
|
||||||
return MSG_OUT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSent() {
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSent(boolean sent) {
|
|
||||||
this.sent = sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSeen() {
|
|
||||||
return seen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSeen(boolean seen) {
|
|
||||||
this.seen = seen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
class ConversationMessageOutViewHolder extends ConversationOutItemViewHolder {
|
||||||
|
|
||||||
|
ConversationMessageOutViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean hasDarkBackground() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,33 +1,29 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
// This class is not thread-safe
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
class ConversationNoticeInItem extends ConversationNoticeItem
|
|
||||||
implements ConversationItem.IncomingItem {
|
|
||||||
|
|
||||||
private boolean read;
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationNoticeInItem extends ConversationInItem {
|
||||||
|
|
||||||
ConversationNoticeInItem(MessageId id, GroupId groupId, String text,
|
@Nullable
|
||||||
long time, boolean read) {
|
private final String msgText;
|
||||||
super(id, groupId, text, time);
|
|
||||||
|
|
||||||
this.read = read;
|
ConversationNoticeInItem(MessageId id, GroupId groupId,
|
||||||
|
String text, @Nullable String msgText, long time,
|
||||||
|
boolean read) {
|
||||||
|
super(id, groupId, text, time, read);
|
||||||
|
this.msgText = msgText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Nullable
|
||||||
int getType() {
|
public String getMsgText() {
|
||||||
return NOTICE_IN;
|
return msgText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRead() {
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRead(boolean read) {
|
|
||||||
this.read = read;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
|
import static android.view.View.GONE;
|
||||||
|
import static android.view.View.VISIBLE;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationNoticeInViewHolder extends ConversationItemViewHolder {
|
||||||
|
|
||||||
|
private final TextView msgText;
|
||||||
|
|
||||||
|
ConversationNoticeInViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
msgText = (TextView) v.findViewById(R.id.msgText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void bind(ConversationItem conversationItem) {
|
||||||
|
super.bind(conversationItem);
|
||||||
|
|
||||||
|
ConversationNoticeInItem item =
|
||||||
|
(ConversationNoticeInItem) conversationItem;
|
||||||
|
|
||||||
|
String message = item.getMsgText();
|
||||||
|
if (StringUtils.isNullOrEmpty(message)) {
|
||||||
|
msgText.setVisibility(GONE);
|
||||||
|
layout.setBackgroundResource(R.drawable.notice_in);
|
||||||
|
} else {
|
||||||
|
msgText.setVisibility(VISIBLE);
|
||||||
|
msgText.setText(StringUtils.trim(message));
|
||||||
|
layout.setBackgroundResource(R.drawable.notice_in_bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.briarproject.android.contact;
|
|
||||||
|
|
||||||
import org.briarproject.api.sync.GroupId;
|
|
||||||
import org.briarproject.api.sync.MessageId;
|
|
||||||
|
|
||||||
abstract class ConversationNoticeItem extends ConversationItem {
|
|
||||||
|
|
||||||
private final String text;
|
|
||||||
|
|
||||||
ConversationNoticeItem(MessageId id, GroupId groupId, String text,
|
|
||||||
long time) {
|
|
||||||
super(id, groupId, time);
|
|
||||||
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +1,29 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
// This class is not thread-safe
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
class ConversationNoticeOutItem extends ConversationNoticeItem
|
|
||||||
implements ConversationItem.OutgoingItem {
|
|
||||||
|
|
||||||
private boolean sent, seen;
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationNoticeOutItem extends ConversationOutItem {
|
||||||
|
|
||||||
ConversationNoticeOutItem(MessageId id, GroupId groupId, String text,
|
@Nullable
|
||||||
long time, boolean sent, boolean seen) {
|
private final String msgText;
|
||||||
super(id, groupId, text, time);
|
|
||||||
|
|
||||||
this.sent = sent;
|
ConversationNoticeOutItem(MessageId id, GroupId groupId,
|
||||||
this.seen = seen;
|
String text, @Nullable String msgText, long time,
|
||||||
|
boolean sent, boolean seen) {
|
||||||
|
super(id, groupId, text, time, sent, seen);
|
||||||
|
this.msgText = msgText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Nullable
|
||||||
int getType() {
|
public String getMsgText() {
|
||||||
return NOTICE_OUT;
|
return msgText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSent() {
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSent(boolean sent) {
|
|
||||||
this.sent = sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSeen() {
|
|
||||||
return seen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSeen(boolean seen) {
|
|
||||||
this.seen = seen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
|
import static android.view.View.GONE;
|
||||||
|
import static android.view.View.VISIBLE;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationNoticeOutViewHolder extends ConversationOutItemViewHolder {
|
||||||
|
|
||||||
|
private final TextView msgText;
|
||||||
|
|
||||||
|
ConversationNoticeOutViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
msgText = (TextView) v.findViewById(R.id.msgText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void bind(ConversationItem conversationItem) {
|
||||||
|
super.bind(conversationItem);
|
||||||
|
|
||||||
|
ConversationNoticeOutItem item =
|
||||||
|
(ConversationNoticeOutItem) conversationItem;
|
||||||
|
|
||||||
|
String message = item.getMsgText();
|
||||||
|
if (StringUtils.isNullOrEmpty(message)) {
|
||||||
|
msgText.setVisibility(GONE);
|
||||||
|
layout.setBackgroundResource(R.drawable.notice_out);
|
||||||
|
} else {
|
||||||
|
msgText.setVisibility(VISIBLE);
|
||||||
|
msgText.setText(StringUtils.trim(message));
|
||||||
|
layout.setBackgroundResource(R.drawable.notice_out_bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean hasDarkBackground() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
abstract class ConversationOutItem extends ConversationItem {
|
||||||
|
|
||||||
|
private boolean sent, seen;
|
||||||
|
|
||||||
|
ConversationOutItem(MessageId id, GroupId groupId, @Nullable String text,
|
||||||
|
long time, boolean sent, boolean seen) {
|
||||||
|
super(id, groupId, text, time);
|
||||||
|
|
||||||
|
this.sent = sent;
|
||||||
|
this.seen = seen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSent() {
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSent(boolean sent) {
|
||||||
|
this.sent = sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSeen() {
|
||||||
|
return seen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeen(boolean seen) {
|
||||||
|
this.seen = seen;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotNullByDefault
|
||||||
|
abstract class ConversationOutItemViewHolder
|
||||||
|
extends ConversationItemViewHolder {
|
||||||
|
|
||||||
|
private final ImageView status;
|
||||||
|
|
||||||
|
ConversationOutItemViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
status = (ImageView) v.findViewById(R.id.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void bind(ConversationItem conversationItem) {
|
||||||
|
super.bind(conversationItem);
|
||||||
|
|
||||||
|
ConversationOutItem item = (ConversationOutItem) conversationItem;
|
||||||
|
|
||||||
|
int res;
|
||||||
|
if (item.isSeen()) {
|
||||||
|
if (hasDarkBackground()) res = R.drawable.message_delivered_white;
|
||||||
|
else res = R.drawable.message_delivered;
|
||||||
|
} else if (item.isSent()) {
|
||||||
|
if (hasDarkBackground()) res = R.drawable.message_sent_white;
|
||||||
|
else res = R.drawable.message_sent;
|
||||||
|
} else {
|
||||||
|
if (hasDarkBackground()) res = R.drawable.message_stored_white;
|
||||||
|
else res = R.drawable.message_stored;
|
||||||
|
}
|
||||||
|
status.setImageResource(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract boolean hasDarkBackground();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.clients.SessionId;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationRequestItem extends ConversationNoticeInItem {
|
||||||
|
|
||||||
|
enum RequestType { INTRODUCTION, FORUM, BLOG };
|
||||||
|
private final RequestType requestType;
|
||||||
|
private final SessionId sessionId;
|
||||||
|
private boolean answered;
|
||||||
|
|
||||||
|
ConversationRequestItem(MessageId id, GroupId groupId,
|
||||||
|
RequestType requestType, SessionId sessionId, String text,
|
||||||
|
@Nullable String msgText, long time, boolean read,
|
||||||
|
boolean answered) {
|
||||||
|
super(id, groupId, text, msgText, time, read);
|
||||||
|
this.requestType = requestType;
|
||||||
|
this.sessionId = sessionId;
|
||||||
|
this.answered = answered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestType getRequestType() {
|
||||||
|
return requestType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SessionId getSessionId() {
|
||||||
|
return sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean wasAnswered() {
|
||||||
|
return answered;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAnswered(boolean answered) {
|
||||||
|
this.answered = answered;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.contact.ConversationAdapter.RequestListener;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import static android.view.View.GONE;
|
||||||
|
import static android.view.View.VISIBLE;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationRequestViewHolder extends ConversationNoticeInViewHolder {
|
||||||
|
|
||||||
|
private final Button acceptButton;
|
||||||
|
private final Button declineButton;
|
||||||
|
|
||||||
|
ConversationRequestViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
acceptButton = (Button) v.findViewById(R.id.acceptButton);
|
||||||
|
declineButton = (Button) v.findViewById(R.id.declineButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(ConversationItem conversationItem,
|
||||||
|
final RequestListener listener) {
|
||||||
|
super.bind(conversationItem);
|
||||||
|
|
||||||
|
final ConversationRequestItem item =
|
||||||
|
(ConversationRequestItem) conversationItem;
|
||||||
|
|
||||||
|
if (item.wasAnswered()) {
|
||||||
|
acceptButton.setVisibility(GONE);
|
||||||
|
declineButton.setVisibility(GONE);
|
||||||
|
} else {
|
||||||
|
acceptButton.setVisibility(VISIBLE);
|
||||||
|
acceptButton.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
item.setAnswered(true);
|
||||||
|
listener.respondToRequest(item, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
declineButton.setVisibility(VISIBLE);
|
||||||
|
declineButton.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
item.setAnswered(true);
|
||||||
|
listener.respondToRequest(item, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package org.briarproject.android.contact;
|
|
||||||
|
|
||||||
import org.briarproject.api.blogs.BlogInvitationRequest;
|
|
||||||
import org.briarproject.api.forum.ForumInvitationRequest;
|
|
||||||
import org.briarproject.api.sharing.InvitationRequest;
|
|
||||||
|
|
||||||
// This class is not thread-safe
|
|
||||||
class ConversationShareableInvitationInItem
|
|
||||||
extends ConversationShareableInvitationItem
|
|
||||||
implements ConversationItem.IncomingItem {
|
|
||||||
|
|
||||||
private final int type;
|
|
||||||
private boolean read;
|
|
||||||
|
|
||||||
ConversationShareableInvitationInItem(InvitationRequest ir) {
|
|
||||||
super(ir);
|
|
||||||
|
|
||||||
if (ir instanceof ForumInvitationRequest) {
|
|
||||||
this.type = FORUM_INVITATION_IN;
|
|
||||||
} else if (ir instanceof BlogInvitationRequest) {
|
|
||||||
this.type = BLOG_INVITATION_IN;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unknown Invitation Type.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.read = ir.isRead();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
int getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRead() {
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRead(boolean read) {
|
|
||||||
this.read = read;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package org.briarproject.android.contact;
|
|
||||||
|
|
||||||
import org.briarproject.api.sharing.InvitationRequest;
|
|
||||||
|
|
||||||
abstract class ConversationShareableInvitationItem extends ConversationItem {
|
|
||||||
|
|
||||||
private final InvitationRequest fim;
|
|
||||||
|
|
||||||
ConversationShareableInvitationItem(InvitationRequest fim) {
|
|
||||||
super(fim.getId(), fim.getGroupId(), fim.getTimestamp());
|
|
||||||
|
|
||||||
this.fim = fim;
|
|
||||||
}
|
|
||||||
|
|
||||||
InvitationRequest getInvitationRequest() {
|
|
||||||
return fim;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package org.briarproject.android.contact;
|
|
||||||
|
|
||||||
import org.briarproject.api.blogs.BlogInvitationRequest;
|
|
||||||
import org.briarproject.api.forum.ForumInvitationRequest;
|
|
||||||
import org.briarproject.api.sharing.InvitationRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is needed and can not be replaced by an ConversationNoticeOutItem,
|
|
||||||
* because it carries the optional invitation message
|
|
||||||
* to be displayed as a regular private message.
|
|
||||||
* <p/>
|
|
||||||
* This class is not thread-safe
|
|
||||||
*/
|
|
||||||
class ConversationShareableInvitationOutItem
|
|
||||||
extends ConversationShareableInvitationItem
|
|
||||||
implements ConversationItem.OutgoingItem {
|
|
||||||
|
|
||||||
private final int type;
|
|
||||||
private boolean sent, seen;
|
|
||||||
|
|
||||||
ConversationShareableInvitationOutItem(InvitationRequest ir) {
|
|
||||||
super(ir);
|
|
||||||
|
|
||||||
if (ir instanceof ForumInvitationRequest) {
|
|
||||||
this.type = FORUM_INVITATION_OUT;
|
|
||||||
} else if (ir instanceof BlogInvitationRequest) {
|
|
||||||
this.type = BLOG_INVITATION_OUT;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unknown Invitation Type.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.sent = ir.isSent();
|
|
||||||
this.seen = ir.isSeen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
int getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSent() {
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSent(boolean sent) {
|
|
||||||
this.sent = sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSeen() {
|
|
||||||
return seen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSeen(boolean seen) {
|
|
||||||
this.seen = seen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user