mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-2780 Sync status | Need update status (#1530)
This commit is contained in:
parent
c6fb926fe2
commit
e064007837
14 changed files with 153 additions and 17 deletions
|
@ -99,6 +99,7 @@ import com.anytypeio.anytype.core_utils.ext.lastDecorator
|
|||
import com.anytypeio.anytype.core_utils.ext.safeNavigate
|
||||
import com.anytypeio.anytype.core_utils.ext.screen
|
||||
import com.anytypeio.anytype.core_utils.ext.show
|
||||
import com.anytypeio.anytype.core_utils.ext.startMarketPageOrWeb
|
||||
import com.anytypeio.anytype.core_utils.ext.subscribe
|
||||
import com.anytypeio.anytype.core_utils.ext.syncTranslationWithImeVisibility
|
||||
import com.anytypeio.anytype.core_utils.ext.throttleFirst
|
||||
|
@ -745,7 +746,8 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
SpaceSyncStatusScreen(
|
||||
uiState = vm.syncStatusWidget.collectAsStateWithLifecycle().value,
|
||||
onDismiss = vm::onSyncWidgetDismiss,
|
||||
scope = lifecycleScope
|
||||
scope = lifecycleScope,
|
||||
onUpdateAppClick = vm::onUpdateAppClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -949,6 +951,9 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
toast("Couldn't parse url: ${command.url}")
|
||||
}
|
||||
}
|
||||
is Command.OpenAppStore -> {
|
||||
startMarketPageOrWeb()
|
||||
}
|
||||
is Command.OpenDocumentMenu -> {
|
||||
hideKeyboard()
|
||||
runCatching {
|
||||
|
|
|
@ -78,6 +78,7 @@ import com.anytypeio.anytype.core_utils.ext.hideKeyboard
|
|||
import com.anytypeio.anytype.core_utils.ext.hideSoftInput
|
||||
import com.anytypeio.anytype.core_utils.ext.invisible
|
||||
import com.anytypeio.anytype.core_utils.ext.safeNavigate
|
||||
import com.anytypeio.anytype.core_utils.ext.startMarketPageOrWeb
|
||||
import com.anytypeio.anytype.core_utils.ext.subscribe
|
||||
import com.anytypeio.anytype.core_utils.ext.syncFocusWithImeVisibility
|
||||
import com.anytypeio.anytype.core_utils.ext.syncTranslationWithImeVisibility
|
||||
|
@ -452,7 +453,8 @@ open class ObjectSetFragment :
|
|||
SpaceSyncStatusScreen(
|
||||
uiState = vm.syncStatusWidget.collectAsStateWithLifecycle().value,
|
||||
onDismiss = vm::onSyncWidgetDismiss,
|
||||
scope = lifecycleScope
|
||||
scope = lifecycleScope,
|
||||
onUpdateAppClick = vm::onUpdateAppClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1228,6 +1230,9 @@ open class ObjectSetFragment :
|
|||
getString(R.string.multiplayer_read_only_access_error)
|
||||
)
|
||||
}
|
||||
ObjectSetCommand.Intent.OpenAppStore -> {
|
||||
startMarketPageOrWeb()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@ import androidx.compose.animation.AnimatedVisibility
|
|||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
@ -46,6 +48,7 @@ import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncStatus
|
|||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncUpdate
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.foundation.Divider
|
||||
import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
|
||||
import com.anytypeio.anytype.core_ui.views.BodyRegular
|
||||
import com.anytypeio.anytype.core_ui.views.Relations3
|
||||
import com.anytypeio.anytype.core_ui.views.Title2
|
||||
|
@ -60,7 +63,8 @@ import kotlinx.coroutines.launch
|
|||
fun SpaceSyncStatusScreen(
|
||||
uiState: SyncStatusWidgetState,
|
||||
onDismiss: () -> Unit,
|
||||
scope: CoroutineScope
|
||||
scope: CoroutineScope,
|
||||
onUpdateAppClick: () -> Unit
|
||||
) {
|
||||
val isVisible = uiState is SyncStatusWidgetState.Success || uiState is SyncStatusWidgetState.Error
|
||||
|
||||
|
@ -112,7 +116,8 @@ fun SpaceSyncStatusScreen(
|
|||
SyncStatusWidgetState.Hidden -> LoadingState()
|
||||
is SyncStatusWidgetState.Success -> SuccessState(
|
||||
spaceSyncUpdate = uiState.spaceSyncUpdate,
|
||||
p2pStatus = uiState.p2PStatusUpdate
|
||||
p2pStatus = uiState.p2PStatusUpdate,
|
||||
onUpdateAppClick = onUpdateAppClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -145,9 +150,13 @@ private fun ColumnScope.ErrorState() {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun SuccessState(spaceSyncUpdate: SpaceSyncUpdate, p2pStatus: P2PStatusUpdate) {
|
||||
private fun SuccessState(
|
||||
spaceSyncUpdate: SpaceSyncUpdate,
|
||||
p2pStatus: P2PStatusUpdate,
|
||||
onUpdateAppClick: () -> Unit
|
||||
) {
|
||||
if (spaceSyncUpdate is SpaceSyncUpdate.Update) {
|
||||
SpaceSyncStatusItem(spaceSyncUpdate)
|
||||
SpaceSyncStatusItem(spaceSyncUpdate, onUpdateAppClick)
|
||||
Divider()
|
||||
}
|
||||
if (p2pStatus is P2PStatusUpdate.Update) {
|
||||
|
@ -197,7 +206,8 @@ private fun P2PStatusItem(
|
|||
|
||||
@Composable
|
||||
private fun SpaceSyncStatusItem(
|
||||
spaceSyncUpdate: SpaceSyncUpdate.Update
|
||||
spaceSyncUpdate: SpaceSyncUpdate.Update,
|
||||
onUpdateAppClick: () -> Unit = {}
|
||||
) {
|
||||
val networkCardSettings = getNetworkCardSettings(
|
||||
syncStatus = spaceSyncUpdate.status,
|
||||
|
@ -205,15 +215,21 @@ private fun SpaceSyncStatusItem(
|
|||
error = spaceSyncUpdate.error,
|
||||
syncingObjectsCounter = spaceSyncUpdate.syncingObjectsCounter
|
||||
)
|
||||
Row(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(72.dp)
|
||||
.padding(horizontal = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
.noRippleClickable {
|
||||
if (spaceSyncUpdate.status == SpaceSyncStatus.NETWORK_UPDATE_NEEDED) {
|
||||
onUpdateAppClick()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier.wrapContentSize(),
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.padding(start = 16.dp)
|
||||
.align(Alignment.CenterStart),
|
||||
painter = networkCardSettings.icon,
|
||||
contentDescription = "dfas",
|
||||
alpha = networkCardSettings.alpha
|
||||
|
@ -221,7 +237,8 @@ private fun SpaceSyncStatusItem(
|
|||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 12.dp)
|
||||
.padding(start = 76.dp)
|
||||
.align(Alignment.CenterStart)
|
||||
) {
|
||||
Text(
|
||||
text = networkCardSettings.mainText,
|
||||
|
@ -236,6 +253,16 @@ private fun SpaceSyncStatusItem(
|
|||
)
|
||||
}
|
||||
}
|
||||
if (spaceSyncUpdate.status == SpaceSyncStatus.NETWORK_UPDATE_NEEDED) {
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.padding(end = 20.dp)
|
||||
.wrapContentSize()
|
||||
.align(Alignment.CenterEnd),
|
||||
painter = painterResource(id = R.drawable.ic_arrow_top_end),
|
||||
contentDescription = "update app icon"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,7 +345,11 @@ private fun getNetworkCardSettings(
|
|||
)
|
||||
}
|
||||
SpaceSyncStatus.NETWORK_UPDATE_NEEDED -> {
|
||||
TODO()
|
||||
CardSettings(
|
||||
icon = painterResource(R.drawable.ic_sync_limitations),
|
||||
mainText = stringResource(id = R.string.sync_status_anytype_network),
|
||||
secondaryText = stringResource(id = R.string.sync_status_anytype_sync_slow)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,7 +393,13 @@ private fun getNetworkCardSettings(
|
|||
secondaryText = stringResource(id = R.string.sync_status_anytype_network_no_connecting)
|
||||
)
|
||||
}
|
||||
SpaceSyncStatus.NETWORK_UPDATE_NEEDED -> TODO()
|
||||
SpaceSyncStatus.NETWORK_UPDATE_NEEDED -> {
|
||||
CardSettings(
|
||||
icon = painterResource(R.drawable.ic_sync_limitations),
|
||||
mainText = stringResource(id = R.string.sync_status_self_host),
|
||||
secondaryText = stringResource(id = R.string.sync_status_anytype_sync_slow)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
SpaceSyncNetwork.LOCAL_ONLY -> {
|
||||
|
@ -540,4 +577,17 @@ fun SpaceSyncStatusPreview12() {
|
|||
spaceId = "1"
|
||||
)
|
||||
P2PStatusItem(p2pStatus = p2pStatus)
|
||||
}
|
||||
|
||||
@Preview(name = "AnytypeNetworkNeedUpdate", showBackground = true)
|
||||
@Composable
|
||||
fun SpaceSyncStatusPreview13() {
|
||||
val spaceSyncUpdate = SpaceSyncUpdate.Update(
|
||||
id = "1",
|
||||
status = SpaceSyncStatus.NETWORK_UPDATE_NEEDED,
|
||||
network = SpaceSyncNetwork.ANYTYPE,
|
||||
error = SpaceSyncError.NULL,
|
||||
syncingObjectsCounter = 0
|
||||
)
|
||||
SpaceSyncStatusItem(spaceSyncUpdate = spaceSyncUpdate)
|
||||
}
|
|
@ -52,7 +52,8 @@ class StatusBadgeWidget @JvmOverloads constructor(
|
|||
setImageResource(R.drawable.ic_sync_grey_10)
|
||||
}
|
||||
SpaceSyncStatus.NETWORK_UPDATE_NEEDED -> {
|
||||
// TODO
|
||||
visible()
|
||||
setImageResource(R.drawable.ic_sync_slow_10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
core-ui/src/main/res/drawable/ic_arrow_top_end.xml
Normal file
11
core-ui/src/main/res/drawable/ic_arrow_top_end.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="12dp"
|
||||
android:height="12dp"
|
||||
android:viewportWidth="12"
|
||||
android:viewportHeight="12">
|
||||
<path
|
||||
android:pathData="M3.5,1H11M11,1V8.5M11,1L1,11"
|
||||
android:strokeWidth="1.25"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="@color/glyph_active"/>
|
||||
</vector>
|
21
core-ui/src/main/res/drawable/ic_sync_limitations.xml
Normal file
21
core-ui/src/main/res/drawable/ic_sync_limitations.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:pathData="M24,0L24,0A24,24 0,0 1,48 24L48,24A24,24 0,0 1,24 48L24,48A24,24 0,0 1,0 24L0,24A24,24 0,0 1,24 0z"
|
||||
android:fillColor="@color/palette_light_yellow"/>
|
||||
<path
|
||||
android:pathData="M20.5,16L20.5,16A0.5,0.5 0,0 1,21 16.5L21,19.5A0.5,0.5 0,0 1,20.5 20L20.5,20A0.5,0.5 0,0 1,20 19.5L20,16.5A0.5,0.5 0,0 1,20.5 16z"
|
||||
android:fillColor="@color/palette_dark_yellow"/>
|
||||
<path
|
||||
android:pathData="M27.5,16L27.5,16A0.5,0.5 0,0 1,28 16.5L28,19.5A0.5,0.5 0,0 1,27.5 20L27.5,20A0.5,0.5 0,0 1,27 19.5L27,16.5A0.5,0.5 0,0 1,27.5 16z"
|
||||
android:fillColor="@color/palette_dark_yellow"/>
|
||||
<path
|
||||
android:strokeWidth="1"
|
||||
android:pathData="M16,29H32"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="@color/palette_dark_yellow"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
9
core-ui/src/main/res/drawable/ic_sync_slow_10.xml
Normal file
9
core-ui/src/main/res/drawable/ic_sync_slow_10.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="10dp"
|
||||
android:height="10dp"
|
||||
android:viewportWidth="10"
|
||||
android:viewportHeight="10">
|
||||
<path
|
||||
android:pathData="M5,5m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-10 0"
|
||||
android:fillColor="@color/palette_system_yellow"/>
|
||||
</vector>
|
|
@ -1,8 +1,11 @@
|
|||
package com.anytypeio.anytype.core_utils.ext
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Parcelable
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.anytypeio.anytype.core_utils.R
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
@ -54,4 +57,22 @@ fun <T> CoroutineScope.subscribe(flow: Flow<T>, body: suspend (T) -> Unit): Job
|
|||
flow.cancellable().onEach { body(it) }.launchIn(this)
|
||||
|
||||
fun <T> Fragment.subscribe(flow: Flow<T>, body: (T) -> Unit): Job =
|
||||
flow.cancellable().onEach { body(it) }.launchIn(viewLifecycleOwner.lifecycleScope)
|
||||
flow.cancellable().onEach { body(it) }.launchIn(viewLifecycleOwner.lifecycleScope)
|
||||
|
||||
fun Fragment.startMarketPageOrWeb() {
|
||||
runCatching {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse("${getString(R.string.play_market_url)}${context?.packageName}")
|
||||
)
|
||||
)
|
||||
}.onFailure {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(getString(R.string.download_anytype_url))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
<resources>
|
||||
<string name="app_name">CoreUtils</string>
|
||||
<string name="download_anytype_url" translatable="false">https://download.anytype.io</string>
|
||||
<string name="play_market_url" translatable="false">market://details?id=</string>
|
||||
</resources>
|
||||
|
|
|
@ -916,7 +916,6 @@
|
|||
|
||||
<string name="anytype_update_alert_description">Some of your data was managed in a newer version of Anytype. Please update the app to work with all your docs and the latest features.</string>
|
||||
<string name="anytype_update_alert_title">It\'s time to update</string>
|
||||
<string name="download_anytype_url" translatable="false">https://download.anytype.io</string>
|
||||
|
||||
<string name="space_type_default">Entry</string>
|
||||
<string name="space_type_default_space">Entry space</string>
|
||||
|
@ -1734,6 +1733,7 @@ Please provide specific details of your needs here.</string>
|
|||
</plurals>
|
||||
<string name="sync_status_anytype_network_connecting">Network Connecting...</string>
|
||||
<string name="sync_status_anytype_network_no_connecting">No connection</string>
|
||||
<string name="sync_status_anytype_sync_slow">Sync might be slow. Update the app.</string>
|
||||
|
||||
<string name="sync_status_storage_limit_exceed">Storage limit reached</string>
|
||||
<string name="sync_status_incompatible_version">Incompatible version</string>
|
||||
|
|
|
@ -7413,6 +7413,10 @@ class EditorViewModel(
|
|||
fun onSyncWidgetDismiss() {
|
||||
syncStatusWidget.value = SyncStatusWidgetState.Hidden
|
||||
}
|
||||
|
||||
fun onUpdateAppClick() {
|
||||
dispatch(command = Command.OpenAppStore)
|
||||
}
|
||||
//endregion
|
||||
|
||||
data class Params(
|
||||
|
|
|
@ -57,6 +57,8 @@ sealed class Command {
|
|||
val url: Url
|
||||
) : Command()
|
||||
|
||||
data object OpenAppStore: Command()
|
||||
|
||||
data class OpenDocumentMenu(
|
||||
val ctx: Id,
|
||||
val space: Id,
|
||||
|
|
|
@ -115,6 +115,7 @@ sealed class ObjectSetCommand {
|
|||
data class GoTo(val url: String) : Intent()
|
||||
data class MailTo(val email: String) : Intent()
|
||||
data class Call(val phone: String) : Intent()
|
||||
data object OpenAppStore : Intent()
|
||||
}
|
||||
|
||||
data object ShowOnlyAccessError : ObjectSetCommand()
|
||||
|
|
|
@ -2865,6 +2865,10 @@ class ObjectSetViewModel(
|
|||
fun onSyncWidgetDismiss() {
|
||||
syncStatusWidget.value = SyncStatusWidgetState.Hidden
|
||||
}
|
||||
|
||||
fun onUpdateAppClick() {
|
||||
dispatch(command = ObjectSetCommand.Intent.OpenAppStore)
|
||||
}
|
||||
//endregion
|
||||
|
||||
companion object {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue