mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-21 19:31:30 +00:00
Add PN mode screen glow
This commit is contained in:
parent
be04246ba2
commit
eafd4bf557
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/contentView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
@ -30,7 +31,7 @@
|
|||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
android:text="There are two ways Session can notify you of new messages." />
|
android:text="There are two ways Session can notify you of new messages." />
|
||||||
|
|
||||||
<LinearLayout
|
<org.thoughtcrime.securesms.loki.views.PNModeView
|
||||||
android:id="@+id/fcmOptionView"
|
android:id="@+id/fcmOptionView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -66,9 +67,9 @@
|
|||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:text="@string/activity_pn_mode_recommended_option_tag" />
|
android:text="@string/activity_pn_mode_recommended_option_tag" />
|
||||||
|
|
||||||
</LinearLayout>
|
</org.thoughtcrime.securesms.loki.views.PNModeView>
|
||||||
|
|
||||||
<LinearLayout
|
<org.thoughtcrime.securesms.loki.views.PNModeView
|
||||||
android:id="@+id/backgroundPollingOptionView"
|
android:id="@+id/backgroundPollingOptionView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -95,7 +96,7 @@
|
|||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
android:text="Session will occasionally check for new messages in the background. Full metadata protection is guaranteed, but message notifications will be unreliable." />
|
android:text="Session will occasionally check for new messages in the background. Full metadata protection is guaranteed, but message notifications will be unreliable." />
|
||||||
|
|
||||||
</LinearLayout>
|
</org.thoughtcrime.securesms.loki.views.PNModeView>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/contentView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
@ -30,7 +31,7 @@
|
|||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
android:text="There are two ways Session can notify you of new messages." />
|
android:text="There are two ways Session can notify you of new messages." />
|
||||||
|
|
||||||
<LinearLayout
|
<org.thoughtcrime.securesms.loki.views.PNModeView
|
||||||
android:id="@+id/fcmOptionView"
|
android:id="@+id/fcmOptionView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -66,9 +67,9 @@
|
|||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:text="@string/activity_pn_mode_recommended_option_tag" />
|
android:text="@string/activity_pn_mode_recommended_option_tag" />
|
||||||
|
|
||||||
</LinearLayout>
|
</org.thoughtcrime.securesms.loki.views.PNModeView>
|
||||||
|
|
||||||
<LinearLayout
|
<org.thoughtcrime.securesms.loki.views.PNModeView
|
||||||
android:id="@+id/backgroundPollingOptionView"
|
android:id="@+id/backgroundPollingOptionView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -95,7 +96,7 @@
|
|||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
android:text="Session will occasionally check for new messages in the background. Full metadata protection is guaranteed, but message notifications will be unreliable." />
|
android:text="Session will occasionally check for new messages in the background. Full metadata protection is guaranteed, but message notifications will be unreliable." />
|
||||||
|
|
||||||
</LinearLayout>
|
</org.thoughtcrime.securesms.loki.views.PNModeView>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package org.thoughtcrime.securesms.loki.activities
|
package org.thoughtcrime.securesms.loki.activities
|
||||||
|
|
||||||
|
import android.animation.ArgbEvaluator
|
||||||
|
import android.animation.ValueAnimator
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.drawable.TransitionDrawable
|
import android.graphics.drawable.TransitionDrawable
|
||||||
@ -9,27 +11,36 @@ import androidx.annotation.DrawableRes
|
|||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.ColorRes
|
||||||
import kotlinx.android.synthetic.main.activity_display_name.registerButton
|
import kotlinx.android.synthetic.main.activity_display_name.registerButton
|
||||||
import kotlinx.android.synthetic.main.activity_pn_mode.*
|
import kotlinx.android.synthetic.main.activity_pn_mode.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||||
|
import org.thoughtcrime.securesms.loki.utilities.disableClipping
|
||||||
|
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
||||||
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
|
import org.thoughtcrime.securesms.loki.utilities.setUpActionBarSessionLogo
|
||||||
import org.thoughtcrime.securesms.loki.utilities.show
|
import org.thoughtcrime.securesms.loki.utilities.show
|
||||||
|
import org.thoughtcrime.securesms.loki.views.GlowViewUtilities
|
||||||
|
import org.thoughtcrime.securesms.loki.views.PNModeView
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
|
||||||
class PNModeActivity : BaseActionBarActivity() {
|
class PNModeActivity : BaseActionBarActivity() {
|
||||||
private var selectedOptionView: LinearLayout? = null
|
private var selectedOptionView: PNModeView? = null
|
||||||
|
|
||||||
// region Lifecycle
|
// region Lifecycle
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setUpActionBarSessionLogo()
|
setUpActionBarSessionLogo()
|
||||||
setContentView(R.layout.activity_pn_mode)
|
setContentView(R.layout.activity_pn_mode)
|
||||||
|
contentView.disableClipping()
|
||||||
fcmOptionView.setOnClickListener { toggleFCM() }
|
fcmOptionView.setOnClickListener { toggleFCM() }
|
||||||
|
fcmOptionView.mainColor = resources.getColorWithID(R.color.pn_option_background, theme)
|
||||||
|
fcmOptionView.strokeColor = resources.getColorWithID(R.color.pn_option_border, theme)
|
||||||
backgroundPollingOptionView.setOnClickListener { toggleBackgroundPolling() }
|
backgroundPollingOptionView.setOnClickListener { toggleBackgroundPolling() }
|
||||||
|
backgroundPollingOptionView.mainColor = resources.getColorWithID(R.color.pn_option_background, theme)
|
||||||
|
backgroundPollingOptionView.strokeColor = resources.getColorWithID(R.color.pn_option_border, theme)
|
||||||
registerButton.setOnClickListener { register() }
|
registerButton.setOnClickListener { register() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,15 +82,23 @@ class PNModeActivity : BaseActionBarActivity() {
|
|||||||
when (selectedOptionView) {
|
when (selectedOptionView) {
|
||||||
null -> {
|
null -> {
|
||||||
performTransition(R.drawable.pn_option_background_select_transition, fcmOptionView)
|
performTransition(R.drawable.pn_option_background_select_transition, fcmOptionView)
|
||||||
|
GlowViewUtilities.animateShadowColorChange(this, fcmOptionView, R.color.transparent, R.color.accent)
|
||||||
|
animateStrokeColorChange(fcmOptionView, R.color.pn_option_border, R.color.accent)
|
||||||
selectedOptionView = fcmOptionView
|
selectedOptionView = fcmOptionView
|
||||||
}
|
}
|
||||||
fcmOptionView -> {
|
fcmOptionView -> {
|
||||||
performTransition(R.drawable.pn_option_background_deselect_transition, fcmOptionView)
|
performTransition(R.drawable.pn_option_background_deselect_transition, fcmOptionView)
|
||||||
|
GlowViewUtilities.animateShadowColorChange(this, fcmOptionView, R.color.accent, R.color.transparent)
|
||||||
|
animateStrokeColorChange(fcmOptionView, R.color.accent, R.color.pn_option_border)
|
||||||
selectedOptionView = null
|
selectedOptionView = null
|
||||||
}
|
}
|
||||||
backgroundPollingOptionView -> {
|
backgroundPollingOptionView -> {
|
||||||
performTransition(R.drawable.pn_option_background_select_transition, fcmOptionView)
|
performTransition(R.drawable.pn_option_background_select_transition, fcmOptionView)
|
||||||
|
GlowViewUtilities.animateShadowColorChange(this, fcmOptionView, R.color.transparent, R.color.accent)
|
||||||
|
animateStrokeColorChange(fcmOptionView, R.color.pn_option_border, R.color.accent)
|
||||||
performTransition(R.drawable.pn_option_background_deselect_transition, backgroundPollingOptionView)
|
performTransition(R.drawable.pn_option_background_deselect_transition, backgroundPollingOptionView)
|
||||||
|
GlowViewUtilities.animateShadowColorChange(this, backgroundPollingOptionView, R.color.accent, R.color.transparent)
|
||||||
|
animateStrokeColorChange(backgroundPollingOptionView, R.color.accent, R.color.pn_option_border)
|
||||||
selectedOptionView = fcmOptionView
|
selectedOptionView = fcmOptionView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,20 +108,40 @@ class PNModeActivity : BaseActionBarActivity() {
|
|||||||
when (selectedOptionView) {
|
when (selectedOptionView) {
|
||||||
null -> {
|
null -> {
|
||||||
performTransition(R.drawable.pn_option_background_select_transition, backgroundPollingOptionView)
|
performTransition(R.drawable.pn_option_background_select_transition, backgroundPollingOptionView)
|
||||||
|
GlowViewUtilities.animateShadowColorChange(this, backgroundPollingOptionView, R.color.transparent, R.color.accent)
|
||||||
|
animateStrokeColorChange(backgroundPollingOptionView, R.color.pn_option_border, R.color.accent)
|
||||||
selectedOptionView = backgroundPollingOptionView
|
selectedOptionView = backgroundPollingOptionView
|
||||||
}
|
}
|
||||||
backgroundPollingOptionView -> {
|
backgroundPollingOptionView -> {
|
||||||
performTransition(R.drawable.pn_option_background_deselect_transition, backgroundPollingOptionView)
|
performTransition(R.drawable.pn_option_background_deselect_transition, backgroundPollingOptionView)
|
||||||
|
GlowViewUtilities.animateShadowColorChange(this, backgroundPollingOptionView, R.color.accent, R.color.transparent)
|
||||||
|
animateStrokeColorChange(backgroundPollingOptionView, R.color.accent, R.color.pn_option_border)
|
||||||
selectedOptionView = null
|
selectedOptionView = null
|
||||||
}
|
}
|
||||||
fcmOptionView -> {
|
fcmOptionView -> {
|
||||||
performTransition(R.drawable.pn_option_background_select_transition, backgroundPollingOptionView)
|
performTransition(R.drawable.pn_option_background_select_transition, backgroundPollingOptionView)
|
||||||
|
GlowViewUtilities.animateShadowColorChange(this, backgroundPollingOptionView, R.color.transparent, R.color.accent)
|
||||||
|
animateStrokeColorChange(backgroundPollingOptionView, R.color.pn_option_border, R.color.accent)
|
||||||
performTransition(R.drawable.pn_option_background_deselect_transition, fcmOptionView)
|
performTransition(R.drawable.pn_option_background_deselect_transition, fcmOptionView)
|
||||||
|
GlowViewUtilities.animateShadowColorChange(this, fcmOptionView, R.color.accent, R.color.transparent)
|
||||||
|
animateStrokeColorChange(fcmOptionView, R.color.accent, R.color.pn_option_border)
|
||||||
selectedOptionView = backgroundPollingOptionView
|
selectedOptionView = backgroundPollingOptionView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun animateStrokeColorChange(bubble: PNModeView, @ColorRes startColorID: Int, @ColorRes endColorID: Int) {
|
||||||
|
val startColor = resources.getColorWithID(startColorID, theme)
|
||||||
|
val endColor = resources.getColorWithID(endColorID, theme)
|
||||||
|
val animation = ValueAnimator.ofObject(ArgbEvaluator(), startColor, endColor)
|
||||||
|
animation.duration = 250
|
||||||
|
animation.addUpdateListener { animator ->
|
||||||
|
val color = animator.animatedValue as Int
|
||||||
|
bubble.strokeColor = color
|
||||||
|
}
|
||||||
|
animation.start()
|
||||||
|
}
|
||||||
|
|
||||||
private fun register() {
|
private fun register() {
|
||||||
if (selectedOptionView == null) {
|
if (selectedOptionView == null) {
|
||||||
val dialog = AlertDialog.Builder(this)
|
val dialog = AlertDialog.Builder(this)
|
||||||
@ -111,7 +150,6 @@ class PNModeActivity : BaseActionBarActivity() {
|
|||||||
dialog.create().show()
|
dialog.create().show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val displayName = TextSecurePreferences.getProfileName(this)
|
|
||||||
TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
|
TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
|
||||||
TextSecurePreferences.setPromptedPushRegistration(this, true)
|
TextSecurePreferences.setPromptedPushRegistration(this, true)
|
||||||
TextSecurePreferences.setIsUsingFCM(this, (selectedOptionView == fcmOptionView))
|
TextSecurePreferences.setIsUsingFCM(this, (selectedOptionView == fcmOptionView))
|
||||||
|
92
src/org/thoughtcrime/securesms/loki/views/GlowView.kt
Normal file
92
src/org/thoughtcrime/securesms/loki/views/GlowView.kt
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package org.thoughtcrime.securesms.loki.views
|
||||||
|
|
||||||
|
import android.animation.ArgbEvaluator
|
||||||
|
import android.animation.ValueAnimator
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.*
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewOutlineProvider
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import androidx.annotation.ColorInt
|
||||||
|
import androidx.annotation.ColorRes
|
||||||
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
||||||
|
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||||
|
|
||||||
|
interface GlowView {
|
||||||
|
var mainColor: Int
|
||||||
|
var sessionShadowColor: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
object GlowViewUtilities {
|
||||||
|
|
||||||
|
fun animateColorChange(context: Context, view: GlowView, @ColorRes startColorID: Int, @ColorRes endColorID: Int) {
|
||||||
|
val startColor = context.resources.getColorWithID(startColorID, context.theme)
|
||||||
|
val endColor = context.resources.getColorWithID(endColorID, context.theme)
|
||||||
|
val animation = ValueAnimator.ofObject(ArgbEvaluator(), startColor, endColor)
|
||||||
|
animation.duration = 250
|
||||||
|
animation.addUpdateListener { animator ->
|
||||||
|
val color = animator.animatedValue as Int
|
||||||
|
view.mainColor = color
|
||||||
|
}
|
||||||
|
animation.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun animateShadowColorChange(context: Context, view: GlowView, @ColorRes startColorID: Int, @ColorRes endColorID: Int) {
|
||||||
|
val startColor = context.resources.getColorWithID(startColorID, context.theme)
|
||||||
|
val endColor = context.resources.getColorWithID(endColorID, context.theme)
|
||||||
|
val animation = ValueAnimator.ofObject(ArgbEvaluator(), startColor, endColor)
|
||||||
|
animation.duration = 250
|
||||||
|
animation.addUpdateListener { animator ->
|
||||||
|
val color = animator.animatedValue as Int
|
||||||
|
view.sessionShadowColor = color
|
||||||
|
}
|
||||||
|
animation.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PNModeView : LinearLayout, GlowView {
|
||||||
|
@ColorInt override var mainColor: Int = 0
|
||||||
|
set(newValue) { field = newValue; paint.color = newValue }
|
||||||
|
@ColorInt var strokeColor: Int = 0
|
||||||
|
set(newValue) { field = newValue; strokePaint.color = newValue }
|
||||||
|
@ColorInt override var sessionShadowColor: Int = 0
|
||||||
|
set(newValue) { field = newValue; paint.setShadowLayer(toPx(4, resources).toFloat(), 0.0f, 0.0f, newValue) }
|
||||||
|
|
||||||
|
private val paint: Paint by lazy {
|
||||||
|
val result = Paint()
|
||||||
|
result.style = Paint.Style.FILL
|
||||||
|
result.isAntiAlias = true
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
private val strokePaint: Paint by lazy {
|
||||||
|
val result = Paint()
|
||||||
|
result.style = Paint.Style.STROKE
|
||||||
|
result.isAntiAlias = true
|
||||||
|
result.strokeWidth = toPx(1, resources).toFloat()
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
// region Lifecycle
|
||||||
|
constructor(context: Context) : super(context) { }
|
||||||
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { }
|
||||||
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { }
|
||||||
|
|
||||||
|
init {
|
||||||
|
setWillNotDraw(false)
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Updating
|
||||||
|
override fun onDraw(c: Canvas) {
|
||||||
|
val w = width.toFloat()
|
||||||
|
val h = height.toFloat()
|
||||||
|
val r = resources.getDimension(R.dimen.pn_option_corner_radius)
|
||||||
|
c.drawRoundRect(0.0f, 0.0f, w, h, r, r, paint)
|
||||||
|
c.drawRoundRect(0.0f, 0.0f, w, h, r, r, strokePaint)
|
||||||
|
super.onDraw(c)
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user