Update DisplayNameActivity

This commit is contained in:
andrew 2023-09-26 14:57:28 +09:30
parent 1068c167a3
commit 76166b39a9
16 changed files with 239 additions and 74 deletions

View File

@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:$gradlePluginVersion"
classpath 'com.android.tools.build:gradle:7.4.2'
classpath files('libs/gradle-witness.jar')
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion"
@ -335,14 +335,13 @@ dependencies {
testImplementation 'org.robolectric:shadows-multidex:4.4'
implementation 'com.github.bumptech.glide:compose:1.0.0-alpha.1'
implementation 'androidx.compose.ui:ui:1.4.3'
implementation 'androidx.compose.ui:ui-tooling:1.4.3'
implementation 'androidx.compose.ui:ui:1.5.1'
implementation 'androidx.compose.ui:ui-tooling:1.5.1'
implementation "com.google.accompanist:accompanist-themeadapter-appcompat:0.31.5-beta"
implementation "com.google.accompanist:accompanist-pager-indicators:0.31.5-beta"
implementation "androidx.compose.runtime:runtime-livedata:1.4.3"
implementation 'androidx.compose.foundation:foundation-layout:1.5.0-alpha02'
implementation 'androidx.compose.material:material:1.5.0-alpha02'
implementation 'androidx.compose.foundation:foundation-layout:1.5.1'
implementation 'androidx.compose.material:material:1.5.1'
}
static def getLastCommitTimestamp() {

View File

@ -115,7 +115,7 @@
android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.Session.DayNight.FlatActionBar" />
<activity
android:name="org.thoughtcrime.securesms.onboarding.DisplayNameActivity"
android:name="org.thoughtcrime.securesms.onboarding.name.DisplayNameActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.Session.DayNight.FlatActionBar" />

View File

@ -41,7 +41,7 @@ class AlbumThumbnailView : RelativeLayout {
private var slides: List<Slide> = listOf()
private var slideSize: Int = 0
override fun dispatchDraw(canvas: Canvas?) {
override fun dispatchDraw(canvas: Canvas) {
super.dispatchDraw(canvas)
cornerMask.mask(canvas)
}

View File

@ -30,9 +30,7 @@ class ThumbnailProgressBar: View {
private val objectRect = Rect()
private val drawingRect = Rect()
override fun dispatchDraw(canvas: Canvas?) {
if (canvas == null) return
override fun dispatchDraw(canvas: Canvas) {
getDrawingRect(objectRect)
drawingRect.set(objectRect)

View File

@ -1,57 +0,0 @@
package org.thoughtcrime.securesms.onboarding
import android.content.Intent
import android.os.Bundle
import android.view.KeyEvent
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.TextView.OnEditorActionListener
import android.widget.Toast
import network.loki.messenger.R
import network.loki.messenger.databinding.ActivityDisplayNameBinding
import org.session.libsession.utilities.SSKEnvironment.ProfileManagerProtocol
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.util.push
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
import org.session.libsession.utilities.TextSecurePreferences
class DisplayNameActivity : BaseActionBarActivity() {
private lateinit var binding: ActivityDisplayNameBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setUpActionBarSessionLogo()
binding = ActivityDisplayNameBinding.inflate(layoutInflater)
setContentView(binding.root)
with(binding) {
displayNameEditText.imeOptions = displayNameEditText.imeOptions or 16777216 // Always use incognito keyboard
displayNameEditText.setOnEditorActionListener(
OnEditorActionListener { _, actionID, event ->
if (actionID == EditorInfo.IME_ACTION_SEARCH ||
actionID == EditorInfo.IME_ACTION_DONE ||
(event.action == KeyEvent.ACTION_DOWN &&
event.keyCode == KeyEvent.KEYCODE_ENTER)) {
register()
return@OnEditorActionListener true
}
false
})
registerButton.setOnClickListener { register() }
}
}
private fun register() {
val displayName = binding.displayNameEditText.text.toString().trim()
if (displayName.isEmpty()) {
return Toast.makeText(this, R.string.activity_display_name_display_name_missing_error, Toast.LENGTH_SHORT).show()
}
if (displayName.toByteArray().size > ProfileManagerProtocol.Companion.NAME_PADDED_LENGTH) {
return Toast.makeText(this, R.string.activity_display_name_display_name_too_long_error, Toast.LENGTH_SHORT).show()
}
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(binding.displayNameEditText.windowToken, 0)
TextSecurePreferences.setProfileName(this, displayName)
val intent = Intent(this, PNModeActivity::class.java)
push(intent)
}
}

View File

@ -6,6 +6,7 @@ import network.loki.messenger.databinding.ActivityLandingBinding
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.onboarding.name.DisplayNameActivity
import org.thoughtcrime.securesms.service.KeyCachingService
import org.thoughtcrime.securesms.util.push
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo

View File

@ -24,6 +24,7 @@ import kotlinx.coroutines.launch
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.onboarding.name.DisplayNameActivity
import org.thoughtcrime.securesms.ui.AppTheme
import org.thoughtcrime.securesms.ui.ProgressArc
import org.thoughtcrime.securesms.util.push

View File

@ -0,0 +1,139 @@
package org.thoughtcrime.securesms.onboarding.name
import android.content.Intent
import android.os.Bundle
import android.view.inputmethod.InputMethodManager
import androidx.activity.viewModels
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha
import androidx.compose.material.LocalContentColor
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.material.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import network.loki.messenger.R
import network.loki.messenger.databinding.ActivityDisplayNameBinding
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.onboarding.PNModeActivity
import org.thoughtcrime.securesms.ui.AppTheme
import org.thoughtcrime.securesms.ui.OutlineButton
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.baseBold
import org.thoughtcrime.securesms.ui.colorDestructive
import org.thoughtcrime.securesms.util.push
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
@AndroidEntryPoint
class DisplayNameActivity : BaseActionBarActivity() {
private val viewModel: DisplayNameViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setUpActionBarSessionLogo()
ComposeView(this)
.apply { setContent { DisplayNameScreen(viewModel) } }
.let(::setContentView)
lifecycleScope.launch {
viewModel.eventFlow.collect {
// val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
// inputMethodManager.hideSoftInputFromWindow(content.displayNameEditText.windowToken, 0)
Intent(this@DisplayNameActivity, PNModeActivity::class.java).also(::push)
}
}
}
@Composable
private fun DisplayNameScreen(viewModel: DisplayNameViewModel) {
val state = viewModel.stateFlow.collectAsState()
AppTheme {
DisplayName(state.value, viewModel::onChange, viewModel::onContinue)
}
}
@Preview
@Composable
fun PreviewDisplayName() {
PreviewTheme(R.style.Classic_Dark) {
DisplayName(State())
}
}
@Composable
fun DisplayName(state: State, onChange: (String) -> Unit = {}, onContinue: () -> Unit = {}) {
Column(
verticalArrangement = Arrangement.spacedBy(20.dp),
modifier = Modifier
.padding(horizontal = 50.dp)
.padding(bottom = 12.dp)
) {
Spacer(modifier = Modifier.weight(1f))
Text(stringResource(state.title), style = MaterialTheme.typography.h4)
Text(
stringResource(state.description),
style = MaterialTheme.typography.base,
modifier = Modifier.padding(bottom = 12.dp))
OutlinedTextField(
value = state.displayName,
onValueChange = { onChange(it) },
placeholder = { Text(stringResource(R.string.activity_display_name_edit_text_hint)) },
colors = TextFieldDefaults.outlinedTextFieldColors(
textColor = state.error?.let { colorDestructive } ?:
LocalContentColor.current.copy(LocalContentAlpha.current),
focusedBorderColor = Color(0xff414141),
unfocusedBorderColor = Color(0xff414141),
cursorColor = LocalContentColor.current,
placeholderColor = state.error?.let { colorDestructive }
?: MaterialTheme.colors.onSurface.copy(ContentAlpha.medium)
),
singleLine = true,
keyboardActions = KeyboardActions(
onDone = { viewModel.onContinue() },
onGo = { viewModel.onContinue() },
onSearch = { viewModel.onContinue() },
onSend = { viewModel.onContinue() },
),
isError = state.error != null,
shape = RoundedCornerShape(12.dp)
)
state.error?.let {
Text(stringResource(it), style = MaterialTheme.typography.baseBold, color = MaterialTheme.colors.error)
}
Spacer(modifier = Modifier.weight(2f))
OutlineButton(
stringResource(R.string.continue_2),
modifier = Modifier
.align(Alignment.CenterHorizontally)
.width(262.dp)
) { onContinue() }
}
}
}

View File

@ -0,0 +1,63 @@
package org.thoughtcrime.securesms.onboarding.name
import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import network.loki.messenger.R
import org.session.libsession.utilities.SSKEnvironment.ProfileManagerProtocol.Companion.NAME_PADDED_LENGTH
import org.session.libsession.utilities.TextSecurePreferences
import javax.inject.Inject
@HiltViewModel
class DisplayNameViewModel @Inject constructor(
private val prefs: TextSecurePreferences
): ViewModel() {
private val state = MutableStateFlow(State())
val stateFlow = state.asStateFlow()
private val event = Channel<Event>()
val eventFlow = event.receiveAsFlow()
fun onContinue() {
state.update { it.copy(displayName = it.displayName.trim()) }
val displayName = state.value.displayName
when {
displayName.isEmpty() -> { state.update { it.copy(error = R.string.activity_display_name_display_name_missing_error) } }
displayName.length > NAME_PADDED_LENGTH -> { state.update { it.copy(error = R.string.activity_display_name_display_name_too_long_error) } }
else -> {
prefs.setProfileName(displayName)
viewModelScope.launch { event.send(Event.DONE) }
}
}
}
fun onChange(value: String) {
state.update {
it.copy(
displayName = value,
error = value.takeIf { it.length > NAME_PADDED_LENGTH }?.let { R.string.activity_display_name_display_name_too_long_error }
)
}
}
}
data class State(
@StringRes val title: Int = R.string.activity_display_name_title_2,
@StringRes val description: Int = R.string.activity_display_name_explanation,
@StringRes val error: Int? = null,
val displayName: String = ""
)
sealed interface Event {
object DONE: Event
}

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.ui
import androidx.annotation.DrawableRes
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box
@ -17,11 +18,13 @@ import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ButtonColors
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Card
import androidx.compose.material.Colors
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
@ -34,7 +37,6 @@ import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
@ -45,6 +47,22 @@ import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.components.ProfilePictureView
import kotlin.math.roundToInt
@Composable
fun OutlineButton(text: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
OutlinedButton(
modifier = modifier.size(108.dp, 34.dp),
onClick = onClick,
border = BorderStroke(1.dp, LocalExtraColors.current.prominentButtonColor),
shape = RoundedCornerShape(50), // = 50% percent
colors = ButtonDefaults.outlinedButtonColors(
contentColor = LocalExtraColors.current.prominentButtonColor,
backgroundColor = MaterialTheme.colors.background
)
){
Text(text = text)
}
}
@Composable
fun ItemButton(
text: String,

View File

@ -30,6 +30,7 @@ val LocalExtraColors = staticCompositionLocalOf<ExtraColors> { error("No Custom
data class ExtraColors(
val settingsBackground: Color,
val prominentButtonColor: Color
)
/**
@ -42,6 +43,7 @@ fun AppTheme(
val extraColors = LocalContext.current.run {
ExtraColors(
settingsBackground = getColorFromTheme(R.attr.colorSettingsBackground),
prominentButtonColor = getColorFromTheme(R.attr.prominentButtonColor),
)
}
@ -98,6 +100,7 @@ val sessionTypography = Typography(
)
val Typography.base get() = defaultStyle(14.sp)
val Typography.baseBold get() = boldStyle(14.sp)
val Typography.small get() = defaultStyle(12.sp)
val Typography.h7 get() = boldStyle(18.sp)

View File

@ -728,7 +728,7 @@
<string name="activity_restore_explanation">Enter the recovery phrase that was given to you when you signed up to restore your account.</string>
<string name="activity_restore_seed_edit_text_hint">Enter your recovery phrase</string>
<string name="activity_display_name_title_2">Pick your display name</string>
<string name="activity_display_name_explanation">This will be your name when you use Session. It can be your real name, an alias, or anything else you like.</string>
<string name="activity_display_name_explanation">It can be your real name, an alias, or anything else you like — and you can change it any time.</string>
<string name="activity_display_name_edit_text_hint">Enter a display name</string>
<string name="activity_display_name_display_name_missing_error">Please pick a display name</string>
<string name="activity_display_name_display_name_too_long_error">Please pick a shorter display name</string>

View File

@ -58,6 +58,7 @@
<item name="prominentButtonColor">?colorAccent</item>
<item name="attachment_document_icon_small">@drawable/ic_document_small_dark</item>
<item name="attachment_document_icon_large">@drawable/ic_document_large_dark</item>
<item name="colorError">@color/destructive</item>
</style>
<!-- This should be the default theme for the application. -->

View File

@ -11,7 +11,7 @@ buildscript {
}
dependencies {
classpath "com.android.tools.build:gradle:$gradlePluginVersion"
classpath 'com.android.tools.build:gradle:7.4.2'
classpath files('libs/gradle-witness.jar')
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion"
@ -77,6 +77,6 @@ allprojects {
project.ext {
androidMinimumSdkVersion = 23
androidTargetSdkVersion = 33
androidCompileSdkVersion = 33
androidCompileSdkVersion = 34
}
}

View File

@ -13,7 +13,6 @@
#Mon Jun 26 09:56:43 AEST 2023
android.enableJetifier=true
gradlePluginVersion=7.3.1
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
org.gradle.unsafe.configuration-cache=true

View File

@ -1,6 +1,6 @@
#Thu Dec 30 07:09:53 SAST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME