mirror of
https://github.com/oxen-io/session-android.git
synced 2023-12-14 02:53:01 +01:00
7a773016da
* feat: start new app theming feature * feat: add some theming colours * refactor: start refactoring themes and colours to use dynamic attributes * feat: adding more colours and switching over default colours to be theme based instead of hard-coded or day/night specific * refactor: take a look at ocean light and logo colour * feat: global search colours for light and dark ocean * feat: more styling * feat: adding themes to conversation activity and refactoring the base theme to apply over the top of the activity's theme so it retains noActionBar etc * feat: add dynamic accent color * docs: add todo for changing how accent colour is applied * feat: update new theming to use override primary style so that the regular colorAccent attribute can be used in existing layouts * feat: coordinating styles across layouts, fixing up pinned icons and naming for conversation list items * refactor: re-styling layouts to match new themes and attributes. Need to figure out action mode close button * refactor: remove @color/text and replace with ?android:textColorPrimary to override in themes * refactor: add context theme wrapper to bottom sheet dialog that references accent color * fix: input bar bug fix and preference activity themes * refactor: new settings menu options * fix: crash for PNModeActivity.kt refactor: move ordering in seed dialog to match designs, copy changes to match new settings menu * feat: add new appearance settings activity * refactor: title and VM changes * fix: correct override * feat: add theme appearance screen UI features and start VM implementation. re-add legacy theme utils to get default for migration * fix: compile errors and missing themes from emoji features * refactor: remove background shape alteration and old bottom sheet styles, re-add the theme mode attr * feat: appearance screen wired up, just need to refresh theme * feat: add theme state recreation and fix match system settings option * refactor: add bottom margin * feat: explore custom preference category * feat: add the customized session theme for CorrectedPreferenceFragment * feat: replace AppProtectionPreferenceFragment to extend ListSummaryPreferenceFragment * refactor: change drawable style and remove explicit dividers * refactor: remove divider in CorrectedPreferenceFragment * feat: add theme state check on resume, might be jarring currently * feat: add preference divider elements for settings menu * refactor: settings menu redesigns * refactor: change led preference to integer and refactor TextSecurePreferences.kt * feat: add scroll parcel to save/restore hierarchy on restart with appearance changes * feat: add the conversations blocked contacts and refactor preference order and copy * feat: add blocked contacts activity, basic layout and vm * feat: add unblock DB functions and storage protocol, start working on the DB query state flow, might have to just implement recipient on modified listener * feat: add blocked contacts and notif recipient listeners * feat: add recipient db reader * feat: add blocked contact interactions and fix a theming crash for notifications * feat: introduce better equals and hashcode implementations to recipient, replace home diff util content check with hashcode-based comparison * feat: add settings menu vectors * fix: preview compile error * refactor: migrating settings menu to new designs * feat: help menu * refactor: simplify link opening * refactor: remove space * feat: refactor preferences and start theming for light mode options * refactor: fixing dark and light modes with dialogs * refactor: popup dialogs use proper themes now * refactor: alert dialogs and media edit fragments use attribute references * refactor: use input bar button attribute instead color control normal in vector tint * refactor: transparency, dialog fixes, notification fix * refactor: attrs and styles for buttons * fix: use prominent button color on the outline button's border * fix: fix the trash * refactor: remove the appearance * refactor: avatar placeholder generation, chips and element border styles * refactor: use colors instead of style references * refactor: theming changes to match designs and feedback * refactor: the titles are bold and the categories are tertiary coloured now * fix: appearance settings match preferences, search bottom bar uses themed attributes * refactor: increase setting button height * Update clear all data dialog * Update seed dialog * refactor: more qa feedback changes * feat: add new TLs and fa-rIR TLs * Update notification content dialog * Fix message requests clear all button text color * feat: re-add screenshot observer * refactor: make send tint accent color * feat: add unread background differences * fix: change unread count indicator * build: upgrade build numbers * Fix message requests popupmenu background color * fix: crash from attr reference in color attribute * build: upgrade build number * fix: message bubbles, thumbnail backgrounds, search bar visibility with input bar, attachment buttons * fix: tertiary text for keyboard page search view * fix: emoji overflow colour differences * fix: reaction pill dialog background is now correct colour * Add style to reactions tab layout * fix: appearance activity reverting primary color at correct time * fix: show call privacy warning every time instead of just once * fix: gradient background(?) and audio autoplay disable * fix: crash in all media containing documents * fix: reaction dialog heading fixes * Add style to reactions tab layout * fix: remove gradient backgrounds * fix: adding new reaction normal text attribute to try correct the tab layout * fix: ocean dark unread/read colours * build; update build number * build: update build number Co-authored-by: charles <charles@oxen.io>
226 lines
7.6 KiB
Kotlin
226 lines
7.6 KiB
Kotlin
package org.thoughtcrime.securesms.util
|
|
|
|
import android.animation.ArgbEvaluator
|
|
import android.animation.ValueAnimator
|
|
import android.content.Context
|
|
import android.graphics.Canvas
|
|
import android.graphics.Paint
|
|
import android.util.AttributeSet
|
|
import android.view.View
|
|
import android.widget.LinearLayout
|
|
import android.widget.RelativeLayout
|
|
import androidx.annotation.ColorInt
|
|
import androidx.annotation.ColorRes
|
|
import network.loki.messenger.R
|
|
import kotlin.math.roundToInt
|
|
|
|
interface GlowView {
|
|
var mainColor: Int
|
|
var sessionShadowColor: Int
|
|
}
|
|
|
|
object GlowViewUtilities {
|
|
|
|
fun animateColorIdChange(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 animateColorChange(view: GlowView, @ColorInt startColor: Int, @ColorInt endColor: Int) {
|
|
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 animateShadowColorIdChange(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()
|
|
}
|
|
|
|
fun animateShadowColorChange(view: GlowView, @ColorInt startColor: Int, @ColorInt endColor: Int) {
|
|
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
|
|
}
|
|
|
|
class NewConversationButtonImageView : androidx.appcompat.widget.AppCompatImageView, GlowView {
|
|
@ColorInt override var mainColor: Int = 0
|
|
set(newValue) { field = newValue; paint.color = newValue }
|
|
@ColorInt override var sessionShadowColor: Int = 0
|
|
set(newValue) { field = newValue; paint.setShadowLayer(toPx(6, 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
|
|
}
|
|
|
|
// 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()
|
|
c.drawCircle(w / 2, h / 2, w / 2, paint)
|
|
super.onDraw(c)
|
|
}
|
|
// endregion
|
|
}
|
|
|
|
class PathDotView : View, GlowView {
|
|
@ColorInt override var mainColor: Int = 0
|
|
set(newValue) { field = newValue; paint.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
|
|
}
|
|
|
|
// 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()
|
|
c.drawCircle(w / 2, h / 2, w / 2, paint)
|
|
super.onDraw(c)
|
|
}
|
|
// endregion
|
|
}
|
|
|
|
class InputBarButtonImageViewContainer : RelativeLayout, GlowView {
|
|
@ColorInt override var mainColor: Int = 0
|
|
set(newValue) { field = newValue; fillPaint.color = newValue }
|
|
@ColorInt var strokeColor: Int = 0
|
|
set(newValue) { field = newValue; strokePaint.color = newValue }
|
|
@ColorInt override var sessionShadowColor: Int = 0 // Unused
|
|
|
|
private val fillPaint: 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 = 1.0f
|
|
result.alpha = (255 * 0.2f).roundToInt()
|
|
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()
|
|
c.drawCircle(w / 2, h / 2, w / 2, fillPaint)
|
|
if (strokeColor != 0) {
|
|
c.drawCircle(w / 2, h / 2, w / 2, strokePaint)
|
|
}
|
|
super.onDraw(c)
|
|
}
|
|
// endregion
|
|
}
|