1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-2149 Networking | Enhancement | New network settings layouts + navigation (#859)

This commit is contained in:
Evgenii Kozlov 2024-02-14 13:54:35 +01:00 committed by GitHub
parent c163c67312
commit 155cbdc027
Signed by: github
GPG key ID: B5690EEEBB952194
14 changed files with 363 additions and 9 deletions

View file

@ -521,6 +521,10 @@ class OnboardingFragment : Fragment() {
Timber.e(e, "Error while opening terms of use")
}
}
SideEffect.OpenNetworkSettings -> {
val dialog = OnboardingNetworkSetupDialog()
dialog.show(childFragmentManager, "")
}
}
}
}

View file

@ -0,0 +1,51 @@
package com.anytypeio.anytype.ui.onboarding
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.material.MaterialTheme
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.NetworkModeConfig
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetComposeFragment
import com.anytypeio.anytype.ui.onboarding.screens.signin.NetworkSetupScreen
import com.anytypeio.anytype.ui.settings.typography
class OnboardingNetworkSetupDialog : BaseBottomSheetComposeFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.NetworkSettingDialogTheme)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
MaterialTheme(
typography = typography
) {
NetworkSetupScreen(
config = NetworkModeConfig(),
onSelfHostNetworkClicked = {
// TODO
},
onSetSelfHostConfigConfigClicked = {
// TODO
},
onLocalOnlyClicked = {
// TODO
},
onAnytypeNetworkClicked = {
// TODO
}
)
}
}
}
}

View file

@ -1,6 +1,7 @@
package com.anytypeio.anytype.ui.onboarding.screens
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -44,7 +45,8 @@ fun AuthScreenPreview() {
onLoginClicked = {},
onJoinClicked = {},
onPrivacyPolicyClicked = {},
onTermsOfUseClicked = {}
onTermsOfUseClicked = {},
onSettingsClicked = {}
)
}
@ -56,7 +58,8 @@ fun AuthScreenWrapper(
onJoinClicked = vm::onJoinClicked,
onLoginClicked = vm::onLoginClicked,
onPrivacyPolicyClicked = vm::onPrivacyPolicyClicked,
onTermsOfUseClicked = vm::onTermsOfUseClicked
onTermsOfUseClicked = vm::onTermsOfUseClicked,
onSettingsClicked = vm::onSettingsClicked
)
}
@ -65,7 +68,8 @@ fun AuthScreen(
onJoinClicked: () -> Unit,
onLoginClicked: () -> Unit,
onPrivacyPolicyClicked: () -> Unit,
onTermsOfUseClicked: () -> Unit
onTermsOfUseClicked: () -> Unit,
onSettingsClicked: () -> Unit
) {
Box(
modifier = Modifier.fillMaxSize()
@ -90,6 +94,14 @@ fun AuthScreen(
onTermsOfUseClicked = onTermsOfUseClicked
)
}
Image(
painter = painterResource(id = R.drawable.ic_onboarding_settings),
contentDescription = "Onboarding settings",
modifier = Modifier
.align(Alignment.TopEnd)
.padding(top = 8.dp, end = 16.dp)
.clickable { onSettingsClicked() }
)
}
}

View file

@ -0,0 +1,226 @@
package com.anytypeio.anytype.ui.onboarding.screens.signin
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.NetworkMode
import com.anytypeio.anytype.core_models.NetworkModeConfig
import com.anytypeio.anytype.core_ui.NetworkSettingCardColor
import com.anytypeio.anytype.core_ui.NetworkSettingDescriptionColor
import com.anytypeio.anytype.core_ui.NetworkSettingTitleColor
import com.anytypeio.anytype.core_ui.foundation.Divider
import com.anytypeio.anytype.core_ui.foundation.Dragger
import com.anytypeio.anytype.core_ui.foundation.Toolbar
import com.anytypeio.anytype.core_ui.views.BodyCalloutRegular
import com.anytypeio.anytype.ui.spaces.Section
@Preview
@Composable
fun DefaultNetworkSetupScreenPreview() {
NetworkSetupScreen(
config = NetworkModeConfig(
networkMode = NetworkMode.DEFAULT,
userFilePath = null,
storedFilePath = null
),
onAnytypeNetworkClicked = {},
onLocalOnlyClicked = {},
onSelfHostNetworkClicked = {},
onSetSelfHostConfigConfigClicked = {}
)
}
@Preview
@Composable
fun SelfHostNetworkSetupScreenPreview() {
NetworkSetupScreen(
config = NetworkModeConfig(
networkMode = NetworkMode.CUSTOM,
userFilePath = null,
storedFilePath = null
),
onAnytypeNetworkClicked = {},
onLocalOnlyClicked = {},
onSelfHostNetworkClicked = {},
onSetSelfHostConfigConfigClicked = {}
)
}
@Preview
@Composable
fun SelfHostNetworkWithPathSetupScreenPreview() {
NetworkSetupScreen(
config = NetworkModeConfig(
networkMode = NetworkMode.CUSTOM,
userFilePath = null,
storedFilePath = null
),
onAnytypeNetworkClicked = {},
onLocalOnlyClicked = {},
onSelfHostNetworkClicked = {},
onSetSelfHostConfigConfigClicked = {}
)
}
@Preview
@Composable
fun LocalNetworkWithPathSetupScreenPreview() {
NetworkSetupScreen(
config = NetworkModeConfig(
networkMode = NetworkMode.LOCAL,
userFilePath = null,
storedFilePath = null
),
onAnytypeNetworkClicked = {},
onLocalOnlyClicked = {},
onSelfHostNetworkClicked = {},
onSetSelfHostConfigConfigClicked = {}
)
}
@Composable
fun NetworkSetupScreen(
config: NetworkModeConfig,
onLocalOnlyClicked: () -> Unit,
onAnytypeNetworkClicked: () -> Unit,
onSelfHostNetworkClicked: () -> Unit,
onSetSelfHostConfigConfigClicked: () -> Unit
) {
Column(
modifier = Modifier
.padding(horizontal = 20.dp)
.verticalScroll(rememberScrollState())
) {
Dragger(
modifier = Modifier
.padding(vertical = 6.dp)
.align(Alignment.CenterHorizontally),
color = Color(0xffE3E3E3)
)
Toolbar(
title = stringResource(id = R.string.network),
color = colorResource(id = R.color.text_white)
)
Column(
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(color = NetworkSettingCardColor)
.fillMaxWidth()
.padding(horizontal = 20.dp)
) {
Spacer(modifier = Modifier.height(14.dp))
Row(
modifier = Modifier.padding(),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(id = R.string.network_settings_anytype_network),
style = BodyCalloutRegular,
color = NetworkSettingTitleColor,
modifier = Modifier.weight(1.0f)
)
if (config.networkMode == NetworkMode.DEFAULT) {
Image(
painter = painterResource(id = R.drawable.ic_network_settings_checked),
contentDescription = "Check icon"
)
}
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = stringResource(id = R.string.network_settings_anytype_network_description),
style = BodyCalloutRegular,
color = NetworkSettingDescriptionColor
)
Spacer(modifier = Modifier.height(14.dp))
}
Section(
title = stringResource(id = R.string.network_settings_networks_section),
color = NetworkSettingDescriptionColor
)
Column(
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.fillMaxWidth()
.background(color = NetworkSettingCardColor)
) {
Spacer(modifier = Modifier.height(14.dp))
Row(
modifier = Modifier.padding(horizontal = 20.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(id = R.string.network_settings_self_host),
style = BodyCalloutRegular,
color = NetworkSettingTitleColor,
modifier = Modifier.weight(1.0f)
)
if (config.networkMode == NetworkMode.CUSTOM) {
Image(
painter = painterResource(id = R.drawable.ic_network_settings_checked),
contentDescription = "Check icon"
)
}
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = stringResource(id = R.string.network_settings_self_host_description),
style = BodyCalloutRegular,
color = NetworkSettingDescriptionColor,
modifier = Modifier.padding(horizontal = 20.dp)
)
Spacer(modifier = Modifier.height(14.dp))
Divider(
paddingStart = 20.dp,
paddingEnd = 0.dp
)
Spacer(modifier = Modifier.height(14.dp))
Row(
modifier = Modifier.padding(horizontal = 20.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(id = R.string.network_settings_local_only),
style = BodyCalloutRegular,
color = NetworkSettingTitleColor,
modifier = Modifier.weight(1.0f)
)
if (config.networkMode == NetworkMode.LOCAL) {
Image(
painter = painterResource(id = R.drawable.ic_network_settings_checked),
contentDescription = "Check icon"
)
}
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = stringResource(id = R.string.network_settings_local_only_description),
style = BodyCalloutRegular,
color = NetworkSettingDescriptionColor,
modifier = Modifier.padding(horizontal = 20.dp)
)
Spacer(modifier = Modifier.height(14.dp))
}
Spacer(modifier = Modifier.height(24.dp))
}
}

View file

@ -255,7 +255,8 @@ fun SpaceNameInput(
@Composable
fun Section(
title: String
title: String,
color: Color = colorResource(id = R.color.text_secondary)
) {
Box(modifier = Modifier
.height(52.dp)
@ -268,7 +269,7 @@ fun Section(
)
.align(Alignment.BottomStart),
text = title,
color = colorResource(id = R.color.text_secondary),
color = color,
style = Caption1Regular
)
}

View file

@ -2,6 +2,10 @@ package com.anytypeio.anytype.core_ui
import androidx.compose.ui.graphics.Color
val NetworkSettingTitleColor = Color(0xFFD4D4D4)
val NetworkSettingDescriptionColor = Color(0xFF949494)
val NetworkSettingCardColor = Color(0xff252525)
val OnboardingSubtitleColor = Color(0xFF505050)
val OnBoardingTextPrimaryColor = Color(0xFFF3F2EC)

View file

@ -38,7 +38,10 @@ import com.anytypeio.anytype.core_ui.views.HeadlineHeading
import com.anytypeio.anytype.core_ui.views.Title1
@Composable
fun Toolbar(title: String) {
fun Toolbar(
title: String,
color: Color = colorResource(R.color.text_primary)
) {
Box(
Modifier
.fillMaxWidth()
@ -48,7 +51,7 @@ fun Toolbar(title: String) {
Text(
text = title,
style = Title1,
color = colorResource(R.color.text_primary)
color = color
)
}
}

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M18.632,6.403L11.13,18.192L5.469,12.531L6.529,11.47L10.868,15.809L17.366,5.598L18.632,6.403Z"
android:fillColor="#D4D4D4"
android:fillType="evenOdd"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M15.25,5.75C15.25,5.336 15.586,5 16,5C16.414,5 16.75,5.336 16.75,5.75V7.533C17.755,7.621 18.711,7.883 19.585,8.291L20.476,6.748C20.683,6.39 21.141,6.267 21.5,6.474C21.796,6.645 21.932,6.988 21.853,7.304C21.837,7.371 21.81,7.436 21.774,7.499L20.883,9.042C21.689,9.608 22.392,10.311 22.958,11.117L24.502,10.225C24.861,10.018 25.319,10.141 25.526,10.5C25.733,10.859 25.611,11.317 25.252,11.524L23.709,12.415C24.117,13.289 24.379,14.245 24.467,15.25H26.25C26.664,15.25 27,15.586 27,16C27,16.414 26.664,16.75 26.25,16.75H24.467C24.379,17.755 24.117,18.711 23.709,19.585L25.252,20.476C25.611,20.683 25.733,21.141 25.526,21.5C25.319,21.859 24.861,21.982 24.502,21.775L22.958,20.883C22.392,21.689 21.689,22.392 20.883,22.958L21.774,24.502C21.852,24.636 21.883,24.785 21.873,24.929C21.86,25.115 21.778,25.293 21.637,25.425C21.596,25.463 21.551,25.497 21.5,25.526C21.141,25.733 20.683,25.61 20.476,25.252L19.585,23.709C18.711,24.117 17.755,24.379 16.75,24.467V26.25C16.75,26.664 16.414,27 16,27C15.586,27 15.25,26.664 15.25,26.25V24.467C14.245,24.379 13.29,24.117 12.415,23.709L11.524,25.252C11.317,25.611 10.859,25.733 10.5,25.526C10.141,25.319 10.018,24.861 10.226,24.502L11.117,22.958C10.311,22.392 9.608,21.689 9.042,20.883L7.498,21.774C7.139,21.982 6.681,21.859 6.474,21.5C6.267,21.141 6.389,20.683 6.748,20.475L8.291,19.585C7.883,18.711 7.621,17.755 7.533,16.75H5.75C5.724,16.75 5.699,16.749 5.673,16.746C5.295,16.708 5,16.388 5,16C5,15.586 5.336,15.25 5.75,15.25H7.533C7.621,14.245 7.883,13.29 8.291,12.415L6.748,11.525C6.389,11.318 6.267,10.859 6.474,10.5C6.681,10.141 7.139,10.019 7.498,10.226L9.042,11.117C9.608,10.311 10.311,9.608 11.117,9.042L10.226,7.498C10.018,7.139 10.141,6.681 10.5,6.474C10.859,6.267 11.317,6.389 11.524,6.748L12.415,8.291C13.29,7.883 14.245,7.621 15.25,7.533V5.75ZM9.04,16.75C9.414,20.263 12.387,23 16,23C17.008,23 17.966,22.787 18.831,22.404L15.567,16.75H9.04ZM15.567,15.25H9.04C9.414,11.737 12.387,9 16,9C17.008,9 17.966,9.213 18.831,9.596L15.567,15.25ZM20.13,21.653L16.866,16L20.13,10.347C21.87,11.621 23,13.678 23,16C23,18.322 21.87,20.379 20.13,21.653Z"
android:fillColor="#7B7A72"
android:fillType="evenOdd"/>
</vector>

View file

@ -49,10 +49,23 @@
<item name="colorAccent">@color/orange</item>
</style>
<style name="NetworkSettingDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">@style/NetworkSettingModalStyle</item>
<item name="android:windowIsFloating">false</item>
<item name="android:background">@android:color/transparent</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
<item name="colorAccent">@color/orange</item>
</style>
<style name="SelectSpaceModalStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/rounded_dialog_select_spaces</item>
</style>
<style name="NetworkSettingModalStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/rounded_dialog_network_settings</item>
</style>
<style name="AppBottomSecondarySheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">@style/AppModalStyleSecondary</item>
<item name="android:windowIsFloating">false</item>

View file

@ -1279,6 +1279,15 @@
<!--region ONBOARDING ERRORS -->
<string name="error_invalid_recovery_phrase">Invalid recovery phrase</string>
<string name="network">Network</string>
<string name="network_settings_anytype_network">Anytype network</string>
<string name="network_settings_anytype_network_description">Backup to the network managed by Anytype</string>
<string name="network_settings_local_only">Local-only</string>
<string name="network_settings_local_only_description">Don\'t back up; sync within local network</string>
<string name="network_settings_self_host">Self-hosted</string>
<string name="network_settings_self_host_description">Back up to your self-hosted network</string>
<string name="network_settings_networks_section">Networks</string>
<!--endregion-->

View file

@ -13,6 +13,7 @@ import com.anytypeio.anytype.persistence.networkmode.DefaultNetworkModeProvider.
interface NetworkModeProvider {
fun set(networkModeConfig: NetworkModeConfig)
fun get(): NetworkModeConfig
fun clear()
}
class DefaultNetworkModeProvider(private val sharedPreferences: SharedPreferences) :
@ -60,6 +61,10 @@ class DefaultNetworkModeProvider(private val sharedPreferences: SharedPreference
}
}
override fun clear() {
// TODO?
}
object NetworkModeConstants {
const val NETWORK_MODE_PREF = "pref.network_mode"
const val NETWORK_MODE_APP_FILE_PATH_PREF = "pref.network_config_file_path"

View file

@ -42,6 +42,10 @@ class OnboardingStartViewModel @Inject constructor(
viewModelScope.launch { sideEffects.emit(SideEffect.OpenTermsOfUse) }
}
fun onSettingsClicked() {
viewModelScope.launch { sideEffects.emit(SideEffect.OpenNetworkSettings) }
}
private fun navigateTo(destination: AuthNavigation) {
viewModelScope.launch {
navigation.emit(destination)
@ -60,6 +64,7 @@ class OnboardingStartViewModel @Inject constructor(
sealed class SideEffect {
object OpenPrivacyPolicy : SideEffect()
object OpenTermsOfUse : SideEffect()
object OpenNetworkSettings : SideEffect()
}
class Factory @Inject constructor(

View file

@ -358,7 +358,8 @@ class TagOrStatusValueViewModel(
success = {
dispatcher.send(it)
sendAnalyticsRelationValueEvent(analytics)
})
}
)
}
}
@ -515,5 +516,5 @@ sealed class RelationsListItem {
}
}
const val SUB_MY_OPTIONS = "subscription.relation_options"
const val SUB_MY_OPTIONS = "subscription.relation-options"
const val DELAY_UNTIL_CLOSE = 300L