feat: v0.2.0 — sincronização do botão garantida, SSE em tempo real, WYSIWYG/Preview e lista rica
Sync (bug do celular real): - mudanças só de metadados (título/formato/categorias) entram na fila - auto-reconciliação: toda rodada enfileira notas sujas sem entrada na fila - re-enfileira update se o usuário digitou durante o push - sync no ON_RESUME; botão Sincronizar com spinner no lugar do ícone Tempo real (SSE): - SseClient (OkHttp, Dispatchers.IO, backoff) consome /api/events com Bearer - saved: nota limpa recarrega sozinha (editor aberto incluído, com rekey por meta), nota suja mostra banner Recarregar/Manter; snackbar na lista - presence: 👥N na lista/editor quando outra sessão (web ou app) abre a mesma nota - SessionId único por instalação, enviado em presence e ecoado nos saves Editor moderno (WebView nativo, sem deps novas): - modos Editar / WYSIWYG / Preview; WYSIWYG = contenteditable com serializador html→md em JS na página-asset + ponte @JavascriptInterface (tudo na main thread) - toolbar Markdown no modo texto (wrap/prefix seleção) e execCommand no WYSIWYG - Preview renderiza md via /api/render; links não navegam fora do app - lista: MediumTopAppBar, chips de filtro (categoria com caminho da árvore e tags), cards com status ☁/●/🗑/ e 👥, FAB estendido; telas em Material 3 dynamic color Testado no emulador Android 15: título-only sync ✅, SSE ao vivo ✅, WYSIWYG→servidor ✅, 👥 presença ✅, conflito 409 com cópia única ✅
This commit is contained in:
1 parent
9e0bcc3e9b
commit
61d4abebbd
12 files changed
+1096
-154
No files matched your search
@@ -20,9 +20,11 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.LifecycleEventEffect
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import com.labexposed.notas.domain.SyncPhase
|
||||
import com.labexposed.notas.domain.SyncUiState
|
||||
import com.labexposed.notas.ui.EditorScreen
|
||||
@@ -45,6 +47,9 @@ private fun NotasApp_(vm: NotasViewModel = viewModel()) {
|
||||
val nav = rememberNavController()
|
||||
val settings by vm.settings.collectAsState()
|
||||
|
||||
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) { vm.onResumed() }
|
||||
LifecycleEventEffect(Lifecycle.Event.ON_PAUSE) { vm.onPaused() }
|
||||
|
||||
NavHost(navController = nav, startDestination = if (settings.configured) "list" else "settings") {
|
||||
composable("settings") {
|
||||
SettingsScreen(vm, onDone = { nav.navigate("list") { popUpTo("settings") { inclusive = true } } })
|
||||
|
||||
Reference in new issue
Block a user