Fully colorize conversations.
1. Switch from 300 to 500 colors. 2. Colorize incoming conversation bubbles. 3. Colorize recipeint preference activity toolbar. 4. Support inverted colors in avatars. 5. Make status bar icons tint according to secondary color. // FREEBIE
Before Width: | Height: | Size: 343 B |
BIN
res/drawable-hdpi/ic_done_all_white_18dp.png
Normal file
After Width: | Height: | Size: 345 B |
Before Width: | Height: | Size: 269 B |
BIN
res/drawable-hdpi/ic_done_white_18dp.png
Normal file
After Width: | Height: | Size: 281 B |
Before Width: | Height: | Size: 283 B |
BIN
res/drawable-mdpi/ic_done_all_white_18dp.png
Normal file
After Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 230 B |
BIN
res/drawable-mdpi/ic_done_white_18dp.png
Normal file
After Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 388 B |
BIN
res/drawable-xhdpi/ic_done_all_white_18dp.png
Normal file
After Width: | Height: | Size: 389 B |
Before Width: | Height: | Size: 326 B |
BIN
res/drawable-xhdpi/ic_done_white_18dp.png
Normal file
After Width: | Height: | Size: 309 B |
Before Width: | Height: | Size: 494 B |
BIN
res/drawable-xxhdpi/ic_done_all_white_18dp.png
Normal file
After Width: | Height: | Size: 505 B |
Before Width: | Height: | Size: 407 B |
BIN
res/drawable-xxhdpi/ic_done_white_18dp.png
Normal file
After Width: | Height: | Size: 403 B |
Before Width: | Height: | Size: 584 B |
BIN
res/drawable-xxxhdpi/ic_done_all_white_18dp.png
Normal file
After Width: | Height: | Size: 583 B |
Before Width: | Height: | Size: 451 B |
BIN
res/drawable-xxxhdpi/ic_done_white_18dp.png
Normal file
After Width: | Height: | Size: 476 B |
@ -6,7 +6,6 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ListView android:id="@android:id/list"
|
<ListView android:id="@android:id/list"
|
||||||
style="?android:attr/listViewWhiteStyle"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1.0"
|
android:layout_weight="1.0"
|
||||||
@ -19,6 +18,6 @@
|
|||||||
android:divider="@android:color/transparent"
|
android:divider="@android:color/transparent"
|
||||||
android:dividerHeight="0dp"
|
android:dividerHeight="0dp"
|
||||||
android:layout_marginBottom="1dip"
|
android:layout_marginBottom="1dip"
|
||||||
android:cacheColorHint="?android:attr/windowBackground" />
|
android:cacheColorHint="?conversation_background" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -65,7 +65,7 @@
|
|||||||
android:paddingLeft="4dp"
|
android:paddingLeft="4dp"
|
||||||
android:paddingRight="4dp"
|
android:paddingRight="4dp"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textColor="?conversation_received_text_primary_color"
|
android:textColor="?conversation_item_received_text_primary_color"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:autoLink="all"
|
android:autoLink="all"
|
||||||
android:linksClickable="true" />
|
android:linksClickable="true" />
|
||||||
@ -117,9 +117,11 @@
|
|||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:paddingRight="4dp"
|
android:paddingRight="4dp"
|
||||||
android:paddingTop="2dp"
|
android:paddingTop="2dp"
|
||||||
android:src="?menu_lock_icon_small_received"
|
android:src="?menu_lock_icon_small"
|
||||||
android:contentDescription="@string/conversation_item__secure_message_description"
|
android:contentDescription="@string/conversation_item__secure_message_description"
|
||||||
android:visibility="gone" />
|
android:visibility="gone"
|
||||||
|
android:tint="?conversation_item_received_text_secondary_color"
|
||||||
|
android:tintMode="multiply"/>
|
||||||
|
|
||||||
<FrameLayout android:id="@+id/pending_indicator_stub"
|
<FrameLayout android:id="@+id/pending_indicator_stub"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -131,7 +133,7 @@
|
|||||||
android:layout_gravity="left"
|
android:layout_gravity="left"
|
||||||
android:paddingTop="1dip"
|
android:paddingTop="1dip"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textColor="?conversation_received_text_secondary_color"
|
android:textColor="?conversation_item_received_text_secondary_color"
|
||||||
android:textSize="@dimen/conversation_item_date_text_size"
|
android:textSize="@dimen/conversation_item_date_text_size"
|
||||||
android:fontFamily="sans-serif-light"
|
android:fontFamily="sans-serif-light"
|
||||||
android:autoLink="none"
|
android:autoLink="none"
|
||||||
|
@ -147,20 +147,24 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical|end"
|
android:layout_gravity="center_vertical|end"
|
||||||
android:src="@drawable/ic_done_grey600_18dp"
|
android:src="@drawable/ic_done_white_18dp"
|
||||||
android:paddingLeft="2dp"
|
android:paddingLeft="2dp"
|
||||||
android:paddingBottom="2dp"
|
android:paddingBottom="2dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
android:tint="?conversation_item_sent_text_secondary_color"
|
||||||
|
android:tintMode="multiply"
|
||||||
android:contentDescription="@string/conversation_item_sent__delivered_description" />
|
android:contentDescription="@string/conversation_item_sent__delivered_description" />
|
||||||
|
|
||||||
<ImageView android:id="@+id/delivered_indicator"
|
<ImageView android:id="@+id/delivered_indicator"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical|end"
|
android:layout_gravity="center_vertical|end"
|
||||||
android:src="@drawable/ic_done_all_grey600_18dp"
|
android:src="@drawable/ic_done_all_white_18dp"
|
||||||
android:paddingLeft="2dp"
|
android:paddingLeft="2dp"
|
||||||
android:paddingBottom="2dp"
|
android:paddingBottom="2dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
android:tint="?conversation_item_sent_text_secondary_color"
|
||||||
|
android:tintMode="multiply"
|
||||||
android:contentDescription="@string/conversation_item_sent__delivered_description" />
|
android:contentDescription="@string/conversation_item_sent__delivered_description" />
|
||||||
|
|
||||||
<ImageView android:id="@+id/secure_indicator"
|
<ImageView android:id="@+id/secure_indicator"
|
||||||
@ -171,6 +175,8 @@
|
|||||||
android:layout_gravity="center_vertical|end"
|
android:layout_gravity="center_vertical|end"
|
||||||
android:paddingLeft="2dp"
|
android:paddingLeft="2dp"
|
||||||
android:paddingBottom="3dp"
|
android:paddingBottom="3dp"
|
||||||
|
android:tint="?conversation_item_sent_text_secondary_color"
|
||||||
|
android:tintMode="multiply"
|
||||||
android:contentDescription="@string/conversation_item__secure_message_description" />
|
android:contentDescription="@string/conversation_item__secure_message_description" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
@ -25,7 +26,8 @@
|
|||||||
android:layout_height="50dp"
|
android:layout_height="50dp"
|
||||||
android:cropToPadding="true"
|
android:cropToPadding="true"
|
||||||
android:layout_marginLeft="0dp"
|
android:layout_marginLeft="0dp"
|
||||||
android:layout_alignParentLeft="true"/>
|
android:layout_alignParentLeft="true"
|
||||||
|
app:inverted="true"/>
|
||||||
|
|
||||||
<TextView android:id="@+id/name"
|
<TextView android:id="@+id/name"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -39,20 +39,6 @@
|
|||||||
<item>Ukrainian Український</item>
|
<item>Ukrainian Український</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<array name="avatar_colors">
|
|
||||||
<item>#6dcaec</item>
|
|
||||||
<item>#cf9fe7</item>
|
|
||||||
<item>#b6db49</item>
|
|
||||||
<item>#ffd060</item>
|
|
||||||
<item>#ff7979</item>
|
|
||||||
|
|
||||||
<item>#2cb1e1</item>
|
|
||||||
<item>#c182e0</item>
|
|
||||||
<item>#92c500</item>
|
|
||||||
<item>#ffb61c</item>
|
|
||||||
<item>#f83a3a</item>
|
|
||||||
</array>
|
|
||||||
|
|
||||||
<string-array name="language_values">
|
<string-array name="language_values">
|
||||||
<item>zz</item>
|
<item>zz</item>
|
||||||
<item>en</item>
|
<item>en</item>
|
||||||
@ -191,23 +177,23 @@
|
|||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="default_color_choice_values" translatable="false">
|
<string-array name="default_color_choice_values" translatable="false">
|
||||||
<item>#ffE57373</item>
|
<item>#ffF44336</item>
|
||||||
<item>#ffF06292</item>
|
<item>#ffE91E63</item>
|
||||||
<item>#ffBA68C8</item>
|
<item>#ff9C27B0</item>
|
||||||
<item>#ff9575CD</item>
|
<item>#ff673AB7</item>
|
||||||
<item>#ff7986CB</item>
|
<item>#ff3F51B5</item>
|
||||||
<item>#ff64B5F6</item>
|
<item>#ff2196F3</item>
|
||||||
<item>#ff4FC3F7</item>
|
<item>#ff03A9F4</item>
|
||||||
<item>#ff4DD0E1</item>
|
<item>#ff00BCD4</item>
|
||||||
<item>#FF4DB6AC</item>
|
<item>#ff009688</item>
|
||||||
<item>#FF81C784</item>
|
<item>#ff4CAF50</item>
|
||||||
<item>#FFAED581</item>
|
<item>#ff8BC34A</item>
|
||||||
<item>#FFDCE775</item>
|
<!--<item>#FFCDDC39</item>-->
|
||||||
<item>#FFFFD54F</item>
|
<item>#FFFFC107</item>
|
||||||
<item>#FFFFB74D</item>
|
<item>#ffFF9800</item>
|
||||||
<item>#FFFF8A65</item>
|
<item>#ffFF5722</item>
|
||||||
<item>#FFA1887F</item>
|
<item>#ff795548</item>
|
||||||
<item>#FF90A4AE</item>
|
<item>#ff607D8B</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
<attr name="conversation_sent_card_background" format="reference|color"/>
|
<attr name="conversation_sent_card_background" format="reference|color"/>
|
||||||
<attr name="conversation_group_member_name" format="reference|color"/>
|
<attr name="conversation_group_member_name" format="reference|color"/>
|
||||||
<attr name="conversation_received_card_background" format="reference|color"/>
|
<attr name="conversation_received_card_background" format="reference|color"/>
|
||||||
<attr name="conversation_received_text_primary_color" format="reference|color"/>
|
|
||||||
<attr name="conversation_received_text_secondary_color" format="reference|color"/>
|
|
||||||
|
|
||||||
<attr name="fab_color" format="reference|color" />
|
<attr name="fab_color" format="reference|color" />
|
||||||
<attr name="lower_right_divet" format="reference" />
|
<attr name="lower_right_divet" format="reference" />
|
||||||
@ -57,6 +56,8 @@
|
|||||||
<attr name="conversation_item_bubble_background" format="reference|color"/>
|
<attr name="conversation_item_bubble_background" format="reference|color"/>
|
||||||
<attr name="conversation_item_sent_text_primary_color" format="reference|color"/>
|
<attr name="conversation_item_sent_text_primary_color" format="reference|color"/>
|
||||||
<attr name="conversation_item_sent_text_secondary_color" format="reference|color"/>
|
<attr name="conversation_item_sent_text_secondary_color" format="reference|color"/>
|
||||||
|
<attr name="conversation_item_received_text_primary_color" format="reference|color"/>
|
||||||
|
<attr name="conversation_item_received_text_secondary_color" format="reference|color"/>
|
||||||
<attr name="conversation_item_sent_text_indicator_tab_color" format="reference|color"/>
|
<attr name="conversation_item_sent_text_indicator_tab_color" format="reference|color"/>
|
||||||
<attr name="conversation_item_sent_indicator_text_background" format="reference" />
|
<attr name="conversation_item_sent_indicator_text_background" format="reference" />
|
||||||
|
|
||||||
@ -87,7 +88,6 @@
|
|||||||
<attr name="menu_unlock_icon" format="reference" />
|
<attr name="menu_unlock_icon" format="reference" />
|
||||||
<attr name="menu_lock_icon" format="reference" />
|
<attr name="menu_lock_icon" format="reference" />
|
||||||
<attr name="menu_lock_icon_small" format="reference" />
|
<attr name="menu_lock_icon_small" format="reference" />
|
||||||
<attr name="menu_lock_icon_small_received" format="reference" />
|
|
||||||
<attr name="menu_trash_icon" format="reference" />
|
<attr name="menu_trash_icon" format="reference" />
|
||||||
<attr name="menu_selectall_icon" format="reference" />
|
<attr name="menu_selectall_icon" format="reference" />
|
||||||
<attr name="menu_group_icon" format="reference" />
|
<attr name="menu_group_icon" format="reference" />
|
||||||
@ -130,4 +130,8 @@
|
|||||||
<attr name="numColumns" format="integer" />
|
<attr name="numColumns" format="integer" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
|
<declare-styleable name="AvatarImageView">
|
||||||
|
<attr name="inverted" format="boolean"/>
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
<item name="titleTextStyle">@style/TextSecure.TitleTextStyle</item>
|
<item name="titleTextStyle">@style/TextSecure.TitleTextStyle</item>
|
||||||
<item name="subtitleTextStyle">@style/TextSecure.SubtitleTextStyle</item>
|
<item name="subtitleTextStyle">@style/TextSecure.SubtitleTextStyle</item>
|
||||||
<item name="android:textColorPrimary">@color/white</item>
|
<item name="android:textColorPrimary">@color/white</item>
|
||||||
<item name="android:textColorSecondary">#99ffffff</item>
|
<item name="android:textColorSecondary">#BFffffff</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="TextSecure.DarkActionBar.TabBar"
|
<style name="TextSecure.DarkActionBar.TabBar"
|
||||||
@ -61,7 +61,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="TextSecure.SubtitleTextStyle" parent="TextAppearance.AppCompat.Widget.ActionBar.Subtitle">
|
<style name="TextSecure.SubtitleTextStyle" parent="TextAppearance.AppCompat.Widget.ActionBar.Subtitle">
|
||||||
<item name="android:textColor">#99ffffff</item>
|
<item name="android:textColor">#BFffffff</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="TextSecure.IntroActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
|
<style name="TextSecure.IntroActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
|
||||||
|
@ -78,8 +78,6 @@
|
|||||||
<item name="lower_right_divet">@drawable/divet_lower_right_dark</item>
|
<item name="lower_right_divet">@drawable/divet_lower_right_dark</item>
|
||||||
|
|
||||||
<item name="conversation_group_member_name">#99000000</item>
|
<item name="conversation_group_member_name">#99000000</item>
|
||||||
<item name="conversation_received_text_primary_color">#ff333333</item>
|
|
||||||
<item name="conversation_received_text_secondary_color">#99333333</item>
|
|
||||||
|
|
||||||
<item name="contact_selection_push_user">#ff000000</item>
|
<item name="contact_selection_push_user">#ff000000</item>
|
||||||
<item name="contact_selection_lay_user">#a0000000</item>
|
<item name="contact_selection_lay_user">#a0000000</item>
|
||||||
@ -116,10 +114,13 @@
|
|||||||
<item name="emoji_category_symbol">@drawable/emoji_category_symbol_light</item>
|
<item name="emoji_category_symbol">@drawable/emoji_category_symbol_light</item>
|
||||||
<item name="emoji_category_emoticons">@drawable/emoji_category_emoticons_light</item>
|
<item name="emoji_category_emoticons">@drawable/emoji_category_emoticons_light</item>
|
||||||
|
|
||||||
<item name="conversation_item_sent_text_primary_color">#99000000</item>
|
|
||||||
<item name="conversation_item_bubble_background">@color/white</item>
|
<item name="conversation_item_bubble_background">@color/white</item>
|
||||||
|
<item name="conversation_item_sent_text_primary_color">#99000000</item>
|
||||||
<item name="conversation_item_sent_text_secondary_color">#bb000000</item>
|
<item name="conversation_item_sent_text_secondary_color">#bb000000</item>
|
||||||
<item name="conversation_item_sent_text_indicator_tab_color">#99000000</item>
|
<item name="conversation_item_sent_text_indicator_tab_color">#99000000</item>
|
||||||
|
<item name="conversation_item_received_text_primary_color">@color/white</item>
|
||||||
|
<item name="conversation_item_received_text_secondary_color">#BFffffff</item>
|
||||||
<item name="conversation_item_background">@drawable/conversation_item_background</item>
|
<item name="conversation_item_background">@drawable/conversation_item_background</item>
|
||||||
<item name="conversation_item_sent_indicator_text_background">@drawable/conversation_item_sent_indicator_text_shape</item>
|
<item name="conversation_item_sent_indicator_text_background">@drawable/conversation_item_sent_indicator_text_shape</item>
|
||||||
|
|
||||||
@ -140,8 +141,7 @@
|
|||||||
<item name="menu_popup_expand">@drawable/ic_launch_white_24dp</item>
|
<item name="menu_popup_expand">@drawable/ic_launch_white_24dp</item>
|
||||||
<item name="menu_unlock_icon">@drawable/ic_unlocked_white_24dp</item>
|
<item name="menu_unlock_icon">@drawable/ic_unlocked_white_24dp</item>
|
||||||
<item name="menu_lock_icon">@drawable/ic_lock_white_24dp</item>
|
<item name="menu_lock_icon">@drawable/ic_lock_white_24dp</item>
|
||||||
<item name="menu_lock_icon_small">@drawable/ic_lock_black_18dp</item>
|
<item name="menu_lock_icon_small">@drawable/ic_lock_white_18dp</item>
|
||||||
<item name="menu_lock_icon_small_received">@drawable/ic_lock_black_18dp</item>
|
|
||||||
<item name="menu_trash_icon">@drawable/ic_delete_white_24dp</item>
|
<item name="menu_trash_icon">@drawable/ic_delete_white_24dp</item>
|
||||||
<item name="menu_selectall_icon">@drawable/ic_select_all_white_24dp</item>
|
<item name="menu_selectall_icon">@drawable/ic_select_all_white_24dp</item>
|
||||||
<item name="menu_split_icon">@drawable/ic_call_split_white_24dp</item>
|
<item name="menu_split_icon">@drawable/ic_call_split_white_24dp</item>
|
||||||
@ -188,8 +188,6 @@
|
|||||||
<item name="share_list_item_divider">@drawable/share_list_divider_shape_dark</item>
|
<item name="share_list_item_divider">@drawable/share_list_divider_shape_dark</item>
|
||||||
|
|
||||||
<item name="conversation_group_member_name">#99ffffff</item>
|
<item name="conversation_group_member_name">#99ffffff</item>
|
||||||
<item name="conversation_received_text_primary_color">#ffeeeeee</item>
|
|
||||||
<item name="conversation_received_text_secondary_color">#99eeeeee</item>
|
|
||||||
|
|
||||||
<item name="contact_selection_push_user">#ffeeeeee</item>
|
<item name="contact_selection_push_user">#ffeeeeee</item>
|
||||||
<item name="contact_selection_lay_user">#afeeeeee</item>
|
<item name="contact_selection_lay_user">#afeeeeee</item>
|
||||||
@ -201,6 +199,8 @@
|
|||||||
<item name="conversation_item_sent_text_primary_color">#ffffffff</item>
|
<item name="conversation_item_sent_text_primary_color">#ffffffff</item>
|
||||||
<item name="conversation_item_sent_text_secondary_color">#aaeeeeee</item>
|
<item name="conversation_item_sent_text_secondary_color">#aaeeeeee</item>
|
||||||
<item name="conversation_item_sent_text_indicator_tab_color">#99ffffff</item>
|
<item name="conversation_item_sent_text_indicator_tab_color">#99ffffff</item>
|
||||||
|
<item name="conversation_item_received_text_primary_color">@color/white</item>
|
||||||
|
<item name="conversation_item_received_text_secondary_color">#BFffffff</item>
|
||||||
<item name="conversation_item_sent_indicator_text_background">@drawable/conversation_item_sent_indicator_text_shape_dark</item>
|
<item name="conversation_item_sent_indicator_text_background">@drawable/conversation_item_sent_indicator_text_shape_dark</item>
|
||||||
|
|
||||||
<item name="dialog_info_icon">@drawable/ic_info_outline_dark</item>
|
<item name="dialog_info_icon">@drawable/ic_info_outline_dark</item>
|
||||||
@ -254,7 +254,6 @@
|
|||||||
<item name="menu_unlock_icon">@drawable/ic_unlocked_white_24dp</item>
|
<item name="menu_unlock_icon">@drawable/ic_unlocked_white_24dp</item>
|
||||||
<item name="menu_lock_icon">@drawable/ic_lock_white_24dp</item>
|
<item name="menu_lock_icon">@drawable/ic_lock_white_24dp</item>
|
||||||
<item name="menu_lock_icon_small">@drawable/ic_lock_white_18dp</item>
|
<item name="menu_lock_icon_small">@drawable/ic_lock_white_18dp</item>
|
||||||
<item name="menu_lock_icon_small_received">@drawable/ic_lock_white_18dp</item>
|
|
||||||
<item name="menu_trash_icon">@drawable/ic_delete_white_24dp</item>
|
<item name="menu_trash_icon">@drawable/ic_delete_white_24dp</item>
|
||||||
<item name="menu_selectall_icon">@drawable/ic_select_all_white_24dp</item>
|
<item name="menu_selectall_icon">@drawable/ic_select_all_white_24dp</item>
|
||||||
<item name="menu_split_icon">@drawable/ic_call_split_white_24dp</item>
|
<item name="menu_split_icon">@drawable/ic_call_split_white_24dp</item>
|
||||||
|
@ -190,8 +190,16 @@ public class ConversationItem extends LinearLayout {
|
|||||||
private void setBubbleState(MessageRecord messageRecord) {
|
private void setBubbleState(MessageRecord messageRecord) {
|
||||||
int[] attributes = new int[]{R.attr.conversation_item_bubble_background};
|
int[] attributes = new int[]{R.attr.conversation_item_bubble_background};
|
||||||
TypedArray colors = context.obtainStyledAttributes(attributes);
|
TypedArray colors = context.obtainStyledAttributes(attributes);
|
||||||
|
int defaultColor = colors.getColor(0, 0xFFFFFF);
|
||||||
|
|
||||||
bodyBubble.getBackground().setColorFilter(colors.getColor(0, 0xFFFFFFFF), PorterDuff.Mode.MULTIPLY);
|
if (messageRecord.isOutgoing()) {
|
||||||
|
bodyBubble.getBackground().setColorFilter(defaultColor, PorterDuff.Mode.MULTIPLY);
|
||||||
|
} else {
|
||||||
|
bodyBubble.getBackground().setColorFilter(messageRecord.getIndividualRecipient()
|
||||||
|
.getColor()
|
||||||
|
.or(defaultColor),
|
||||||
|
PorterDuff.Mode.MULTIPLY);
|
||||||
|
}
|
||||||
|
|
||||||
colors.recycle();
|
colors.recycle();
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.media.Ringtone;
|
|||||||
import android.media.RingtoneManager;
|
import android.media.RingtoneManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
@ -18,7 +19,6 @@ import android.support.v4.app.Fragment;
|
|||||||
import android.support.v4.preference.PreferenceFragment;
|
import android.support.v4.preference.PreferenceFragment;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@ -26,6 +26,7 @@ import android.widget.TextView;
|
|||||||
import com.afollestad.materialdialogs.AlertDialogWrapper;
|
import com.afollestad.materialdialogs.AlertDialogWrapper;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.VibrateState;
|
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.VibrateState;
|
||||||
@ -53,6 +54,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||||
|
|
||||||
private AvatarImageView avatar;
|
private AvatarImageView avatar;
|
||||||
|
private Toolbar toolbar;
|
||||||
private TextView title;
|
private TextView title;
|
||||||
private TextView blockedIndicator;
|
private TextView blockedIndicator;
|
||||||
|
|
||||||
@ -103,7 +105,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeToolbar() {
|
private void initializeToolbar() {
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
this.toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
@ -115,8 +117,18 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setHeader(Recipients recipients) {
|
private void setHeader(Recipients recipients) {
|
||||||
|
Optional<Integer> color = recipients.getColor();
|
||||||
|
|
||||||
this.avatar.setAvatar(recipients, true);
|
this.avatar.setAvatar(recipients, true);
|
||||||
this.title.setText(recipients.toShortString());
|
this.title.setText(recipients.toShortString());
|
||||||
|
this.toolbar.setBackgroundColor(color.or(getResources().getColor(R.color.textsecure_primary)));
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
int primaryDark = getResources().getColor(R.color.textsecure_primary_dark);
|
||||||
|
|
||||||
|
if (color.isPresent()) getWindow().setStatusBarColor(ContactColors.getStatusTinted(color.get()).or(primaryDark));
|
||||||
|
else getWindow().setStatusBarColor(primaryDark);
|
||||||
|
}
|
||||||
|
|
||||||
if (recipients.isBlocked()) this.blockedIndicator.setVisibility(View.VISIBLE);
|
if (recipients.isBlocked()) this.blockedIndicator.setVisibility(View.VISIBLE);
|
||||||
else this.blockedIndicator.setVisibility(View.GONE);
|
else this.blockedIndicator.setVisibility(View.GONE);
|
||||||
@ -207,11 +219,11 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (recipients.getColor().isPresent()) {
|
if (recipients.getColor().isPresent()) {
|
||||||
colorPreference.setValue(recipients.getColor().get());
|
|
||||||
colorPreference.setEnabled(true);
|
colorPreference.setEnabled(true);
|
||||||
|
colorPreference.setValue(recipients.getColor().get());
|
||||||
} else {
|
} else {
|
||||||
colorPreference.setValue(getResources().getColor(R.color.textsecure_primary));
|
|
||||||
colorPreference.setEnabled(false);
|
colorPreference.setEnabled(false);
|
||||||
|
colorPreference.setValue(getResources().getColor(R.color.textsecure_primary));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recipients.isSingleRecipient() || recipients.isGroupRecipient()) {
|
if (!recipients.isSingleRecipient() || recipients.isGroupRecipient()) {
|
||||||
@ -288,7 +300,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
final int value = (Integer)newValue;
|
final int value = (Integer)newValue;
|
||||||
|
|
||||||
if (value != recipients.getColor().get()) {
|
if (preference.isEnabled() && value != recipients.getColor().get()) {
|
||||||
recipients.setColor(Optional.of(value));
|
recipients.setColor(Optional.of(value));
|
||||||
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
|
@ -2,12 +2,14 @@ package org.thoughtcrime.securesms.components;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
@ -16,6 +18,8 @@ import org.thoughtcrime.securesms.recipients.Recipients;
|
|||||||
|
|
||||||
public class AvatarImageView extends ImageView {
|
public class AvatarImageView extends ImageView {
|
||||||
|
|
||||||
|
private boolean inverted;
|
||||||
|
|
||||||
public AvatarImageView(Context context) {
|
public AvatarImageView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
setScaleType(ScaleType.CENTER_CROP);
|
setScaleType(ScaleType.CENTER_CROP);
|
||||||
@ -24,15 +28,21 @@ public class AvatarImageView extends ImageView {
|
|||||||
public AvatarImageView(Context context, AttributeSet attrs) {
|
public AvatarImageView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
setScaleType(ScaleType.CENTER_CROP);
|
setScaleType(ScaleType.CENTER_CROP);
|
||||||
|
|
||||||
|
if (attrs != null) {
|
||||||
|
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AvatarImageView, 0, 0);
|
||||||
|
inverted = typedArray.getBoolean(0, false);
|
||||||
|
typedArray.recycle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAvatar(@Nullable Recipients recipients, boolean quickContactEnabled) {
|
public void setAvatar(@Nullable Recipients recipients, boolean quickContactEnabled) {
|
||||||
if (recipients != null) {
|
if (recipients != null) {
|
||||||
int backgroundColor = recipients.getColor().or(ContactColors.UNKNOWN_COLOR);
|
int backgroundColor = recipients.getColor().or(ContactColors.UNKNOWN_COLOR);
|
||||||
setImageDrawable(recipients.getContactPhoto().asDrawable(getContext(), backgroundColor));
|
setImageDrawable(recipients.getContactPhoto().asDrawable(getContext(), backgroundColor, inverted));
|
||||||
setAvatarClickHandler(recipients, quickContactEnabled);
|
setAvatarClickHandler(recipients, quickContactEnabled);
|
||||||
} else {
|
} else {
|
||||||
setImageDrawable(ContactPhotoFactory.getDefaultContactPhoto(null).asDrawable(getContext(), ContactColors.UNKNOWN_COLOR));
|
setImageDrawable(ContactPhotoFactory.getDefaultContactPhoto(null).asDrawable(getContext(), ContactColors.UNKNOWN_COLOR, inverted));
|
||||||
setOnClickListener(null);
|
setOnClickListener(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,12 @@ public class BitmapContactPhoto implements ContactPhoto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Drawable asDrawable(Context context, int background) {
|
public Drawable asDrawable(Context context, int color) {
|
||||||
|
return asDrawable(context, color, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drawable asDrawable(Context context, int color, boolean inverted) {
|
||||||
return RoundedDrawable.fromBitmap(bitmap)
|
return RoundedDrawable.fromBitmap(bitmap)
|
||||||
.setScaleType(ImageView.ScaleType.CENTER_CROP)
|
.setScaleType(ImageView.ScaleType.CENTER_CROP)
|
||||||
.setOval(true);
|
.setOval(true);
|
||||||
|
@ -16,40 +16,58 @@ public class ContactColors {
|
|||||||
public static final int UNKNOWN_COLOR = 0xff9E9E9E;
|
public static final int UNKNOWN_COLOR = 0xff9E9E9E;
|
||||||
|
|
||||||
private static final int RED_300 = 0xffE57373;
|
private static final int RED_300 = 0xffE57373;
|
||||||
|
private static final int RED_500 = 0xffF44336;
|
||||||
private static final int RED_700 = 0xFFD32F2F;
|
private static final int RED_700 = 0xFFD32F2F;
|
||||||
private static final int PINK_300 = 0xffF06292;
|
private static final int PINK_300 = 0xffF06292;
|
||||||
|
private static final int PINK_500 = 0xffE91E63;
|
||||||
private static final int PINK_700 = 0xFFC2185B;
|
private static final int PINK_700 = 0xFFC2185B;
|
||||||
private static final int PURPLE_300 = 0xffBA68C8;
|
private static final int PURPLE_300 = 0xffBA68C8;
|
||||||
|
private static final int PURPLE_500 = 0Xff9C27B0;
|
||||||
private static final int PURPLE_700 = 0xFF7B1FA2;
|
private static final int PURPLE_700 = 0xFF7B1FA2;
|
||||||
private static final int DEEP_PURPLE_300 = 0xff9575CD;
|
private static final int DEEP_PURPLE_300 = 0xff9575CD;
|
||||||
|
private static final int DEEP_PURPLE_500 = 0xff673AB7;
|
||||||
private static final int DEEP_PURPLE_700 = 0xFF512DA8;
|
private static final int DEEP_PURPLE_700 = 0xFF512DA8;
|
||||||
private static final int INDIGO_300 = 0xff7986CB;
|
private static final int INDIGO_300 = 0xff7986CB;
|
||||||
private static final int INDIGO_700 = 0xFF303F9F;
|
private static final int INDIGO_500 = 0xff3F51B5;
|
||||||
|
private static final int INDIGO_700 = 0xff303F9F;
|
||||||
private static final int BLUE_300 = 0xff64B5F6;
|
private static final int BLUE_300 = 0xff64B5F6;
|
||||||
|
private static final int BLUE_500 = 0xff2196F3;
|
||||||
private static final int BLUE_700 = 0xFF1976D2;
|
private static final int BLUE_700 = 0xFF1976D2;
|
||||||
private static final int LIGHT_BLUE_300 = 0xff4FC3F7;
|
private static final int LIGHT_BLUE_300 = 0xff4FC3F7;
|
||||||
|
private static final int LIGHT_BLUE_500 = 0xff03A9F4;
|
||||||
private static final int LIGHT_BLUE_700 = 0xFF0288D1;
|
private static final int LIGHT_BLUE_700 = 0xFF0288D1;
|
||||||
private static final int CYAN_300 = 0xff4DD0E1;
|
private static final int CYAN_300 = 0xff4DD0E1;
|
||||||
|
private static final int CYAN_500 = 0xff00BCD4;
|
||||||
private static final int CYAN_700 = 0xFF0097A7;
|
private static final int CYAN_700 = 0xFF0097A7;
|
||||||
private static final int TEAL_300 = 0xFF4DB6AC;
|
private static final int TEAL_300 = 0xFF4DB6AC;
|
||||||
|
private static final int TEAL_500 = 0xff009688;
|
||||||
private static final int TEAL_700 = 0xFF00796B;
|
private static final int TEAL_700 = 0xFF00796B;
|
||||||
private static final int GREEN_300 = 0xFF81C784;
|
private static final int GREEN_300 = 0xFF81C784;
|
||||||
|
private static final int GREEN_500 = 0xff4CAF50;
|
||||||
private static final int GREEN_700 = 0xFF388E3C;
|
private static final int GREEN_700 = 0xFF388E3C;
|
||||||
private static final int LIGHT_GREEN_300 = 0xFFAED581;
|
private static final int LIGHT_GREEN_300 = 0xFFAED581;
|
||||||
|
private static final int LIGHT_GREEN_500 = 0xff8BC34A;
|
||||||
private static final int LIGHT_GREEN_700 = 0xFF689F38;
|
private static final int LIGHT_GREEN_700 = 0xFF689F38;
|
||||||
private static final int LIME_300 = 0xFFDCE775;
|
private static final int LIME_300 = 0xFFDCE775;
|
||||||
|
private static final int LIME_500 = 0XFFCDDC39;
|
||||||
private static final int LIME_700 = 0xFFAFB42B;
|
private static final int LIME_700 = 0xFFAFB42B;
|
||||||
private static final int YELLOW_300 = 0xFFFFF176;
|
private static final int YELLOW_300 = 0xFFFFF176;
|
||||||
|
private static final int YELLOW_500 = 0xffFFEB3B;
|
||||||
private static final int YELLOW_700 = 0xFFFBC02D;
|
private static final int YELLOW_700 = 0xFFFBC02D;
|
||||||
private static final int AMBER_300 = 0xFFFFD54F;
|
private static final int AMBER_300 = 0xFFFFD54F;
|
||||||
|
private static final int AMBER_500 = 0XFFFFC107;
|
||||||
private static final int AMBER_700 = 0xFFFFA000;
|
private static final int AMBER_700 = 0xFFFFA000;
|
||||||
private static final int ORANGE_300 = 0xFFFFB74D;
|
private static final int ORANGE_300 = 0xFFFFB74D;
|
||||||
|
private static final int ORANGE_500 = 0xffFF9800;
|
||||||
private static final int ORANGE_700 = 0xFFF57C00;
|
private static final int ORANGE_700 = 0xFFF57C00;
|
||||||
private static final int DEEP_ORANGE_300 = 0xFFFF8A65;
|
private static final int DEEP_ORANGE_300 = 0xFFFF8A65;
|
||||||
|
private static final int DEEP_ORANGE_500 = 0xffFF5722;
|
||||||
private static final int DEEP_ORANGE_700 = 0xFFE64A19;
|
private static final int DEEP_ORANGE_700 = 0xFFE64A19;
|
||||||
private static final int BROWN_300 = 0xFFA1887F;
|
private static final int BROWN_300 = 0xFFA1887F;
|
||||||
|
private static final int BROWN_500 = 0xff795548;
|
||||||
private static final int BROWN_700 = 0xFF5D4037;
|
private static final int BROWN_700 = 0xFF5D4037;
|
||||||
private static final int BLUE_GREY_300 = 0xFF90A4AE;
|
private static final int BLUE_GREY_300 = 0xFF90A4AE;
|
||||||
|
private static final int BLUE_GREY_500 = 0xff607D8B;
|
||||||
private static final int BLUE_GREY_700 = 0xFF455A64;
|
private static final int BLUE_GREY_700 = 0xFF455A64;
|
||||||
|
|
||||||
private static final List<Integer> MATERIAL_300 = new ArrayList<>(Arrays.asList(
|
private static final List<Integer> MATERIAL_300 = new ArrayList<>(Arrays.asList(
|
||||||
@ -72,6 +90,46 @@ public class ContactColors {
|
|||||||
BLUE_GREY_300)
|
BLUE_GREY_300)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private static final List<Integer> MATERIAL_500 = new ArrayList<>(Arrays.asList(
|
||||||
|
RED_500,
|
||||||
|
PINK_500,
|
||||||
|
PURPLE_500,
|
||||||
|
DEEP_PURPLE_500,
|
||||||
|
INDIGO_500,
|
||||||
|
BLUE_500,
|
||||||
|
LIGHT_BLUE_500,
|
||||||
|
CYAN_500,
|
||||||
|
TEAL_500,
|
||||||
|
GREEN_500,
|
||||||
|
LIGHT_GREEN_500,
|
||||||
|
// LIME_500,
|
||||||
|
AMBER_500,
|
||||||
|
ORANGE_500,
|
||||||
|
DEEP_ORANGE_500,
|
||||||
|
BROWN_500,
|
||||||
|
BLUE_GREY_500)
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final SparseIntArray MATERIAL_500_TO_700 = new SparseIntArray() {{
|
||||||
|
put(RED_500, RED_700);
|
||||||
|
put(PINK_500, PINK_700);
|
||||||
|
put(PURPLE_500, PURPLE_700);
|
||||||
|
put(DEEP_PURPLE_500, DEEP_PURPLE_700);
|
||||||
|
put(INDIGO_500, INDIGO_700);
|
||||||
|
put(BLUE_500, BLUE_700);
|
||||||
|
put(LIGHT_BLUE_500, LIGHT_BLUE_700);
|
||||||
|
put(CYAN_500, CYAN_700);
|
||||||
|
put(TEAL_500, TEAL_700);
|
||||||
|
put(GREEN_500, GREEN_700);
|
||||||
|
put(LIGHT_GREEN_500, LIGHT_GREEN_700);
|
||||||
|
// put(LIME_500, LIME_700);
|
||||||
|
put(AMBER_500, AMBER_700);
|
||||||
|
put(ORANGE_500, ORANGE_700);
|
||||||
|
put(DEEP_ORANGE_500, DEEP_ORANGE_700);
|
||||||
|
put(BROWN_500, BROWN_700);
|
||||||
|
put(BLUE_GREY_500, BLUE_GREY_700);
|
||||||
|
}};
|
||||||
|
|
||||||
private static final SparseIntArray MATERIAL_300_TO_700 = new SparseIntArray() {{
|
private static final SparseIntArray MATERIAL_300_TO_700 = new SparseIntArray() {{
|
||||||
put(RED_300, RED_700);
|
put(RED_300, RED_700);
|
||||||
put(PINK_300, PINK_700);
|
put(PINK_300, PINK_700);
|
||||||
@ -92,15 +150,14 @@ public class ContactColors {
|
|||||||
put(BLUE_GREY_300, BLUE_GREY_700);
|
put(BLUE_GREY_300, BLUE_GREY_700);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
private static final ColorGenerator MATERIAL_GENERATOR = ColorGenerator.create(MATERIAL_500);
|
||||||
private static final ColorGenerator MATERIAL_GENERATOR = ColorGenerator.create(MATERIAL_300);
|
|
||||||
|
|
||||||
public static int generateFor(@NonNull String name) {
|
public static int generateFor(@NonNull String name) {
|
||||||
return MATERIAL_GENERATOR.getColor(name);
|
return MATERIAL_GENERATOR.getColor(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<Integer> getStatusTinted(int color) {
|
public static Optional<Integer> getStatusTinted(int color) {
|
||||||
int statusTinted = MATERIAL_300_TO_700.get(color, -1);
|
int statusTinted = MATERIAL_500_TO_700.get(color, -1);
|
||||||
return statusTinted == -1 ? Optional.<Integer>absent() : Optional.of(statusTinted);
|
return statusTinted == -1 ? Optional.<Integer>absent() : Optional.of(statusTinted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ import android.graphics.drawable.Drawable;
|
|||||||
|
|
||||||
public interface ContactPhoto {
|
public interface ContactPhoto {
|
||||||
|
|
||||||
public Drawable asDrawable(Context context, int background);
|
public Drawable asDrawable(Context context, int color);
|
||||||
|
public Drawable asDrawable(Context context, int color, boolean inverted);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.thoughtcrime.securesms.contacts.avatars;
|
package org.thoughtcrime.securesms.contacts.avatars;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
@ -18,14 +19,20 @@ public class GeneratedContactPhoto implements ContactPhoto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Drawable asDrawable(Context context, int background) {
|
public Drawable asDrawable(Context context, int color) {
|
||||||
|
return asDrawable(context, color, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drawable asDrawable(Context context, int color, boolean inverted) {
|
||||||
int targetSize = context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size);
|
int targetSize = context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size);
|
||||||
|
|
||||||
return TextDrawable.builder()
|
return TextDrawable.builder()
|
||||||
.beginConfig()
|
.beginConfig()
|
||||||
.width(targetSize)
|
.width(targetSize)
|
||||||
.height(targetSize)
|
.height(targetSize)
|
||||||
|
.textColor(inverted ? color : Color.WHITE)
|
||||||
.endConfig()
|
.endConfig()
|
||||||
.buildRound(String.valueOf(name.charAt(0)), background);
|
.buildRound(String.valueOf(name.charAt(0)), inverted ? Color.WHITE : color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package org.thoughtcrime.securesms.contacts.avatars;
|
package org.thoughtcrime.securesms.contacts.avatars;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.ColorFilter;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.LayerDrawable;
|
import android.graphics.drawable.LayerDrawable;
|
||||||
|
import android.support.v4.graphics.ColorUtils;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import com.amulyakhare.textdrawable.TextDrawable;
|
import com.amulyakhare.textdrawable.TextDrawable;
|
||||||
@ -17,11 +21,21 @@ public class ResourceContactPhoto implements ContactPhoto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Drawable asDrawable(Context context, int backgroundColor) {
|
public Drawable asDrawable(Context context, int color) {
|
||||||
Drawable background = TextDrawable.builder().buildRound(" ", backgroundColor);
|
return asDrawable(context, color, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drawable asDrawable(Context context, int color, boolean inverted) {
|
||||||
|
Drawable background = TextDrawable.builder().buildRound(" ", inverted ? Color.WHITE : color);
|
||||||
RoundedDrawable foreground = (RoundedDrawable) RoundedDrawable.fromDrawable(context.getResources().getDrawable(resourceId));
|
RoundedDrawable foreground = (RoundedDrawable) RoundedDrawable.fromDrawable(context.getResources().getDrawable(resourceId));
|
||||||
|
|
||||||
foreground.setScaleType(ImageView.ScaleType.CENTER);
|
foreground.setScaleType(ImageView.ScaleType.CENTER);
|
||||||
|
|
||||||
|
if (inverted) {
|
||||||
|
foreground.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||||
|
}
|
||||||
|
|
||||||
return new ExpandingLayerDrawable(new Drawable[] {background, foreground});
|
return new ExpandingLayerDrawable(new Drawable[] {background, foreground});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,12 @@ public class TransparentContactPhoto implements ContactPhoto {
|
|||||||
TransparentContactPhoto() {}
|
TransparentContactPhoto() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Drawable asDrawable(Context context, int background) {
|
public Drawable asDrawable(Context context, int color) {
|
||||||
|
return asDrawable(context, color, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drawable asDrawable(Context context, int color, boolean inverted) {
|
||||||
return RoundedDrawable.fromDrawable(context.getResources().getDrawable(android.R.color.transparent));
|
return RoundedDrawable.fromDrawable(context.getResources().getDrawable(android.R.color.transparent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,14 @@ import android.support.annotation.NonNull;
|
|||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientProvider.RecipientDetails;
|
import org.thoughtcrime.securesms.recipients.RecipientProvider.RecipientDetails;
|
||||||
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
||||||
|
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -46,31 +48,28 @@ public class Recipient {
|
|||||||
|
|
||||||
private ContactPhoto contactPhoto;
|
private ContactPhoto contactPhoto;
|
||||||
private Uri contactUri;
|
private Uri contactUri;
|
||||||
|
private Optional<Integer> color;
|
||||||
|
|
||||||
Recipient(long recipientId, String number, ListenableFutureTask<RecipientDetails> future)
|
Recipient(long recipientId, String number, ListenableFutureTask<RecipientDetails> future)
|
||||||
{
|
{
|
||||||
this.recipientId = recipientId;
|
this.recipientId = recipientId;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
this.contactPhoto = ContactPhotoFactory.getLoadingPhoto();
|
this.contactPhoto = ContactPhotoFactory.getLoadingPhoto();
|
||||||
|
this.color = Optional.absent();
|
||||||
|
|
||||||
future.addListener(new FutureTaskListener<RecipientDetails>() {
|
future.addListener(new FutureTaskListener<RecipientDetails>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(RecipientDetails result) {
|
public void onSuccess(RecipientDetails result) {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
Set<RecipientModifiedListener> localListeners;
|
|
||||||
|
|
||||||
synchronized (Recipient.this) {
|
synchronized (Recipient.this) {
|
||||||
Recipient.this.name = result.name;
|
Recipient.this.name = result.name;
|
||||||
Recipient.this.number = result.number;
|
Recipient.this.number = result.number;
|
||||||
Recipient.this.contactUri = result.contactUri;
|
Recipient.this.contactUri = result.contactUri;
|
||||||
Recipient.this.contactPhoto = result.avatar;
|
Recipient.this.contactPhoto = result.avatar;
|
||||||
|
Recipient.this.color = result.color;
|
||||||
localListeners = new HashSet<>(listeners);
|
|
||||||
listeners.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (RecipientModifiedListener listener : localListeners)
|
notifyListeners();
|
||||||
listener.onModified(Recipient.this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +86,7 @@ public class Recipient {
|
|||||||
this.contactUri = details.contactUri;
|
this.contactUri = details.contactUri;
|
||||||
this.name = details.name;
|
this.name = details.name;
|
||||||
this.contactPhoto = details.avatar;
|
this.contactPhoto = details.avatar;
|
||||||
|
this.color = details.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Uri getContactUri() {
|
public synchronized Uri getContactUri() {
|
||||||
@ -97,6 +97,20 @@ public class Recipient {
|
|||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized @NonNull Optional<Integer> getColor() {
|
||||||
|
if (color.isPresent()) return color;
|
||||||
|
else if (name != null) return Optional.of(ContactColors.generateFor(name));
|
||||||
|
else return Optional.of(ContactColors.UNKNOWN_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(Optional<Integer> color) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
public String getNumber() {
|
public String getNumber() {
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
@ -126,7 +140,9 @@ public class Recipient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Recipient getUnknownRecipient() {
|
public static Recipient getUnknownRecipient() {
|
||||||
return new Recipient(-1, new RecipientDetails("Unknown", "Unknown", null, ContactPhotoFactory.getDefaultContactPhoto("Unknown")));
|
return new Recipient(-1, new RecipientDetails("Unknown", "Unknown", null,
|
||||||
|
ContactPhotoFactory.getDefaultContactPhoto("Unknown"),
|
||||||
|
Optional.<Integer>absent()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -144,6 +160,17 @@ public class Recipient {
|
|||||||
return 31 + (int)this.recipientId;
|
return 31 + (int)this.recipientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyListeners() {
|
||||||
|
Set<RecipientModifiedListener> localListeners;
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
localListeners = new HashSet<>(listeners);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RecipientModifiedListener listener : localListeners)
|
||||||
|
listener.onModified(Recipient.this);
|
||||||
|
}
|
||||||
|
|
||||||
public interface RecipientModifiedListener {
|
public interface RecipientModifiedListener {
|
||||||
public void onModified(Recipient recipient);
|
public void onModified(Recipient recipient);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.util.GroupUtil;
|
|||||||
import org.thoughtcrime.securesms.util.LRUCache;
|
import org.thoughtcrime.securesms.util.LRUCache;
|
||||||
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -67,9 +68,9 @@ public class RecipientProvider {
|
|||||||
String number = CanonicalAddressDatabase.getInstance(context).getAddressFromId(recipientId);
|
String number = CanonicalAddressDatabase.getInstance(context).getAddressFromId(recipientId);
|
||||||
|
|
||||||
if (asynchronous) {
|
if (asynchronous) {
|
||||||
cachedRecipient = new Recipient(recipientId, number, getRecipientDetailsAsync(context, number));
|
cachedRecipient = new Recipient(recipientId, number, getRecipientDetailsAsync(context, recipientId, number));
|
||||||
} else {
|
} else {
|
||||||
cachedRecipient = new Recipient(recipientId, getRecipientDetailsSync(context, number));
|
cachedRecipient = new Recipient(recipientId, getRecipientDetailsSync(context, recipientId, number));
|
||||||
}
|
}
|
||||||
|
|
||||||
recipientCache.put(recipientId, cachedRecipient);
|
recipientCache.put(recipientId, cachedRecipient);
|
||||||
@ -99,12 +100,13 @@ public class RecipientProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull ListenableFutureTask<RecipientDetails> getRecipientDetailsAsync(final Context context,
|
private @NonNull ListenableFutureTask<RecipientDetails> getRecipientDetailsAsync(final Context context,
|
||||||
|
final long recipientId,
|
||||||
final String number)
|
final String number)
|
||||||
{
|
{
|
||||||
Callable<RecipientDetails> task = new Callable<RecipientDetails>() {
|
Callable<RecipientDetails> task = new Callable<RecipientDetails>() {
|
||||||
@Override
|
@Override
|
||||||
public RecipientDetails call() throws Exception {
|
public RecipientDetails call() throws Exception {
|
||||||
return getRecipientDetailsSync(context, number);
|
return getRecipientDetailsSync(context, recipientId, number);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -113,12 +115,14 @@ public class RecipientProvider {
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull RecipientDetails getRecipientDetailsSync(Context context, String number) {
|
private @NonNull RecipientDetails getRecipientDetailsSync(Context context, long recipientId, String number) {
|
||||||
if (GroupUtil.isEncodedGroup(number)) return getGroupRecipientDetails(context, number);
|
if (GroupUtil.isEncodedGroup(number)) return getGroupRecipientDetails(context, number);
|
||||||
else return getIndividualRecipientDetails(context, number);
|
else return getIndividualRecipientDetails(context, recipientId, number);
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull RecipientDetails getIndividualRecipientDetails(Context context, String number) {
|
private @NonNull RecipientDetails getIndividualRecipientDetails(Context context, long recipientId, String number) {
|
||||||
|
Optional<RecipientsPreferences> preferences = DatabaseFactory.getRecipientPreferenceDatabase(context).getRecipientsPreferences(new long[]{recipientId});
|
||||||
|
Optional<Integer> color = preferences.isPresent() ? preferences.get().getColor() : Optional.<Integer>absent();
|
||||||
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
|
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
|
||||||
Cursor cursor = context.getContentResolver().query(uri, CALLER_ID_PROJECTION,
|
Cursor cursor = context.getContentResolver().query(uri, CALLER_ID_PROJECTION,
|
||||||
null, null, null);
|
null, null, null);
|
||||||
@ -131,14 +135,14 @@ public class RecipientProvider {
|
|||||||
Uri.withAppendedPath(Contacts.CONTENT_URI, cursor.getLong(2) + ""),
|
Uri.withAppendedPath(Contacts.CONTENT_URI, cursor.getLong(2) + ""),
|
||||||
name);
|
name);
|
||||||
|
|
||||||
return new RecipientDetails(cursor.getString(0), cursor.getString(3), contactUri, contactPhoto);
|
return new RecipientDetails(cursor.getString(0), cursor.getString(3), contactUri, contactPhoto, color);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null)
|
if (cursor != null)
|
||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RecipientDetails(null, number, null, ContactPhotoFactory.getDefaultContactPhoto(null));
|
return new RecipientDetails(null, number, null, ContactPhotoFactory.getDefaultContactPhoto(null), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull RecipientDetails getGroupRecipientDetails(Context context, String groupId) {
|
private @NonNull RecipientDetails getGroupRecipientDetails(Context context, String groupId) {
|
||||||
@ -148,13 +152,13 @@ public class RecipientProvider {
|
|||||||
|
|
||||||
if (record != null) {
|
if (record != null) {
|
||||||
ContactPhoto contactPhoto = ContactPhotoFactory.getGroupContactPhoto(record.getAvatar());
|
ContactPhoto contactPhoto = ContactPhotoFactory.getGroupContactPhoto(record.getAvatar());
|
||||||
return new RecipientDetails(record.getTitle(), groupId, null, contactPhoto);
|
return new RecipientDetails(record.getTitle(), groupId, null, contactPhoto, Optional.<Integer>absent());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RecipientDetails(null, groupId, null, ContactPhotoFactory.getDefaultGroupPhoto());
|
return new RecipientDetails(null, groupId, null, ContactPhotoFactory.getDefaultGroupPhoto(), Optional.<Integer>absent());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w("RecipientProvider", e);
|
Log.w("RecipientProvider", e);
|
||||||
return new RecipientDetails(null, groupId, null, ContactPhotoFactory.getDefaultGroupPhoto());
|
return new RecipientDetails(null, groupId, null, ContactPhotoFactory.getDefaultGroupPhoto(), Optional.<Integer>absent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,14 +186,17 @@ public class RecipientProvider {
|
|||||||
@NonNull public final String number;
|
@NonNull public final String number;
|
||||||
@NonNull public final ContactPhoto avatar;
|
@NonNull public final ContactPhoto avatar;
|
||||||
@Nullable public final Uri contactUri;
|
@Nullable public final Uri contactUri;
|
||||||
|
@NonNull public final Optional<Integer> color;
|
||||||
|
|
||||||
public RecipientDetails(@Nullable String name, @NonNull String number,
|
public RecipientDetails(@Nullable String name, @NonNull String number,
|
||||||
@Nullable Uri contactUri, @NonNull ContactPhoto avatar)
|
@Nullable Uri contactUri, @NonNull ContactPhoto avatar,
|
||||||
|
@NonNull Optional<Integer> color)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
this.contactUri = contactUri;
|
this.contactUri = contactUri;
|
||||||
|
this.color = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ import android.support.annotation.Nullable;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Patterns;
|
import android.util.Patterns;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
||||||
@ -55,7 +54,6 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
|||||||
private long mutedUntil = 0;
|
private long mutedUntil = 0;
|
||||||
private boolean blocked = false;
|
private boolean blocked = false;
|
||||||
private VibrateState vibrate = VibrateState.DEFAULT;
|
private VibrateState vibrate = VibrateState.DEFAULT;
|
||||||
private Optional<Integer> color = Optional.absent();
|
|
||||||
|
|
||||||
Recipients() {
|
Recipients() {
|
||||||
this(new LinkedList<Recipient>(), (RecipientsPreferences)null);
|
this(new LinkedList<Recipient>(), (RecipientsPreferences)null);
|
||||||
@ -69,7 +67,6 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
|||||||
mutedUntil = preferences.getMuteUntil();
|
mutedUntil = preferences.getMuteUntil();
|
||||||
vibrate = preferences.getVibrateState();
|
vibrate = preferences.getVibrateState();
|
||||||
blocked = preferences.isBlocked();
|
blocked = preferences.isBlocked();
|
||||||
color = preferences.getColor();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +85,6 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
|||||||
mutedUntil = result.getMuteUntil();
|
mutedUntil = result.getMuteUntil();
|
||||||
vibrate = result.getVibrateState();
|
vibrate = result.getVibrateState();
|
||||||
blocked = result.isBlocked();
|
blocked = result.isBlocked();
|
||||||
color = result.getColor();
|
|
||||||
|
|
||||||
localListeners = new HashSet<>(listeners);
|
localListeners = new HashSet<>(listeners);
|
||||||
}
|
}
|
||||||
@ -106,21 +102,6 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Optional<Integer> getColor() {
|
|
||||||
if (color.isPresent()) return color;
|
|
||||||
else if (isGroupRecipient()) return Optional.absent();
|
|
||||||
else if (recipients.get(0).getName() == null) return Optional.absent();
|
|
||||||
else return Optional.of(ContactColors.generateFor(recipients.get(0).getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(Optional<Integer> color) {
|
|
||||||
synchronized (this) {
|
|
||||||
this.color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized @Nullable Uri getRingtone() {
|
public synchronized @Nullable Uri getRingtone() {
|
||||||
return ringtone;
|
return ringtone;
|
||||||
}
|
}
|
||||||
@ -169,12 +150,22 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull
|
public @NonNull ContactPhoto getContactPhoto() {
|
||||||
ContactPhoto getContactPhoto() {
|
|
||||||
if (recipients.size() == 1) return recipients.get(0).getContactPhoto();
|
if (recipients.size() == 1) return recipients.get(0).getContactPhoto();
|
||||||
else return ContactPhotoFactory.getDefaultGroupPhoto();
|
else return ContactPhotoFactory.getDefaultGroupPhoto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized @NonNull Optional<Integer> getColor() {
|
||||||
|
if (!isSingleRecipient() || isGroupRecipient()) return Optional.absent();
|
||||||
|
else if (isEmpty()) return Optional.absent();
|
||||||
|
else return recipients.get(0).getColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setColor(Optional<Integer> color) {
|
||||||
|
if (!isSingleRecipient() || isGroupRecipient()) throw new AssertionError("Groups don't have colors!");
|
||||||
|
else if (!isEmpty()) recipients.get(0).setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized void addListener(RecipientsModifiedListener listener) {
|
public synchronized void addListener(RecipientsModifiedListener listener) {
|
||||||
if (listeners.isEmpty()) {
|
if (listeners.isEmpty()) {
|
||||||
for (Recipient recipient : recipients) {
|
for (Recipient recipient : recipients) {
|
||||||
|