mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 00:37:47 +00:00
Implement remaining onion request UI
This commit is contained in:
parent
326b5a9475
commit
3a646476ff
@ -5,4 +5,4 @@
|
||||
|
||||
<solid android:color="@color/accent" />
|
||||
|
||||
</shape>
|
||||
</shape>
|
8
res/drawable/paths_building_dot.xml
Normal file
8
res/drawable/paths_building_dot.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<solid android:color="@color/paths_building" />
|
||||
|
||||
</shape>
|
@ -40,13 +40,21 @@
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="64dp" />
|
||||
|
||||
<org.thoughtcrime.securesms.loki.views.ProfilePictureView
|
||||
android:id="@+id/pathStatusView"
|
||||
<RelativeLayout
|
||||
android:id="@+id/pathStatusViewContainer"
|
||||
android:layout_width="@dimen/small_profile_picture_size"
|
||||
android:layout_height="@dimen/small_profile_picture_size"
|
||||
android:background="@color/red"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true" />
|
||||
android:layout_centerVertical="true" >
|
||||
|
||||
<org.thoughtcrime.securesms.loki.views.PathStatusView
|
||||
android:layout_width="@dimen/path_status_view_size"
|
||||
android:layout_height="@dimen/path_status_view_size"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginRight="8dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@drawable/default_session_background"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
@ -32,6 +33,14 @@
|
||||
android:orientation="vertical"
|
||||
android:layout_centerInParent="true" />
|
||||
|
||||
<com.github.ybq.android.spinkit.SpinKitView
|
||||
style="@style/SpinKitView.Large.ThreeBounce"
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
app:SpinKit_Color="@color/text" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<Button
|
||||
|
@ -28,6 +28,7 @@
|
||||
<color name="new_conversation_button_collapsed_background">#1F1F1F</color>
|
||||
<color name="pn_option_background">#1B1B1B</color>
|
||||
<color name="pn_option_border">#212121</color>
|
||||
<color name="paths_building">#FFCE3A</color>
|
||||
<!-- Session -->
|
||||
|
||||
<!-- Loki -->
|
||||
|
@ -33,6 +33,7 @@
|
||||
<dimen name="dialog_corner_radius">8dp</dimen>
|
||||
<dimen name="dialog_button_corner_radius">4dp</dimen>
|
||||
<dimen name="pn_option_corner_radius">8dp</dimen>
|
||||
<dimen name="path_status_view_size">8dp</dimen>
|
||||
<dimen name="path_row_height">56dp</dimen>
|
||||
<dimen name="path_row_dot_size">8dp</dimen>
|
||||
<dimen name="path_row_expanded_dot_size">16dp</dimen>
|
||||
|
@ -101,7 +101,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
profileButton.hexEncodedPublicKey = hexEncodedPublicKey
|
||||
profileButton.update()
|
||||
profileButton.setOnClickListener { openSettings() }
|
||||
pathStatusView.setOnClickListener { showPath() }
|
||||
pathStatusViewContainer.setOnClickListener { showPath() }
|
||||
// Set up seed reminder view
|
||||
val isMasterDevice = (TextSecurePreferences.getMasterHexEncodedPublicKey(this) == null)
|
||||
val hasViewedSeed = TextSecurePreferences.getHasViewedSeed(this)
|
||||
|
@ -1,10 +1,13 @@
|
||||
package org.thoughtcrime.securesms.loki.activities
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.support.v4.content.LocalBroadcastManager
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.view.Gravity
|
||||
@ -19,35 +22,89 @@ import kotlinx.android.synthetic.main.activity_path.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.loki.utilities.animateSizeChange
|
||||
import org.thoughtcrime.securesms.loki.utilities.fadeIn
|
||||
import org.thoughtcrime.securesms.loki.utilities.fadeOut
|
||||
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
||||
import org.whispersystems.signalservice.loki.api.onionrequests.OnionRequestAPI
|
||||
import org.whispersystems.signalservice.loki.api.onionrequests.Snode
|
||||
|
||||
class PathActivity : PassphraseRequiredActionBarActivity() {
|
||||
private val broadcastReceivers = mutableListOf<BroadcastReceiver>()
|
||||
|
||||
// region Lifecycle
|
||||
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
||||
super.onCreate(savedInstanceState, isReady)
|
||||
setContentView(R.layout.activity_path)
|
||||
supportActionBar!!.title = resources.getString(R.string.activity_path_title)
|
||||
val youRow = getPathRow("You", null, LineView.Location.Top, 1000, 4000)
|
||||
val path = OnionRequestAPI.paths.firstOrNull() ?: return finish()
|
||||
val pathRows = path.mapIndexed { index, snode ->
|
||||
val isGuardSnode = (OnionRequestAPI.guardSnodes.contains(snode))
|
||||
getPathRow(snode, LineView.Location.Middle, index.toLong() * 1000 + 2000, 4000, isGuardSnode)
|
||||
rebuildPathButton.setOnClickListener { rebuildPath() }
|
||||
update(false)
|
||||
registerObservers()
|
||||
}
|
||||
|
||||
private fun registerObservers() {
|
||||
val buildingPathsReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
handleBuildingPathsEvent()
|
||||
}
|
||||
}
|
||||
val destinationRow = getPathRow("Destination", null, LineView.Location.Bottom, 5000, 4000)
|
||||
pathRowsContainer.addView(youRow)
|
||||
for (pathRow in pathRows) {
|
||||
pathRowsContainer.addView(pathRow)
|
||||
broadcastReceivers.add(buildingPathsReceiver)
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(buildingPathsReceiver, IntentFilter("buildingPaths"))
|
||||
val pathsBuiltReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
handlePathsBuiltEvent()
|
||||
}
|
||||
}
|
||||
pathRowsContainer.addView(destinationRow)
|
||||
broadcastReceivers.add(pathsBuiltReceiver)
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(pathsBuiltReceiver, IntentFilter("pathsBuilt"))
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_path, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
for (receiver in broadcastReceivers) {
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
|
||||
}
|
||||
super.onDestroy()
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Updating
|
||||
private fun handleBuildingPathsEvent() { update(false) }
|
||||
private fun handlePathsBuiltEvent() { update(false) }
|
||||
|
||||
private fun update(isAnimated: Boolean) {
|
||||
pathRowsContainer.removeAllViews()
|
||||
if (OnionRequestAPI.paths.count() >= OnionRequestAPI.pathCount) {
|
||||
val path = OnionRequestAPI.paths.firstOrNull() ?: return finish()
|
||||
val dotAnimationRepeatInterval = path.count().toLong() * 1000 + 2000
|
||||
val pathRows = path.mapIndexed { index, snode ->
|
||||
val isGuardSnode = (OnionRequestAPI.guardSnodes.contains(snode))
|
||||
getPathRow(snode, LineView.Location.Middle, index.toLong() * 1000 + 2000, dotAnimationRepeatInterval, isGuardSnode)
|
||||
}
|
||||
val youRow = getPathRow("You", null, LineView.Location.Top, 1000, dotAnimationRepeatInterval)
|
||||
val destinationRow = getPathRow("Destination", null, LineView.Location.Bottom, path.count().toLong() * 1000 + 2000, dotAnimationRepeatInterval)
|
||||
val rows = listOf( youRow ) + pathRows + listOf( destinationRow )
|
||||
for (row in rows) {
|
||||
pathRowsContainer.addView(row)
|
||||
}
|
||||
if (isAnimated) {
|
||||
spinner.fadeOut()
|
||||
} else {
|
||||
spinner.alpha = 0.0f
|
||||
}
|
||||
} else {
|
||||
if (isAnimated) {
|
||||
spinner.fadeIn()
|
||||
} else {
|
||||
spinner.alpha = 1.0f
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region General
|
||||
@ -108,6 +165,12 @@ class PathActivity : PassphraseRequiredActionBarActivity() {
|
||||
Toast.makeText(this, R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun rebuildPath() {
|
||||
OnionRequestAPI.guardSnodes = setOf()
|
||||
OnionRequestAPI.paths = listOf()
|
||||
OnionRequestAPI.buildPaths()
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Line View
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.thoughtcrime.securesms.loki.activities
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.app.Activity
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
@ -31,6 +29,8 @@ import org.thoughtcrime.securesms.database.Address
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.loki.dialogs.ClearAllDataDialog
|
||||
import org.thoughtcrime.securesms.loki.dialogs.SeedDialog
|
||||
import org.thoughtcrime.securesms.loki.utilities.fadeIn
|
||||
import org.thoughtcrime.securesms.loki.utilities.fadeOut
|
||||
import org.thoughtcrime.securesms.loki.utilities.push
|
||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
@ -147,7 +147,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
}
|
||||
|
||||
private fun updateProfile(isUpdatingProfilePicture: Boolean) {
|
||||
showLoader()
|
||||
loader.fadeIn()
|
||||
val promises = mutableListOf<Promise<*, Exception>>()
|
||||
val displayName = displayNameToBeUploaded
|
||||
if (displayName != null) {
|
||||
@ -187,24 +187,9 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
profilePictureView.update()
|
||||
}
|
||||
profilePictureToBeUploaded = null
|
||||
hideLoader()
|
||||
loader.fadeOut()
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// region Interaction
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.thoughtcrime.securesms.loki.utilities
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.FloatEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.graphics.PointF
|
||||
@ -31,4 +33,19 @@ fun View.animateSizeChange(@DimenRes startSizeID: Int, @DimenRes endSizeID: Int,
|
||||
this.layoutParams = layoutParams
|
||||
}
|
||||
animation.start()
|
||||
}
|
||||
}
|
||||
|
||||
fun View.fadeIn(duration: Long = 150) {
|
||||
visibility = View.VISIBLE
|
||||
animate().setDuration(duration).alpha(1.0f).start()
|
||||
}
|
||||
|
||||
fun View.fadeOut(duration: Long = 150) {
|
||||
animate().setDuration(duration).alpha(0.0f).setListener(object : AnimatorListenerAdapter() {
|
||||
|
||||
override fun onAnimationEnd(animation: Animator?) {
|
||||
super.onAnimationEnd(animation)
|
||||
visibility = View.GONE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
77
src/org/thoughtcrime/securesms/loki/views/PathStatusView.kt
Normal file
77
src/org/thoughtcrime/securesms/loki/views/PathStatusView.kt
Normal file
@ -0,0 +1,77 @@
|
||||
package org.thoughtcrime.securesms.loki.views
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.support.v4.content.LocalBroadcastManager
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import network.loki.messenger.R
|
||||
import org.whispersystems.signalservice.loki.api.onionrequests.OnionRequestAPI
|
||||
|
||||
class PathStatusView : View {
|
||||
private val broadcastReceivers = mutableListOf<BroadcastReceiver>()
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
initialize()
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
initialize()
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
||||
initialize()
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
|
||||
initialize()
|
||||
}
|
||||
|
||||
private fun initialize() {
|
||||
update()
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
registerObservers()
|
||||
}
|
||||
|
||||
private fun registerObservers() {
|
||||
val buildingPathsReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
handleBuildingPathsEvent()
|
||||
}
|
||||
}
|
||||
broadcastReceivers.add(buildingPathsReceiver)
|
||||
LocalBroadcastManager.getInstance(context).registerReceiver(buildingPathsReceiver, IntentFilter("buildingPaths"))
|
||||
val pathsBuiltReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
handlePathsBuiltEvent()
|
||||
}
|
||||
}
|
||||
broadcastReceivers.add(pathsBuiltReceiver)
|
||||
LocalBroadcastManager.getInstance(context).registerReceiver(pathsBuiltReceiver, IntentFilter("pathsBuilt"))
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
for (receiver in broadcastReceivers) {
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver)
|
||||
}
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
private fun handleBuildingPathsEvent() { update() }
|
||||
private fun handlePathsBuiltEvent() { update() }
|
||||
|
||||
private fun update() {
|
||||
if (OnionRequestAPI.paths.count() >= OnionRequestAPI.pathCount) {
|
||||
setBackgroundResource(R.drawable.accent_dot)
|
||||
} else {
|
||||
setBackgroundResource(R.drawable.paths_building_dot)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user