mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-25 02:55:23 +00:00
Implement profile picture editing
This commit is contained in:
parent
fd14d66d4f
commit
15b4c6aacc
@ -197,6 +197,7 @@ dependencies {
|
|||||||
}
|
}
|
||||||
implementation "com.jakewharton.rxbinding3:rxbinding:3.1.0"
|
implementation "com.jakewharton.rxbinding3:rxbinding:3.1.0"
|
||||||
implementation "com.github.tbruyelle:rxpermissions:0.10.2"
|
implementation "com.github.tbruyelle:rxpermissions:0.10.2"
|
||||||
|
implementation "com.github.ybq:Android-SpinKit:1.4.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
def canonicalVersionCode = 23
|
def canonicalVersionCode = 23
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
android:id="@+id/profileButton"
|
android:id="@+id/profileButton"
|
||||||
android:layout_width="@dimen/small_profile_picture_size"
|
android:layout_width="@dimen/small_profile_picture_size"
|
||||||
android:layout_height="@dimen/small_profile_picture_size"
|
android:layout_height="@dimen/small_profile_picture_size"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginLeft="10dp"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_centerVertical="true" />
|
android:layout_centerVertical="true" />
|
||||||
|
|
||||||
|
@ -1,258 +1,283 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView
|
<RelativeLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:scrollbars="none">
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/default_session_background">
|
||||||
|
|
||||||
<LinearLayout
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/default_session_background"
|
android:scrollbars="none">
|
||||||
android:orientation="vertical"
|
|
||||||
android:gravity="center_horizontal">
|
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:minHeight="?attr/actionBarSize"
|
|
||||||
app:contentInsetLeft="20dp"
|
|
||||||
app:contentInsetRight="20dp"
|
|
||||||
android:theme="?attr/actionBarStyle">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/cancelButton"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:src="@drawable/ic_close_white_24dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/titleTextView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Settings"
|
|
||||||
android:textColor="@color/text"
|
|
||||||
android:textSize="@dimen/very_large_font_size"
|
|
||||||
android:fontFamily="sans-serif-medium" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/saveButton"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:src="@drawable/ic_check_white_24dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/showQRCodeButton"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:src="@drawable/ic_qr_code" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</android.support.v7.widget.Toolbar>
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.loki.redesign.views.ProfilePictureView
|
|
||||||
android:id="@+id/profilePictureView"
|
|
||||||
android:layout_width="@dimen/large_profile_picture_size"
|
|
||||||
android:layout_height="@dimen/large_profile_picture_size"
|
|
||||||
android:layout_marginTop="@dimen/medium_spacing" />
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/displayNameContainer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="@dimen/large_spacing"
|
|
||||||
android:layout_marginTop="@dimen/small_spacing"
|
|
||||||
android:layout_marginRight="@dimen/large_spacing">
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
style="@style/SessionEditText"
|
|
||||||
android:id="@+id/displayNameEditText"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:paddingTop="12dp"
|
|
||||||
android:paddingBottom="12dp"
|
|
||||||
android:visibility="invisible"
|
|
||||||
android:hint="Enter a display name" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/displayNameTextView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:textColor="@color/text"
|
|
||||||
android:textSize="@dimen/very_large_font_size"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.loki.redesign.views.SeparatorView
|
|
||||||
android:id="@+id/separatorView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="32dp"
|
|
||||||
android:layout_marginLeft="@dimen/large_spacing"
|
|
||||||
android:layout_marginTop="20dp"
|
|
||||||
android:layout_marginRight="@dimen/large_spacing"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/publicKeyTextView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="@dimen/large_spacing"
|
|
||||||
android:layout_marginTop="@dimen/large_spacing"
|
|
||||||
android:layout_marginRight="@dimen/large_spacing"
|
|
||||||
android:textSize="@dimen/large_font_size"
|
|
||||||
android:textColor="@color/text"
|
|
||||||
android:fontFamily="@font/space_mono_regular"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:text="05987d601943c267879be41830888066c6a024cbdc9a548d06813924bf3372ea78" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/large_spacing"
|
android:orientation="vertical"
|
||||||
android:layout_marginTop="@dimen/large_spacing"
|
android:gravity="center_horizontal">
|
||||||
android:layout_marginRight="@dimen/large_spacing"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<Button
|
<android.support.v7.widget.Toolbar
|
||||||
style="@style/MediumProminentOutlineButton"
|
android:id="@+id/toolbar"
|
||||||
android:id="@+id/copyButton"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="0dp"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:layout_height="@dimen/medium_button_height"
|
android:minHeight="?attr/actionBarSize"
|
||||||
android:layout_weight="1"
|
app:contentInsetLeft="20dp"
|
||||||
android:text="Copy" />
|
app:contentInsetRight="20dp"
|
||||||
|
android:theme="?attr/actionBarStyle">
|
||||||
|
|
||||||
<Button
|
<LinearLayout
|
||||||
style="@style/MediumUnimportantOutlineButton"
|
android:layout_width="match_parent"
|
||||||
android:id="@+id/shareButton"
|
android:layout_height="match_parent"
|
||||||
android:layout_width="0dp"
|
android:gravity="center_vertical"
|
||||||
android:layout_height="@dimen/medium_button_height"
|
android:orientation="horizontal">
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginLeft="@dimen/medium_spacing"
|
<ImageView
|
||||||
android:text="Share" />
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/ic_close_white_24dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Settings"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/very_large_font_size"
|
||||||
|
android:fontFamily="sans-serif-medium" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/saveButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/ic_check_white_24dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/showQRCodeButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/ic_qr_code" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</android.support.v7.widget.Toolbar>
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.loki.redesign.views.ProfilePictureView
|
||||||
|
android:id="@+id/profilePictureView"
|
||||||
|
android:layout_width="@dimen/large_profile_picture_size"
|
||||||
|
android:layout_height="@dimen/large_profile_picture_size"
|
||||||
|
android:layout_marginTop="@dimen/medium_spacing" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/displayNameContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/large_spacing"
|
||||||
|
android:layout_marginTop="@dimen/small_spacing"
|
||||||
|
android:layout_marginRight="@dimen/large_spacing">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
style="@style/SessionEditText"
|
||||||
|
android:id="@+id/displayNameEditText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingBottom="12dp"
|
||||||
|
android:visibility="invisible"
|
||||||
|
android:hint="Enter a display name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/displayNameTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/very_large_font_size"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.loki.redesign.views.SeparatorView
|
||||||
|
android:id="@+id/separatorView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:layout_marginLeft="@dimen/large_spacing"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginRight="@dimen/large_spacing"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/publicKeyTextView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/large_spacing"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:layout_marginRight="@dimen/large_spacing"
|
||||||
|
android:textSize="@dimen/large_font_size"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:fontFamily="@font/space_mono_regular"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:text="05987d601943c267879be41830888066c6a024cbdc9a548d06813924bf3372ea78" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/large_spacing"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:layout_marginRight="@dimen/large_spacing"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/MediumProminentOutlineButton"
|
||||||
|
android:id="@+id/copyButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/medium_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Copy" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/MediumUnimportantOutlineButton"
|
||||||
|
android:id="@+id/shareButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/medium_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginLeft="@dimen/medium_spacing"
|
||||||
|
android:text="Share" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:background="@color/separator" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/privacyButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/setting_button_height"
|
||||||
|
android:background="@drawable/setting_button_background"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Privacy" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:background="@color/separator" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/notificationsButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/setting_button_height"
|
||||||
|
android:background="@drawable/setting_button_background"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Notifications" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:background="@color/separator" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/chatsButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/setting_button_height"
|
||||||
|
android:background="@drawable/setting_button_background"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Chats" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:background="@color/separator" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/linkedDevicesButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/setting_button_height"
|
||||||
|
android:background="@drawable/setting_button_background"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Linked Devices" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:background="@color/separator" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/seedButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/setting_button_height"
|
||||||
|
android:background="@drawable/setting_button_background"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Show Seed" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:background="@color/separator" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/clearAllDataButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/setting_button_height"
|
||||||
|
android:background="@drawable/setting_button_background"
|
||||||
|
android:textColor="@color/destructive"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Clear All Data" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:layout_marginBottom="@dimen/large_spacing"
|
||||||
|
android:background="@color/separator" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
</ScrollView>
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1px"
|
|
||||||
android:layout_marginTop="@dimen/large_spacing"
|
|
||||||
android:background="@color/separator" />
|
|
||||||
|
|
||||||
<TextView
|
<RelativeLayout
|
||||||
android:id="@+id/privacyButton"
|
android:id="@+id/loader"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/setting_button_height"
|
android:layout_height="match_parent"
|
||||||
android:background="@drawable/setting_button_background"
|
android:background="#A4000000"
|
||||||
android:textColor="@color/text"
|
android:visibility="gone"
|
||||||
android:textSize="@dimen/medium_font_size"
|
android:alpha="0">
|
||||||
android:textStyle="bold"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="Privacy" />
|
|
||||||
|
|
||||||
<View
|
<com.github.ybq.android.spinkit.SpinKitView
|
||||||
android:layout_width="match_parent"
|
style="@style/SpinKitView.Large.ThreeBounce"
|
||||||
android:layout_height="1px"
|
android:layout_width="wrap_content"
|
||||||
android:background="@color/separator" />
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
app:SpinKit_Color="@color/text" />
|
||||||
|
|
||||||
<TextView
|
</RelativeLayout>
|
||||||
android:id="@+id/notificationsButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"
|
|
||||||
android:background="@drawable/setting_button_background"
|
|
||||||
android:textColor="@color/text"
|
|
||||||
android:textSize="@dimen/medium_font_size"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="Notifications" />
|
|
||||||
|
|
||||||
<View
|
</RelativeLayout>
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1px"
|
|
||||||
android:background="@color/separator" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/chatsButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"
|
|
||||||
android:background="@drawable/setting_button_background"
|
|
||||||
android:textColor="@color/text"
|
|
||||||
android:textSize="@dimen/medium_font_size"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="Chats" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1px"
|
|
||||||
android:background="@color/separator" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/linkedDevicesButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"
|
|
||||||
android:background="@drawable/setting_button_background"
|
|
||||||
android:textColor="@color/text"
|
|
||||||
android:textSize="@dimen/medium_font_size"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="Linked Devices" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1px"
|
|
||||||
android:background="@color/separator" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/seedButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"
|
|
||||||
android:background="@drawable/setting_button_background"
|
|
||||||
android:textColor="@color/text"
|
|
||||||
android:textSize="@dimen/medium_font_size"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="Show Seed" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1px"
|
|
||||||
android:background="@color/separator" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/clearAllDataButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"
|
|
||||||
android:background="@drawable/setting_button_background"
|
|
||||||
android:textColor="@color/destructive"
|
|
||||||
android:textSize="@dimen/medium_font_size"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="Clear All Data" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1px"
|
|
||||||
android:layout_marginBottom="@dimen/large_spacing"
|
|
||||||
android:background="@color/separator" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</ScrollView>
|
|
@ -8,7 +8,6 @@ import android.support.annotation.Nullable;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||||
import org.thoughtcrime.securesms.util.Conversions;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -17,7 +16,7 @@ import java.security.MessageDigest;
|
|||||||
public class ProfileContactPhoto implements ContactPhoto {
|
public class ProfileContactPhoto implements ContactPhoto {
|
||||||
|
|
||||||
private final @NonNull Address address;
|
private final @NonNull Address address;
|
||||||
private final @NonNull String avatarObject;
|
public final @NonNull String avatarObject;
|
||||||
|
|
||||||
public ProfileContactPhoto(@NonNull Address address, @NonNull String avatarObject) {
|
public ProfileContactPhoto(@NonNull Address address, @NonNull String avatarObject) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
|
@ -91,14 +91,14 @@ class RegisterActivity : BaseActionBarActivity() {
|
|||||||
val hexEncodedPublicKey = keyPair!!.hexEncodedPublicKey
|
val hexEncodedPublicKey = keyPair!!.hexEncodedPublicKey
|
||||||
val characterCount = hexEncodedPublicKey.count()
|
val characterCount = hexEncodedPublicKey.count()
|
||||||
var count = 0
|
var count = 0
|
||||||
val limit = 40
|
val limit = 32
|
||||||
fun animate() {
|
fun animate() {
|
||||||
val numberOfIndexesToShuffle = (0 until (40 - count)).random()
|
val numberOfIndexesToShuffle = 32 - count
|
||||||
val indexesToShuffle = (0 until characterCount).shuffled().subList(0, numberOfIndexesToShuffle)
|
val indexesToShuffle = (0 until characterCount).shuffled().subList(0, numberOfIndexesToShuffle)
|
||||||
var mangledHexEncodedPublicKey = hexEncodedPublicKey
|
var mangledHexEncodedPublicKey = hexEncodedPublicKey
|
||||||
for (index in indexesToShuffle) {
|
for (index in indexesToShuffle) {
|
||||||
try {
|
try {
|
||||||
mangledHexEncodedPublicKey = mangledHexEncodedPublicKey.substring(0, index) + "0123456789abcdef________________".random() + mangledHexEncodedPublicKey.substring(index + 1, mangledHexEncodedPublicKey.count())
|
mangledHexEncodedPublicKey = mangledHexEncodedPublicKey.substring(0, index) + "0123456789abcdef__".random() + mangledHexEncodedPublicKey.substring(index + 1, mangledHexEncodedPublicKey.count())
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ class RegisterActivity : BaseActionBarActivity() {
|
|||||||
publicKeyTextView.text = mangledHexEncodedPublicKey
|
publicKeyTextView.text = mangledHexEncodedPublicKey
|
||||||
Handler().postDelayed({
|
Handler().postDelayed({
|
||||||
animate()
|
animate()
|
||||||
}, 40)
|
}, 32)
|
||||||
} else {
|
} else {
|
||||||
publicKeyTextView.text = hexEncodedPublicKey
|
publicKeyTextView.text = hexEncodedPublicKey
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,56 @@
|
|||||||
package org.thoughtcrime.securesms.loki.redesign.activities
|
package org.thoughtcrime.securesms.loki.redesign.activities
|
||||||
|
|
||||||
|
import android.animation.Animator
|
||||||
|
import android.animation.AnimatorListenerAdapter
|
||||||
|
import android.app.Activity
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.AsyncTask
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import kotlinx.android.synthetic.main.activity_settings.*
|
import kotlinx.android.synthetic.main.activity_settings.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
|
import nl.komponents.kovenant.Promise
|
||||||
|
import nl.komponents.kovenant.all
|
||||||
|
import nl.komponents.kovenant.deferred
|
||||||
|
import nl.komponents.kovenant.ui.alwaysUi
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||||
|
import org.thoughtcrime.securesms.avatar.AvatarSelection
|
||||||
|
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
|
||||||
|
import org.thoughtcrime.securesms.database.Address
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
import org.thoughtcrime.securesms.loki.redesign.utilities.push
|
import org.thoughtcrime.securesms.loki.redesign.utilities.push
|
||||||
import org.thoughtcrime.securesms.loki.toPx
|
import org.thoughtcrime.securesms.loki.toPx
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp
|
import org.thoughtcrime.securesms.mms.GlideApp
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||||
|
import org.thoughtcrime.securesms.profiles.AvatarHelper
|
||||||
|
import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints
|
||||||
|
import org.thoughtcrime.securesms.util.BitmapDecodingException
|
||||||
|
import org.thoughtcrime.securesms.util.BitmapUtil
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
import org.whispersystems.signalservice.api.crypto.ProfileCipher
|
||||||
|
import org.whispersystems.signalservice.api.util.StreamDetails
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.security.SecureRandom
|
||||||
|
|
||||||
class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||||
private lateinit var glide: GlideRequests
|
private lateinit var glide: GlideRequests
|
||||||
private var isEditingDisplayName = false
|
private var isEditingDisplayName = false
|
||||||
set(value) { field = value; handleIsEditingDisplayNameChanged() }
|
set(value) { field = value; handleIsEditingDisplayNameChanged() }
|
||||||
private var displayNameToBeUploaded: String? = null
|
private var displayNameToBeUploaded: String? = null
|
||||||
|
private var profilePictureToBeUploaded: ByteArray? = null
|
||||||
|
private var tempFile: File? = null
|
||||||
|
|
||||||
private val hexEncodedPublicKey: String
|
private val hexEncodedPublicKey: String
|
||||||
get() {
|
get() {
|
||||||
@ -50,6 +76,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
profilePictureView.hexEncodedPublicKey = hexEncodedPublicKey
|
profilePictureView.hexEncodedPublicKey = hexEncodedPublicKey
|
||||||
profilePictureView.isLarge = true
|
profilePictureView.isLarge = true
|
||||||
profilePictureView.update()
|
profilePictureView.update()
|
||||||
|
profilePictureView.setOnClickListener { showEditProfilePictureUI() }
|
||||||
// Set up display name container
|
// Set up display name container
|
||||||
displayNameContainer.setOnClickListener { showEditDisplayNameUI() }
|
displayNameContainer.setOnClickListener { showEditDisplayNameUI() }
|
||||||
// Set up display name text view
|
// Set up display name text view
|
||||||
@ -61,6 +88,34 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
// Set up share button
|
// Set up share button
|
||||||
shareButton.setOnClickListener { sharePublicKey() }
|
shareButton.setOnClickListener { sharePublicKey() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
when (requestCode) {
|
||||||
|
AvatarSelection.REQUEST_CODE_AVATAR -> {
|
||||||
|
if (resultCode != Activity.RESULT_OK) { return }
|
||||||
|
val outputFile = Uri.fromFile(File(cacheDir, "cropped"))
|
||||||
|
var inputFile: Uri? = data?.data
|
||||||
|
if (inputFile == null && tempFile != null) {
|
||||||
|
inputFile = Uri.fromFile(tempFile)
|
||||||
|
}
|
||||||
|
AvatarSelection.circularCropImage(this, inputFile, outputFile, R.string.CropImageActivity_profile_avatar)
|
||||||
|
}
|
||||||
|
AvatarSelection.REQUEST_CODE_CROP_IMAGE -> {
|
||||||
|
if (resultCode != Activity.RESULT_OK) { return }
|
||||||
|
AsyncTask.execute {
|
||||||
|
try {
|
||||||
|
profilePictureToBeUploaded = BitmapUtil.createScaledBytes(this@SettingsActivity, AvatarSelection.getResultUri(data), ProfileMediaConstraints()).bitmap
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
updateProfile(true)
|
||||||
|
}
|
||||||
|
} catch (e: BitmapDecodingException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Updating
|
// region Updating
|
||||||
@ -82,18 +137,62 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateProfile(isUpdatingDisplayName: Boolean, isUpdatingProfilePicture: Boolean) {
|
private fun updateProfile(isUpdatingProfilePicture: Boolean) {
|
||||||
val displayName = displayNameToBeUploaded ?: TextSecurePreferences.getProfileName(this)
|
showLoader()
|
||||||
TextSecurePreferences.setProfileName(this, displayName)
|
val promises = mutableListOf<Promise<*, Exception>>()
|
||||||
val publicChatAPI = ApplicationContext.getInstance(this).lokiPublicChatAPI
|
val displayName = displayNameToBeUploaded
|
||||||
if (publicChatAPI != null) {
|
if (displayName != null) {
|
||||||
val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers()
|
val publicChatAPI = ApplicationContext.getInstance(this).lokiPublicChatAPI
|
||||||
for (server in servers) {
|
if (publicChatAPI != null) {
|
||||||
publicChatAPI.setDisplayName(displayName, server)
|
val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers()
|
||||||
|
promises.addAll(servers.map { publicChatAPI.setDisplayName(displayName, it) })
|
||||||
}
|
}
|
||||||
|
TextSecurePreferences.setProfileName(this, displayName)
|
||||||
}
|
}
|
||||||
displayNameTextView.text = displayName
|
val profilePicture = profilePictureToBeUploaded
|
||||||
displayNameToBeUploaded = null
|
val encodedProfileKey = ProfileKeyUtil.generateEncodedProfileKey(this)
|
||||||
|
val profileKey = ProfileKeyUtil.getProfileKeyFromEncodedString(encodedProfileKey)
|
||||||
|
if (isUpdatingProfilePicture && profilePicture != null) {
|
||||||
|
val storageAPI = LokiStorageAPI.shared
|
||||||
|
val deferred = deferred<Unit, Exception>()
|
||||||
|
AsyncTask.execute {
|
||||||
|
val stream = StreamDetails(ByteArrayInputStream(profilePicture), "image/jpeg", profilePicture.size.toLong())
|
||||||
|
val (_, url) = storageAPI.uploadProfilePicture(storageAPI.server, profileKey, stream)
|
||||||
|
TextSecurePreferences.setProfileAvatarUrl(this, url)
|
||||||
|
deferred.resolve(Unit)
|
||||||
|
}
|
||||||
|
promises.add(deferred.promise)
|
||||||
|
}
|
||||||
|
all(promises).alwaysUi {
|
||||||
|
if (displayName != null) {
|
||||||
|
displayNameTextView.text = displayName
|
||||||
|
}
|
||||||
|
displayNameToBeUploaded = null
|
||||||
|
if (isUpdatingProfilePicture && profilePicture != null) {
|
||||||
|
AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)), profilePicture)
|
||||||
|
TextSecurePreferences.setProfileAvatarId(this, SecureRandom().nextInt())
|
||||||
|
ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey)
|
||||||
|
ApplicationContext.getInstance(this).updatePublicChatProfileAvatarIfNeeded()
|
||||||
|
profilePictureView.update()
|
||||||
|
}
|
||||||
|
profilePictureToBeUploaded = null
|
||||||
|
hideLoader()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showLoader() {
|
||||||
|
loader.visibility = View.VISIBLE
|
||||||
|
loader.animate().setDuration(150).alpha(1.0f).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideLoader() {
|
||||||
|
loader.animate().setDuration(150).alpha(0.0f).setListener(object : AnimatorListenerAdapter() {
|
||||||
|
|
||||||
|
override fun onAnimationEnd(animation: Animator?) {
|
||||||
|
super.onAnimationEnd(animation)
|
||||||
|
loader.visibility = View.GONE
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
@ -103,11 +202,19 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun saveDisplayName() {
|
private fun saveDisplayName() {
|
||||||
val displayName = displayNameEditText.text.trim().toString()
|
val displayName = displayNameEditText.text.toString().trim()
|
||||||
// TODO: Validation
|
if (displayName.isEmpty()) {
|
||||||
|
return Toast.makeText(this, "Please pick a display name", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
if (!displayName.matches(Regex("[a-zA-Z0-9_]+"))) {
|
||||||
|
return Toast.makeText(this, "Please pick a display name that consists of only a-z, A-Z, 0-9 and _ characters", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
if (displayName.toByteArray().size > ProfileCipher.NAME_PADDED_LENGTH) {
|
||||||
|
return Toast.makeText(this, "Please pick a shorter display name", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
isEditingDisplayName = false
|
isEditingDisplayName = false
|
||||||
displayNameToBeUploaded = displayName
|
displayNameToBeUploaded = displayName
|
||||||
updateProfile(true, false)
|
updateProfile(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showQRCode() {
|
private fun showQRCode() {
|
||||||
@ -115,6 +222,10 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
push(intent)
|
push(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showEditProfilePictureUI() {
|
||||||
|
tempFile = AvatarSelection.startAvatarSelection(this, false, true)
|
||||||
|
}
|
||||||
|
|
||||||
private fun showEditDisplayNameUI() {
|
private fun showEditDisplayNameUI() {
|
||||||
isEditingDisplayName = true
|
isEditingDisplayName = true
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import android.widget.RelativeLayout
|
|||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
import kotlinx.android.synthetic.main.view_profile_picture.view.*
|
import kotlinx.android.synthetic.main.view_profile_picture.view.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto
|
||||||
import org.thoughtcrime.securesms.database.Address
|
import org.thoughtcrime.securesms.database.Address
|
||||||
import org.thoughtcrime.securesms.loki.JazzIdenticonDrawable
|
import org.thoughtcrime.securesms.loki.JazzIdenticonDrawable
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||||
@ -60,7 +61,7 @@ class ProfilePictureView : RelativeLayout {
|
|||||||
glide.clear(imageView)
|
glide.clear(imageView)
|
||||||
if (hexEncodedPublicKey.isNotEmpty()) {
|
if (hexEncodedPublicKey.isNotEmpty()) {
|
||||||
val signalProfilePicture = Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false).contactPhoto
|
val signalProfilePicture = Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false).contactPhoto
|
||||||
if (signalProfilePicture != null) {
|
if (signalProfilePicture != null && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "0") {
|
||||||
glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView)
|
glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView)
|
||||||
} else {
|
} else {
|
||||||
val size = resources.getDimensionPixelSize(sizeID)
|
val size = resources.getDimensionPixelSize(sizeID)
|
||||||
|
@ -475,7 +475,7 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized @Nullable ContactPhoto getContactPhoto() {
|
public synchronized @Nullable ContactPhoto getContactPhoto() {
|
||||||
if (isLocalNumber && profileAvatar != null) return new ProfileContactPhoto(address, String.valueOf(TextSecurePreferences.getProfileAvatarId(context)));
|
if (isLocalNumber) return new ProfileContactPhoto(address, String.valueOf(TextSecurePreferences.getProfileAvatarId(context)));
|
||||||
else if (isGroupRecipient() && groupAvatarId != null) return new GroupRecordContactPhoto(address, groupAvatarId);
|
else if (isGroupRecipient() && groupAvatarId != null) return new GroupRecordContactPhoto(address, groupAvatarId);
|
||||||
else if (systemContactPhoto != null) return new SystemContactPhoto(address, systemContactPhoto, 0);
|
else if (systemContactPhoto != null) return new SystemContactPhoto(address, systemContactPhoto, 0);
|
||||||
else if (profileAvatar != null) return new ProfileContactPhoto(address, profileAvatar);
|
else if (profileAvatar != null) return new ProfileContactPhoto(address, profileAvatar);
|
||||||
|
Loading…
Reference in New Issue
Block a user