commit
1eb38a1447
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingLeft="@dimen/large_spacing"
|
||||
android:paddingRight="@dimen/large_spacing"
|
||||
android:paddingBottom="@dimen/large_spacing"
|
||||
app:behavior_hideable="true"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
|
||||
|
||||
<org.thoughtcrime.securesms.loki.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/large_spacing" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nameTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/medium_spacing"
|
||||
android:textSize="@dimen/massive_font_size"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/text"
|
||||
android:text="Spiderman" />
|
||||
|
||||
<TextView
|
||||
style="@style/SessionIDTextView"
|
||||
android:id="@+id/publicKeyTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/large_font_size"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:textIsSelectable="true"
|
||||
android:text="05987d601943c267879be41830888066c6a024cbdc9a548d06813924bf3372ea78" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Common.ProminentOutline"
|
||||
android:id="@+id/copyButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/medium_button_height"
|
||||
android:layout_marginTop="@dimen/medium_spacing"
|
||||
android:paddingLeft="@dimen/large_spacing"
|
||||
android:paddingRight="@dimen/large_spacing"
|
||||
android:text="@string/copy" />
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,40 @@
|
||||
package org.thoughtcrime.securesms.loki.dialogs
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import kotlinx.android.synthetic.main.fragment_user_details_bottom_sheet.*
|
||||
import kotlinx.android.synthetic.main.view_conversation.view.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
|
||||
public class UserDetailsBottomSheet : BottomSheetDialogFragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_user_details_bottom_sheet, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val publicKey = arguments?.getString("publicKey") ?: return dismiss()
|
||||
profilePictureView.publicKey = publicKey
|
||||
profilePictureView.glide = GlideApp.with(this)
|
||||
profilePictureView.isLarge = true
|
||||
profilePictureView.update()
|
||||
nameTextView.text = DatabaseFactory.getLokiUserDatabase(requireContext()).getDisplayName(publicKey) ?: "Anonymous"
|
||||
publicKeyTextView.text = publicKey
|
||||
copyButton.setOnClickListener {
|
||||
val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText("Session ID", publicKey)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
Toast.makeText(requireContext(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,158 @@
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue