mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 16:57:50 +00:00
Implement new conversation button redesign
This commit is contained in:
parent
8ff4688de1
commit
f6a8cd93da
18
res/drawable/ic_group.xml
Normal file
18
res/drawable/ic_group.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="22dp"
|
||||
android:viewportWidth="32"
|
||||
android:viewportHeight="22">
|
||||
<path
|
||||
android:pathData="M15.625,10.9375C16.6015,10.9375 17.513,10.6933 18.3593,10.2051C19.2057,9.7168 19.873,9.0495 20.3613,8.2031C20.8496,7.3568 21.0937,6.4453 21.0937,5.4687C21.0937,4.4922 20.8496,3.5807 20.3613,2.7344C19.873,1.888 19.2057,1.2207 18.3593,0.7324C17.513,0.2441 16.6015,0 15.625,0C14.6484,0 13.7369,0.2441 12.8906,0.7324C12.0442,1.2207 11.3769,1.888 10.8886,2.7344C10.4004,3.5807 10.1562,4.4922 10.1562,5.4687C10.1562,6.4453 10.4004,7.3568 10.8886,8.2031C11.3769,9.0495 12.0442,9.7168 12.8906,10.2051C13.7369,10.6933 14.6484,10.9375 15.625,10.9375ZM26.5624,9.375C27.6367,9.375 28.5562,8.9925 29.3212,8.2275C30.0862,7.4625 30.4687,6.543 30.4687,5.4687C30.4687,4.3945 30.0862,3.4749 29.3212,2.71C28.5562,1.945 27.6367,1.5625 26.5624,1.5625C25.4882,1.5625 24.5686,1.945 23.8037,2.71C23.0387,3.4749 22.6562,4.3945 22.6562,5.4687C22.6562,6.543 23.0387,7.4625 23.8037,8.2275C24.5686,8.9925 25.4882,9.375 26.5624,9.375ZM4.6875,9.375C5.7617,9.375 6.6813,8.9925 7.4463,8.2275C8.2112,7.4625 8.5937,6.543 8.5937,5.4687C8.5937,4.3945 8.2112,3.4749 7.4463,2.71C6.6813,1.945 5.7617,1.5625 4.6875,1.5625C3.6133,1.5625 2.6937,1.945 1.9287,2.71C1.1637,3.4749 0.7812,4.3945 0.7812,5.4687C0.7812,6.543 1.1637,7.4625 1.9287,8.2275C2.6937,8.9925 3.6133,9.375 4.6875,9.375ZM15.625,8.5937C14.7786,8.5937 14.0462,8.2845 13.4277,7.666C12.8092,7.0475 12.5,6.3151 12.5,5.4687C12.5,4.6224 12.8092,3.89 13.4277,3.2715C14.0462,2.653 14.7786,2.3437 15.625,2.3437C16.4713,2.3437 17.2037,2.653 17.8222,3.2715C18.4407,3.89 18.75,4.6224 18.75,5.4687C18.75,6.3151 18.4407,7.0475 17.8222,7.666C17.2037,8.2845 16.4713,8.5937 15.625,8.5937ZM26.5624,7.0312C26.1393,7.0312 25.7731,6.8766 25.4638,6.5674C25.1546,6.2581 24.9999,5.8919 24.9999,5.4687C24.9999,5.0456 25.1546,4.6794 25.4638,4.3701C25.7731,4.0609 26.1393,3.9062 26.5624,3.9062C26.9856,3.9062 27.3518,4.0609 27.6611,4.3701C27.9703,4.6794 28.1249,5.0456 28.1249,5.4687C28.1249,5.8919 27.9703,6.2581 27.6611,6.5674C27.3518,6.8766 26.9856,7.0312 26.5624,7.0312ZM4.6875,7.0312C4.2643,7.0312 3.8981,6.8766 3.5889,6.5674C3.2796,6.2581 3.125,5.8919 3.125,5.4687C3.125,5.0456 3.2796,4.6794 3.5889,4.3701C3.8981,4.0609 4.2643,3.9062 4.6875,3.9062C5.1107,3.9062 5.4769,4.0609 5.7861,4.3701C6.0954,4.6794 6.25,5.0456 6.25,5.4687C6.25,5.8919 6.0954,6.2581 5.7861,6.5674C5.4769,6.8766 5.1107,7.0312 4.6875,7.0312ZM30.0781,16.2109C30.4036,16.2109 30.6803,16.097 30.9081,15.8691C31.136,15.6412 31.2499,15.3645 31.2499,15.039C31.2499,13.8997 30.8512,12.9313 30.0536,12.1338C29.2561,11.3362 28.2877,10.9375 27.1484,10.9375L27.1484,10.9375L25.9765,10.9375C25.1301,10.9375 24.3652,11.1653 23.6816,11.6211C24.3652,12.1419 24.9348,12.7278 25.3906,13.3789C25.6184,13.3138 25.8137,13.2812 25.9765,13.2812L25.9765,13.2812L27.1484,13.2812C27.6367,13.2812 28.0517,13.4521 28.3935,13.7939C28.7353,14.1357 28.9062,14.5507 28.9062,15.039C28.9062,15.3645 29.0201,15.6412 29.248,15.8691C29.4758,16.097 29.7525,16.2109 30.0781,16.2109ZM1.1719,16.2109C1.4974,16.2109 1.7741,16.097 2.0019,15.8691C2.2298,15.6412 2.3437,15.3645 2.3437,15.039C2.3437,14.5507 2.5146,14.1357 2.8564,13.7939C3.1982,13.4521 3.6133,13.2812 4.1016,13.2812L4.1016,13.2812L5.2734,13.2812C5.4687,13.2812 5.664,13.33 5.8594,13.4277C6.3151,12.7441 6.8847,12.1419 7.5683,11.6211C6.8847,11.1653 6.1198,10.9375 5.2734,10.9375L5.2734,10.9375L4.1016,10.9375C2.9622,10.9375 1.9938,11.3362 1.1963,12.1338C0.3988,12.9313 0,13.8997 0,15.039C0,15.3645 0.1139,15.6412 0.3418,15.8691C0.5697,16.097 0.8464,16.2109 1.1719,16.2109ZM22.6562,21.8749C23.3072,21.8749 23.8606,21.6471 24.3163,21.1914C24.7721,20.7356 24.9999,20.1822 24.9999,19.5312L24.9999,19.5312L24.9999,17.3339C24.9999,16.1946 24.6744,15.153 24.0234,14.209C23.3723,13.2324 22.469,12.5569 21.3134,12.1826C20.1578,11.8082 18.9941,11.8001 17.8222,12.1582C17.0735,12.386 16.333,12.5 15.6005,12.5C14.8681,12.5 14.1438,12.386 13.4277,12.1582C12.2558,11.8001 11.0921,11.8082 9.9365,12.1826C8.7809,12.5569 7.8776,13.2243 7.2265,14.1845C6.5755,15.1448 6.25,16.1946 6.25,17.3339L6.25,17.3339L6.25,19.5312C6.25,20.1822 6.4778,20.7356 6.9336,21.1914C7.3893,21.6471 7.9427,21.8749 8.5937,21.8749L8.5937,21.8749L22.6562,21.8749ZM22.6562,19.5312L8.5937,19.5312L8.5937,17.3339C8.5937,16.455 8.903,15.6982 9.5215,15.0634C10.1399,14.4287 10.8886,14.095 11.7676,14.0625C13.0371,14.5833 14.3229,14.8437 15.625,14.8437C16.927,14.8437 18.2128,14.5833 19.4824,14.0625C20.3613,14.095 21.11,14.4287 21.7285,15.0634C22.347,15.6982 22.6562,16.455 22.6562,17.3339L22.6562,17.3339L22.6562,19.5312Z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="nonZero"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="M15.625,10.9375C16.6015,10.9375 17.513,10.6933 18.3593,10.2051C19.2057,9.7168 19.873,9.0495 20.3613,8.2031C20.8496,7.3568 21.0937,6.4453 21.0937,5.4687C21.0937,4.4922 20.8496,3.5807 20.3613,2.7344C19.873,1.888 19.2057,1.2207 18.3593,0.7324C17.513,0.2441 16.6015,0 15.625,0C14.6484,0 13.7369,0.2441 12.8906,0.7324C12.0442,1.2207 11.3769,1.888 10.8886,2.7344C10.4004,3.5807 10.1562,4.4922 10.1562,5.4687C10.1562,6.4453 10.4004,7.3568 10.8886,8.2031C11.3769,9.0495 12.0442,9.7168 12.8906,10.2051C13.7369,10.6933 14.6484,10.9375 15.625,10.9375ZM26.5624,9.375C27.6367,9.375 28.5562,8.9925 29.3212,8.2275C30.0862,7.4625 30.4687,6.543 30.4687,5.4687C30.4687,4.3945 30.0862,3.4749 29.3212,2.71C28.5562,1.945 27.6367,1.5625 26.5624,1.5625C25.4882,1.5625 24.5686,1.945 23.8037,2.71C23.0387,3.4749 22.6562,4.3945 22.6562,5.4687C22.6562,6.543 23.0387,7.4625 23.8037,8.2275C24.5686,8.9925 25.4882,9.375 26.5624,9.375ZM4.6875,9.375C5.7617,9.375 6.6813,8.9925 7.4463,8.2275C8.2112,7.4625 8.5937,6.543 8.5937,5.4687C8.5937,4.3945 8.2112,3.4749 7.4463,2.71C6.6813,1.945 5.7617,1.5625 4.6875,1.5625C3.6133,1.5625 2.6937,1.945 1.9287,2.71C1.1637,3.4749 0.7812,4.3945 0.7812,5.4687C0.7812,6.543 1.1637,7.4625 1.9287,8.2275C2.6937,8.9925 3.6133,9.375 4.6875,9.375ZM15.625,8.5937C14.7786,8.5937 14.0462,8.2845 13.4277,7.666C12.8092,7.0475 12.5,6.3151 12.5,5.4687C12.5,4.6224 12.8092,3.89 13.4277,3.2715C14.0462,2.653 14.7786,2.3437 15.625,2.3437C16.4713,2.3437 17.2037,2.653 17.8222,3.2715C18.4407,3.89 18.75,4.6224 18.75,5.4687C18.75,6.3151 18.4407,7.0475 17.8222,7.666C17.2037,8.2845 16.4713,8.5937 15.625,8.5937ZM26.5624,7.0312C26.1393,7.0312 25.7731,6.8766 25.4638,6.5674C25.1546,6.2581 24.9999,5.8919 24.9999,5.4687C24.9999,5.0456 25.1546,4.6794 25.4638,4.3701C25.7731,4.0609 26.1393,3.9062 26.5624,3.9062C26.9856,3.9062 27.3518,4.0609 27.6611,4.3701C27.9703,4.6794 28.1249,5.0456 28.1249,5.4687C28.1249,5.8919 27.9703,6.2581 27.6611,6.5674C27.3518,6.8766 26.9856,7.0312 26.5624,7.0312ZM4.6875,7.0312C4.2643,7.0312 3.8981,6.8766 3.5889,6.5674C3.2796,6.2581 3.125,5.8919 3.125,5.4687C3.125,5.0456 3.2796,4.6794 3.5889,4.3701C3.8981,4.0609 4.2643,3.9062 4.6875,3.9062C5.1107,3.9062 5.4769,4.0609 5.7861,4.3701C6.0954,4.6794 6.25,5.0456 6.25,5.4687C6.25,5.8919 6.0954,6.2581 5.7861,6.5674C5.4769,6.8766 5.1107,7.0312 4.6875,7.0312ZM30.0781,16.2109C30.4036,16.2109 30.6803,16.097 30.9081,15.8691C31.136,15.6412 31.2499,15.3645 31.2499,15.039C31.2499,13.8997 30.8512,12.9313 30.0536,12.1338C29.2561,11.3362 28.2877,10.9375 27.1484,10.9375L27.1484,10.9375L25.9765,10.9375C25.1301,10.9375 24.3652,11.1653 23.6816,11.6211C24.3652,12.1419 24.9348,12.7278 25.3906,13.3789C25.6184,13.3138 25.8137,13.2812 25.9765,13.2812L25.9765,13.2812L27.1484,13.2812C27.6367,13.2812 28.0517,13.4521 28.3935,13.7939C28.7353,14.1357 28.9062,14.5507 28.9062,15.039C28.9062,15.3645 29.0201,15.6412 29.248,15.8691C29.4758,16.097 29.7525,16.2109 30.0781,16.2109ZM1.1719,16.2109C1.4974,16.2109 1.7741,16.097 2.0019,15.8691C2.2298,15.6412 2.3437,15.3645 2.3437,15.039C2.3437,14.5507 2.5146,14.1357 2.8564,13.7939C3.1982,13.4521 3.6133,13.2812 4.1016,13.2812L4.1016,13.2812L5.2734,13.2812C5.4687,13.2812 5.664,13.33 5.8594,13.4277C6.3151,12.7441 6.8847,12.1419 7.5683,11.6211C6.8847,11.1653 6.1198,10.9375 5.2734,10.9375L5.2734,10.9375L4.1016,10.9375C2.9622,10.9375 1.9938,11.3362 1.1963,12.1338C0.3988,12.9313 0,13.8997 0,15.039C0,15.3645 0.1139,15.6412 0.3418,15.8691C0.5697,16.097 0.8464,16.2109 1.1719,16.2109ZM22.6562,21.8749C23.3072,21.8749 23.8606,21.6471 24.3163,21.1914C24.7721,20.7356 24.9999,20.1822 24.9999,19.5312L24.9999,19.5312L24.9999,17.3339C24.9999,16.1946 24.6744,15.153 24.0234,14.209C23.3723,13.2324 22.469,12.5569 21.3134,12.1826C20.1578,11.8082 18.9941,11.8001 17.8222,12.1582C17.0735,12.386 16.333,12.5 15.6005,12.5C14.8681,12.5 14.1438,12.386 13.4277,12.1582C12.2558,11.8001 11.0921,11.8082 9.9365,12.1826C8.7809,12.5569 7.8776,13.2243 7.2265,14.1845C6.5755,15.1448 6.25,16.1946 6.25,17.3339L6.25,17.3339L6.25,19.5312C6.25,20.1822 6.4778,20.7356 6.9336,21.1914C7.3893,21.6471 7.9427,21.8749 8.5937,21.8749L8.5937,21.8749L22.6562,21.8749ZM22.6562,19.5312L8.5937,19.5312L8.5937,17.3339C8.5937,16.455 8.903,15.6982 9.5215,15.0634C10.1399,14.4287 10.8886,14.095 11.7676,14.0625C13.0371,14.5833 14.3229,14.8437 15.625,14.8437C16.927,14.8437 18.2128,14.5833 19.4824,14.0625C20.3613,14.095 21.11,14.4287 21.7285,15.0634C22.347,15.6982 22.6562,16.455 22.6562,17.3339L22.6562,17.3339L22.6562,19.5312Z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="nonZero"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
12
res/drawable/ic_message.xml
Normal file
12
res/drawable/ic_message.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="20">
|
||||
<path
|
||||
android:pathData="M4.2929,14.2929C4.4804,14.1054 4.7348,14 5,14L17,14C17.5523,14 18,13.5523 18,13L18,3C18,2.4477 17.5523,2 17,2L3,2C2.4477,2 2,2.4477 2,3L2,16.5858L4.2929,14.2929ZM5.4142,16L1.7071,19.7071C1.0771,20.3371 0,19.8909 0,19L0,3C0,1.3431 1.3431,0 3,0L17,0C18.6569,0 20,1.3431 20,3L20,13C20,14.6569 18.6569,16 17,16L5.4142,16Z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="nonZero"
|
||||
android:strokeColor="#ffffff"/>
|
||||
</vector>
|
18
res/drawable/ic_plus.xml
Normal file
18
res/drawable/ic_plus.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="23dp"
|
||||
android:height="23dp"
|
||||
android:viewportWidth="23"
|
||||
android:viewportHeight="23">
|
||||
<path
|
||||
android:pathData="M11.4167,0.1111L11.4167,0.1111A1.5278,1.5278 0,0 1,12.9444 1.6389L12.9444,20.5833A1.5278,1.5278 0,0 1,11.4167 22.1111L11.4167,22.1111A1.5278,1.5278 0,0 1,9.8889 20.5833L9.8889,1.6389A1.5278,1.5278 0,0 1,11.4167 0.1111z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="M22.4167,11.1111C22.4167,11.9549 21.7327,12.6389 20.8889,12.6389L1.9444,12.6389C1.1007,12.6389 0.4167,11.9549 0.4167,11.1111C0.4167,10.2673 1.1007,9.5833 1.9444,9.5833L20.8889,9.5833C21.7327,9.5833 22.4167,10.2673 22.4167,11.1111Z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<gradient android:type="radial" android:gradientRadius="36dp" android:startColor="@color/accent" android:endColor="@android:color/transparent" />
|
||||
</shape>
|
||||
android:shape="oval" />
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<solid android:color="@color/accent" />
|
||||
</shape>
|
@ -40,28 +40,6 @@
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="64dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/createClosedGroupButton"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/ic_group_white_24dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/joinPublicChatButton"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginLeft="@dimen/medium_spacing"
|
||||
android:src="@drawable/ic_globe" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
||||
@ -80,36 +58,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<!-- The button below intentionally uses dp for the text size and not sp -->
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
<org.thoughtcrime.securesms.loki.redesign.views.NewConversationButtonSetView
|
||||
android:id="@+id/newConversationButtonSet"
|
||||
android:layout_width="252dp"
|
||||
android:layout_height="156dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="@dimen/new_conversation_button_bottom_offset">
|
||||
|
||||
<View
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:background="@drawable/new_conversation_button_background" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/newConversationButton"
|
||||
android:layout_width="@dimen/new_conversation_button_size"
|
||||
android:layout_height="@dimen/new_conversation_button_size"
|
||||
android:layout_centerInParent="true"
|
||||
android:paddingLeft="1dp"
|
||||
android:paddingBottom="2dp"
|
||||
android:background="@drawable/new_conversation_button_foreground"
|
||||
android:fontFamily="@font/roboto_light"
|
||||
android:textSize="40dp"
|
||||
android:textColor="#121212"
|
||||
android:text="+"
|
||||
android:elevation="0dp"
|
||||
android:stateListAnimator="@null" />
|
||||
|
||||
</RelativeLayout>
|
||||
android:layout_marginBottom="@dimen/new_conversation_button_bottom_offset" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
<color name="received_message_background">#222325</color>
|
||||
<color name="sent_message_background">#3F4146</color>
|
||||
<color name="quote_not_found_background">#99FFFFFF</color>
|
||||
<color name="new_conversation_button_collapsed_background">#1F1F1F</color>
|
||||
<!-- Session -->
|
||||
|
||||
<!-- Loki -->
|
||||
|
@ -22,7 +22,8 @@
|
||||
<dimen name="conversation_view_status_indicator_size">14dp</dimen>
|
||||
<dimen name="border_thickness">1dp</dimen>
|
||||
<dimen name="profile_picture_border_thickness">1dp</dimen>
|
||||
<dimen name="new_conversation_button_size">56dp</dimen>
|
||||
<dimen name="new_conversation_button_collapsed_size">60dp</dimen>
|
||||
<dimen name="new_conversation_button_expanded_size">72dp</dimen>
|
||||
<dimen name="tab_bar_height">36dp</dimen>
|
||||
<dimen name="text_view_corner_radius">8dp</dimen>
|
||||
<dimen name="fake_chat_view_bubble_width">224dp</dimen>
|
||||
|
@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.loki.getColorWithID
|
||||
import org.thoughtcrime.securesms.loki.redesign.utilities.push
|
||||
import org.thoughtcrime.securesms.loki.redesign.utilities.show
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.ConversationView
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.NewConversationButtonSetViewDelegate
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.SeedReminderViewDelegate
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
@ -41,7 +42,7 @@ import org.thoughtcrime.securesms.util.GroupUtil
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import kotlin.math.abs
|
||||
|
||||
class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListener, SeedReminderViewDelegate {
|
||||
class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListener, SeedReminderViewDelegate, NewConversationButtonSetViewDelegate {
|
||||
private lateinit var glide: GlideRequests
|
||||
|
||||
private val hexEncodedPublicKey: String
|
||||
@ -87,8 +88,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
profileButton.hexEncodedPublicKey = hexEncodedPublicKey
|
||||
profileButton.update()
|
||||
profileButton.setOnClickListener { openSettings() }
|
||||
createClosedGroupButton.setOnClickListener { createClosedGroup() }
|
||||
joinPublicChatButton.setOnClickListener { joinPublicChat() }
|
||||
// Set up seed reminder view
|
||||
val isMasterDevice = (TextSecurePreferences.getMasterHexEncodedPublicKey(this) == null)
|
||||
val hasViewedSeed = TextSecurePreferences.getHasViewedSeed(this)
|
||||
@ -125,8 +124,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
homeAdapter.changeCursor(null)
|
||||
}
|
||||
})
|
||||
// Set up new conversation button
|
||||
newConversationButton.setOnClickListener { createPrivateChat() }
|
||||
newConversationButtonSet.delegate = this
|
||||
// Set up typing observer
|
||||
ApplicationContext.getInstance(this).typingStatusRepository.typingThreads.observe(this, Observer<Set<Long>> { threadIDs ->
|
||||
val adapter = recyclerView.adapter as HomeAdapter
|
||||
@ -180,7 +178,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == CreateClosedGroupActivity.createNewPrivateChatResultCode) {
|
||||
createPrivateChat()
|
||||
createNewPrivateChat()
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
@ -215,17 +213,17 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
show(intent)
|
||||
}
|
||||
|
||||
private fun createPrivateChat() {
|
||||
override fun createNewPrivateChat() {
|
||||
val intent = Intent(this, CreatePrivateChatActivity::class.java)
|
||||
show(intent)
|
||||
}
|
||||
|
||||
private fun createClosedGroup() {
|
||||
override fun createNewClosedGroup() {
|
||||
val intent = Intent(this, CreateClosedGroupActivity::class.java)
|
||||
show(intent, true)
|
||||
}
|
||||
|
||||
private fun joinPublicChat() {
|
||||
override fun joinOpenGroup() {
|
||||
val intent = Intent(this, JoinPublicChatActivity::class.java)
|
||||
show(intent)
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package org.thoughtcrime.securesms.loki.redesign.utilities
|
||||
|
||||
import android.graphics.PointF
|
||||
import android.view.View
|
||||
|
||||
fun PointF.distanceTo(other: PointF): Float {
|
||||
return Math.sqrt(Math.pow(this.x.toDouble() - other.x.toDouble(), 2.toDouble()) + Math.pow(this.y.toDouble() - other.y.toDouble(), 2.toDouble())).toFloat()
|
||||
}
|
||||
|
||||
fun PointF.isLeftOf(view: View, margin: Float = 0.0f): Boolean {
|
||||
return isContainedVerticallyIn(view, margin) && x < view.hitRect.left
|
||||
}
|
||||
|
||||
fun PointF.isAbove(view: View, margin: Float = 0.0f): Boolean {
|
||||
return isContainedHorizontallyIn(view, margin) && y < view.hitRect.top
|
||||
}
|
||||
|
||||
fun PointF.isRightOf(view: View, margin: Float = 0.0f): Boolean {
|
||||
return isContainedVerticallyIn(view, margin) && x > view.hitRect.right
|
||||
}
|
||||
|
||||
fun PointF.isBelow(view: View, margin: Float = 0.0f): Boolean {
|
||||
return isContainedHorizontallyIn(view, margin) && y > view.hitRect.bottom
|
||||
}
|
||||
|
||||
fun PointF.isContainedHorizontallyIn(view: View, margin: Float = 0.0f): Boolean {
|
||||
return x >= view.hitRect.left - margin || x <= view.hitRect.right + margin
|
||||
}
|
||||
|
||||
fun PointF.isContainedVerticallyIn(view: View, margin: Float = 0.0f): Boolean {
|
||||
return y >= view.hitRect.top - margin || x <= view.hitRect.bottom + margin
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package org.thoughtcrime.securesms.loki.redesign.utilities
|
||||
|
||||
import android.view.ViewGroup
|
||||
|
||||
fun ViewGroup.disableClipping() {
|
||||
clipToPadding = false
|
||||
clipChildren = false
|
||||
clipToOutline = false
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.thoughtcrime.securesms.loki.redesign.utilities
|
||||
|
||||
import android.graphics.PointF
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
|
||||
fun View.contains(point: PointF): Boolean {
|
||||
return hitRect.contains(point.x.toInt(), point.y.toInt())
|
||||
}
|
||||
|
||||
val View.hitRect: Rect
|
||||
get() {
|
||||
val rect = Rect()
|
||||
getHitRect(rect)
|
||||
return rect
|
||||
}
|
@ -0,0 +1,272 @@
|
||||
package org.thoughtcrime.securesms.loki.redesign.views
|
||||
|
||||
import android.animation.ArgbEvaluator
|
||||
import android.animation.FloatEvaluator
|
||||
import android.animation.PointFEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.content.Context.VIBRATOR_SERVICE
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.PointF
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Build
|
||||
import android.os.VibrationEffect
|
||||
import android.os.VibrationEffect.DEFAULT_AMPLITUDE
|
||||
import android.os.Vibrator
|
||||
import android.support.annotation.ColorRes
|
||||
import android.support.annotation.DimenRes
|
||||
import android.support.annotation.DrawableRes
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.widget.ImageView
|
||||
import android.widget.RelativeLayout
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.loki.getColorWithID
|
||||
import org.thoughtcrime.securesms.loki.redesign.utilities.*
|
||||
import org.thoughtcrime.securesms.loki.toPx
|
||||
|
||||
class NewConversationButtonSetView : RelativeLayout {
|
||||
private var expandedButton: Button? = null
|
||||
var delegate: NewConversationButtonSetViewDelegate? = null
|
||||
|
||||
// region Convenience
|
||||
private val sessionButtonExpandedPosition: PointF get() { return PointF(width.toFloat() / 2 - sessionButton.expandedSize / 2, 0.0f) }
|
||||
private val closedGroupButtonExpandedPosition: PointF get() { return PointF(width.toFloat() - closedGroupButton.expandedSize, height.toFloat() - closedGroupButton.expandedSize) }
|
||||
private val openGroupButtonExpandedPosition: PointF get() { return PointF(0.0f, height.toFloat() - openGroupButton.expandedSize) }
|
||||
private val buttonRestPosition: PointF get() { return PointF(width.toFloat() / 2 - mainButton.expandedSize / 2, height.toFloat() - mainButton.expandedSize) }
|
||||
// endregion
|
||||
|
||||
// region Settings
|
||||
private val maxDragDistance by lazy { toPx(56, resources).toFloat() }
|
||||
private val dragMargin by lazy { toPx(16, resources).toFloat() }
|
||||
// endregion
|
||||
|
||||
// region Components
|
||||
private val mainButton by lazy { Button(context, true, R.drawable.ic_plus) }
|
||||
private val sessionButton by lazy { Button(context, false, R.drawable.ic_message) }
|
||||
private val closedGroupButton by lazy { Button(context, false, R.drawable.ic_group) }
|
||||
private val openGroupButton by lazy { Button(context, false, R.drawable.ic_globe) }
|
||||
// endregion
|
||||
|
||||
// region Button
|
||||
class Button : RelativeLayout {
|
||||
@DrawableRes private var iconID = 0
|
||||
private var isMain = false
|
||||
|
||||
companion object {
|
||||
val animationDuration = 250.toLong()
|
||||
}
|
||||
|
||||
val expandedSize by lazy { resources.getDimension(R.dimen.new_conversation_button_expanded_size) }
|
||||
val collapsedSize by lazy { resources.getDimension(R.dimen.new_conversation_button_collapsed_size) }
|
||||
private val expandedImageViewPosition by lazy { PointF(0.0f, 0.0f) }
|
||||
private val collapsedImageViewPosition by lazy { PointF((expandedSize - collapsedSize) / 2, (expandedSize - collapsedSize) / 2) }
|
||||
|
||||
private val imageView by lazy {
|
||||
val result = ImageView(context)
|
||||
val size = collapsedSize.toInt()
|
||||
result.layoutParams = LayoutParams(size, size)
|
||||
result.setBackgroundResource(R.drawable.new_conversation_button_background)
|
||||
val background = result.background as GradientDrawable
|
||||
val colorID = if (isMain) R.color.accent else R.color.new_conversation_button_collapsed_background
|
||||
background.color = ColorStateList.valueOf(resources.getColorWithID(colorID, context.theme))
|
||||
result.scaleType = ImageView.ScaleType.CENTER
|
||||
result.setImageResource(iconID)
|
||||
result
|
||||
}
|
||||
|
||||
constructor(context: Context) : super(context) { throw IllegalAccessException("Use Button(context:iconID:) instead.") }
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { throw IllegalAccessException("Use Button(context:iconID:) instead.") }
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { throw IllegalAccessException("Use Button(context:iconID:) instead.") }
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) { throw IllegalAccessException("Use Button(context:iconID:) instead.") }
|
||||
|
||||
constructor(context: Context, isMain: Boolean, @DrawableRes iconID: Int) : super(context) {
|
||||
this.iconID = iconID
|
||||
this.isMain = isMain
|
||||
disableClipping()
|
||||
val size = resources.getDimension(R.dimen.new_conversation_button_expanded_size).toInt()
|
||||
val layoutParams = LayoutParams(size, size)
|
||||
this.layoutParams = layoutParams
|
||||
addView(imageView)
|
||||
imageView.x = collapsedImageViewPosition.x
|
||||
imageView.y = collapsedImageViewPosition.y
|
||||
}
|
||||
|
||||
fun expand() {
|
||||
animateImageViewColorChange(R.color.new_conversation_button_collapsed_background, R.color.accent)
|
||||
animateImageViewSizeChange(R.dimen.new_conversation_button_collapsed_size, R.dimen.new_conversation_button_expanded_size)
|
||||
animateImageViewPositionChange(collapsedImageViewPosition, expandedImageViewPosition)
|
||||
}
|
||||
|
||||
fun collapse() {
|
||||
animateImageViewColorChange(R.color.accent, R.color.new_conversation_button_collapsed_background)
|
||||
animateImageViewSizeChange(R.dimen.new_conversation_button_expanded_size, R.dimen.new_conversation_button_collapsed_size)
|
||||
animateImageViewPositionChange(expandedImageViewPosition, collapsedImageViewPosition)
|
||||
}
|
||||
|
||||
private fun animateImageViewColorChange(@ColorRes startColorID: Int, @ColorRes endColorID: Int) {
|
||||
val drawable = imageView.background as GradientDrawable
|
||||
val startColor = resources.getColorWithID(startColorID, context.theme)
|
||||
val endColor = resources.getColorWithID(endColorID, context.theme)
|
||||
val animation = ValueAnimator.ofObject(ArgbEvaluator(), startColor, endColor)
|
||||
animation.duration = animationDuration
|
||||
animation.addUpdateListener { animator ->
|
||||
val color = animator.animatedValue as Int
|
||||
drawable.color = ColorStateList.valueOf(color)
|
||||
}
|
||||
animation.start()
|
||||
}
|
||||
|
||||
private fun animateImageViewSizeChange(@DimenRes startSizeID: Int, @DimenRes endSizeID: Int) {
|
||||
val layoutParams = imageView.layoutParams
|
||||
val startSize = resources.getDimension(startSizeID)
|
||||
val endSize = resources.getDimension(endSizeID)
|
||||
val animation = ValueAnimator.ofObject(FloatEvaluator(), startSize, endSize)
|
||||
animation.duration = animationDuration
|
||||
animation.addUpdateListener { animator ->
|
||||
val size = animator.animatedValue as Float
|
||||
layoutParams.width = size.toInt()
|
||||
layoutParams.height = size.toInt()
|
||||
imageView.layoutParams = layoutParams
|
||||
}
|
||||
animation.start()
|
||||
}
|
||||
|
||||
private fun animateImageViewPositionChange(startPosition: PointF, endPosition: PointF) {
|
||||
val animation = ValueAnimator.ofObject(PointFEvaluator(), startPosition, endPosition)
|
||||
animation.duration = animationDuration
|
||||
animation.addUpdateListener { animator ->
|
||||
val point = animator.animatedValue as PointF
|
||||
imageView.x = point.x
|
||||
imageView.y = point.y
|
||||
}
|
||||
animation.start()
|
||||
}
|
||||
|
||||
fun animatePositionChange(startPosition: PointF, endPosition: PointF) {
|
||||
val animation = ValueAnimator.ofObject(PointFEvaluator(), startPosition, endPosition)
|
||||
animation.duration = animationDuration
|
||||
animation.addUpdateListener { animator ->
|
||||
val point = animator.animatedValue as PointF
|
||||
x = point.x
|
||||
y = point.y
|
||||
}
|
||||
animation.start()
|
||||
}
|
||||
|
||||
fun animateAlphaChange(startAlpha: Float, endAlpha: Float) {
|
||||
val animation = ValueAnimator.ofObject(FloatEvaluator(), startAlpha, endAlpha)
|
||||
animation.duration = animationDuration
|
||||
animation.addUpdateListener { animator ->
|
||||
alpha = animator.animatedValue as Float
|
||||
}
|
||||
animation.start()
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Lifecycle
|
||||
constructor(context: Context) : super(context) { setUpViewHierarchy() }
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { setUpViewHierarchy() }
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { setUpViewHierarchy() }
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) { setUpViewHierarchy() }
|
||||
|
||||
private fun setUpViewHierarchy() {
|
||||
disableClipping()
|
||||
// Set up session button
|
||||
addView(sessionButton)
|
||||
sessionButton.alpha = 0.0f
|
||||
val sessionButtonLayoutParams = sessionButton.layoutParams as LayoutParams
|
||||
sessionButtonLayoutParams.addRule(CENTER_IN_PARENT, TRUE)
|
||||
sessionButtonLayoutParams.addRule(ALIGN_PARENT_BOTTOM, TRUE)
|
||||
// Set up closed group button
|
||||
addView(closedGroupButton)
|
||||
closedGroupButton.alpha = 0.0f
|
||||
val closedGroupButtonLayoutParams = closedGroupButton.layoutParams as LayoutParams
|
||||
closedGroupButtonLayoutParams.addRule(CENTER_IN_PARENT, TRUE)
|
||||
closedGroupButtonLayoutParams.addRule(ALIGN_PARENT_BOTTOM, TRUE)
|
||||
// Set up open group button
|
||||
addView(openGroupButton)
|
||||
openGroupButton.alpha = 0.0f
|
||||
val openGroupButtonLayoutParams = openGroupButton.layoutParams as LayoutParams
|
||||
openGroupButtonLayoutParams.addRule(CENTER_IN_PARENT, TRUE)
|
||||
openGroupButtonLayoutParams.addRule(ALIGN_PARENT_BOTTOM, TRUE)
|
||||
// Set up main button
|
||||
addView(mainButton)
|
||||
val mainButtonLayoutParams = mainButton.layoutParams as LayoutParams
|
||||
mainButtonLayoutParams.addRule(CENTER_IN_PARENT, TRUE)
|
||||
mainButtonLayoutParams.addRule(ALIGN_PARENT_BOTTOM, TRUE)
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Interaction
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
val touchX = event.x
|
||||
val touchY = event.y
|
||||
val touch = PointF(touchX, touchY)
|
||||
val expandedButton = expandedButton
|
||||
val buttonsExcludingMainButton = listOf( sessionButton, closedGroupButton, openGroupButton )
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
val vibrator = context.getSystemService(VIBRATOR_SERVICE) as Vibrator
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
vibrator.vibrate(VibrationEffect.createOneShot(50, DEFAULT_AMPLITUDE))
|
||||
} else {
|
||||
vibrator.vibrate(50)
|
||||
}
|
||||
sessionButton.animatePositionChange(buttonRestPosition, sessionButtonExpandedPosition)
|
||||
closedGroupButton.animatePositionChange(buttonRestPosition, closedGroupButtonExpandedPosition)
|
||||
openGroupButton.animatePositionChange(buttonRestPosition, openGroupButtonExpandedPosition)
|
||||
buttonsExcludingMainButton.forEach { it.animateAlphaChange(0.0f, 1.0f) }
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
mainButton.x = touchX - mainButton.expandedSize / 2
|
||||
mainButton.y = touchY - mainButton.expandedSize / 2
|
||||
mainButton.alpha = 1 - (PointF(mainButton.x, mainButton.y).distanceTo(buttonRestPosition) / maxDragDistance)
|
||||
val buttonToExpand = buttonsExcludingMainButton.firstOrNull { button ->
|
||||
var hasUserDraggedBeyondButton = false
|
||||
if (button == openGroupButton && touch.isLeftOf(openGroupButton, dragMargin)) { hasUserDraggedBeyondButton = true }
|
||||
if (button == sessionButton && touch.isAbove(sessionButton, dragMargin)) { hasUserDraggedBeyondButton = true }
|
||||
if (button == closedGroupButton && touch.isRightOf(closedGroupButton, dragMargin)) { hasUserDraggedBeyondButton = true }
|
||||
button.contains(touch) || hasUserDraggedBeyondButton
|
||||
}
|
||||
if (buttonToExpand != null) {
|
||||
if (buttonToExpand == expandedButton) { return true }
|
||||
expandedButton?.collapse()
|
||||
buttonToExpand.expand()
|
||||
this.expandedButton = buttonToExpand
|
||||
} else {
|
||||
expandedButton?.collapse()
|
||||
this.expandedButton = null
|
||||
}
|
||||
}
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||
expandedButton?.collapse()
|
||||
this.expandedButton = null
|
||||
val allButtons = listOf( mainButton ) + buttonsExcludingMainButton
|
||||
allButtons.forEach {
|
||||
val currentPosition = PointF(it.x, it.y)
|
||||
it.animatePositionChange(currentPosition, buttonRestPosition)
|
||||
val endAlpha = if (it == mainButton) 1.0f else 0.0f
|
||||
it.animateAlphaChange(it.alpha, endAlpha)
|
||||
}
|
||||
if (event.action == MotionEvent.ACTION_UP) {
|
||||
if (openGroupButton.contains(touch) || touch.isLeftOf(openGroupButton, dragMargin)) { delegate?.joinOpenGroup() }
|
||||
else if (sessionButton.contains(touch) || touch.isAbove(sessionButton, dragMargin)) { delegate?.createNewPrivateChat() }
|
||||
else if (closedGroupButton.contains(touch) || touch.isRightOf(closedGroupButton, dragMargin)) { delegate?.createNewClosedGroup() }
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
||||
// region Delegate
|
||||
interface NewConversationButtonSetViewDelegate {
|
||||
|
||||
fun joinOpenGroup()
|
||||
fun createNewPrivateChat()
|
||||
fun createNewClosedGroup()
|
||||
}
|
||||
// endregion
|
Loading…
x
Reference in New Issue
Block a user