add local status
This commit is contained in:
+10
@@ -58,6 +58,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import com.vaultdrop.mobile.R
|
import com.vaultdrop.mobile.R
|
||||||
import com.vaultdrop.mobile.data.local.entity.FileEntity
|
import com.vaultdrop.mobile.data.local.entity.FileEntity
|
||||||
import com.vaultdrop.mobile.domain.FileCategory
|
import com.vaultdrop.mobile.domain.FileCategory
|
||||||
|
import com.vaultdrop.mobile.features.connection.ConnectionStatusViewModel
|
||||||
|
import com.vaultdrop.mobile.ui.components.ServerStatusBadge
|
||||||
import com.vaultdrop.mobile.ui.components.categoryValue
|
import com.vaultdrop.mobile.ui.components.categoryValue
|
||||||
import com.vaultdrop.mobile.ui.document.content.DocumentContentViewer
|
import com.vaultdrop.mobile.ui.document.content.DocumentContentViewer
|
||||||
import com.vaultdrop.mobile.ui.document.content.PdfFocusViewer
|
import com.vaultdrop.mobile.ui.document.content.PdfFocusViewer
|
||||||
@@ -81,9 +83,11 @@ import java.util.Locale
|
|||||||
fun DocumentViewerScreen(
|
fun DocumentViewerScreen(
|
||||||
initialResourceId: String,
|
initialResourceId: String,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
|
connectionStatusViewModel: ConnectionStatusViewModel,
|
||||||
viewModel: DocumentViewerViewModel = hiltViewModel(),
|
viewModel: DocumentViewerViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val documents by viewModel.documents.collectAsStateWithLifecycle()
|
val documents by viewModel.documents.collectAsStateWithLifecycle()
|
||||||
|
val connectionStatus by connectionStatusViewModel.status.collectAsStateWithLifecycle()
|
||||||
val pagerState = rememberPagerState(pageCount = { documents.size })
|
val pagerState = rememberPagerState(pageCount = { documents.size })
|
||||||
|
|
||||||
// Démarre une seule fois sur le document demandé, dès que la liste est chargée.
|
// Démarre une seule fois sur le document demandé, dès que la liste est chargée.
|
||||||
@@ -160,6 +164,12 @@ fun DocumentViewerScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
actions = {
|
||||||
|
ServerStatusBadge(
|
||||||
|
status = connectionStatus,
|
||||||
|
onClick = connectionStatusViewModel::checkNow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
+8
@@ -37,7 +37,9 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import com.vaultdrop.mobile.R
|
import com.vaultdrop.mobile.R
|
||||||
import com.vaultdrop.mobile.data.local.entity.FileEntity
|
import com.vaultdrop.mobile.data.local.entity.FileEntity
|
||||||
import com.vaultdrop.mobile.data.local.entity.FolderEntity
|
import com.vaultdrop.mobile.data.local.entity.FolderEntity
|
||||||
|
import com.vaultdrop.mobile.features.connection.ConnectionStatusViewModel
|
||||||
import com.vaultdrop.mobile.ui.components.FileCategoryIcon
|
import com.vaultdrop.mobile.ui.components.FileCategoryIcon
|
||||||
|
import com.vaultdrop.mobile.ui.components.ServerStatusBadge
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@@ -47,9 +49,11 @@ fun FolderDetailScreen(
|
|||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onOpenFolder: (String) -> Unit,
|
onOpenFolder: (String) -> Unit,
|
||||||
onOpenDocument: (String) -> Unit,
|
onOpenDocument: (String) -> Unit,
|
||||||
|
connectionStatusViewModel: ConnectionStatusViewModel,
|
||||||
viewModel: FolderDetailViewModel = hiltViewModel(),
|
viewModel: FolderDetailViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
val connectionStatus by connectionStatusViewModel.status.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LaunchedEffect(uiState.folderMissing) {
|
LaunchedEffect(uiState.folderMissing) {
|
||||||
if (uiState.folderMissing) onBack()
|
if (uiState.folderMissing) onBack()
|
||||||
@@ -68,6 +72,10 @@ fun FolderDetailScreen(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
|
ServerStatusBadge(
|
||||||
|
status = connectionStatus,
|
||||||
|
onClick = connectionStatusViewModel::checkNow,
|
||||||
|
)
|
||||||
IconButton(onClick = viewModel::refresh) {
|
IconButton(onClick = viewModel::refresh) {
|
||||||
Icon(Icons.Filled.Refresh, contentDescription = stringResource(R.string.refresh))
|
Icon(Icons.Filled.Refresh, contentDescription = stringResource(R.string.refresh))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,8 +49,10 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vaultdrop.mobile.R
|
import com.vaultdrop.mobile.R
|
||||||
import com.vaultdrop.mobile.data.local.entity.FileEntity
|
import com.vaultdrop.mobile.data.local.entity.FileEntity
|
||||||
|
import com.vaultdrop.mobile.features.connection.ConnectionStatusViewModel
|
||||||
import com.vaultdrop.mobile.features.sync.SyncViewModel
|
import com.vaultdrop.mobile.features.sync.SyncViewModel
|
||||||
import com.vaultdrop.mobile.ui.components.FileCategoryIcon
|
import com.vaultdrop.mobile.ui.components.FileCategoryIcon
|
||||||
|
import com.vaultdrop.mobile.ui.components.ServerStatusBadge
|
||||||
import com.vaultdrop.mobile.ui.navigation.FloatingNavBar
|
import com.vaultdrop.mobile.ui.navigation.FloatingNavBar
|
||||||
import com.vaultdrop.mobile.ui.navigation.NavTab
|
import com.vaultdrop.mobile.ui.navigation.NavTab
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@@ -62,10 +64,12 @@ fun FolderListScreen(
|
|||||||
onTabSelected: (NavTab) -> Unit,
|
onTabSelected: (NavTab) -> Unit,
|
||||||
onOpenDocument: (String) -> Unit,
|
onOpenDocument: (String) -> Unit,
|
||||||
syncViewModel: SyncViewModel,
|
syncViewModel: SyncViewModel,
|
||||||
|
connectionStatusViewModel: ConnectionStatusViewModel,
|
||||||
viewModel: FolderListViewModel = hiltViewModel(),
|
viewModel: FolderListViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
val importState by syncViewModel.importState.collectAsStateWithLifecycle()
|
val importState by syncViewModel.importState.collectAsStateWithLifecycle()
|
||||||
|
val connectionStatus by connectionStatusViewModel.status.collectAsStateWithLifecycle()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val folderLabel = stringResource(R.string.folder)
|
val folderLabel = stringResource(R.string.folder)
|
||||||
|
|
||||||
@@ -91,6 +95,10 @@ fun FolderListScreen(
|
|||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text(stringResource(R.string.files)) },
|
title = { Text(stringResource(R.string.files)) },
|
||||||
actions = {
|
actions = {
|
||||||
|
ServerStatusBadge(
|
||||||
|
status = connectionStatus,
|
||||||
|
onClick = connectionStatusViewModel::checkNow,
|
||||||
|
)
|
||||||
IconButton(onClick = viewModel::refresh) {
|
IconButton(onClick = viewModel::refresh) {
|
||||||
Icon(Icons.Filled.Refresh, contentDescription = stringResource(R.string.refresh))
|
Icon(Icons.Filled.Refresh, contentDescription = stringResource(R.string.refresh))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import androidx.navigation.compose.currentBackStackEntryAsState
|
|||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import androidx.navigation.navArgument
|
import androidx.navigation.navArgument
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.vaultdrop.mobile.features.connection.ConnectionStatusViewModel
|
||||||
import com.vaultdrop.mobile.features.sync.SyncViewModel
|
import com.vaultdrop.mobile.features.sync.SyncViewModel
|
||||||
import com.vaultdrop.mobile.ui.auth.AuthViewModel
|
import com.vaultdrop.mobile.ui.auth.AuthViewModel
|
||||||
import com.vaultdrop.mobile.ui.document.DocumentViewerScreen
|
import com.vaultdrop.mobile.ui.document.DocumentViewerScreen
|
||||||
@@ -47,6 +48,7 @@ private fun String?.toNavTab(): NavTab = when (this) {
|
|||||||
fun NavGraph(
|
fun NavGraph(
|
||||||
authViewModel: AuthViewModel,
|
authViewModel: AuthViewModel,
|
||||||
syncViewModel: SyncViewModel,
|
syncViewModel: SyncViewModel,
|
||||||
|
connectionStatusViewModel: ConnectionStatusViewModel,
|
||||||
) {
|
) {
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
|
|
||||||
@@ -75,6 +77,7 @@ fun NavGraph(
|
|||||||
onTabSelected = onTabSelected,
|
onTabSelected = onTabSelected,
|
||||||
onOpenDocument = { id -> navController.navigate(Routes.document(id)) },
|
onOpenDocument = { id -> navController.navigate(Routes.document(id)) },
|
||||||
syncViewModel = syncViewModel,
|
syncViewModel = syncViewModel,
|
||||||
|
connectionStatusViewModel = connectionStatusViewModel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(Routes.SEARCH) {
|
composable(Routes.SEARCH) {
|
||||||
@@ -82,6 +85,7 @@ fun NavGraph(
|
|||||||
selectedTab = selectedTab,
|
selectedTab = selectedTab,
|
||||||
onTabSelected = onTabSelected,
|
onTabSelected = onTabSelected,
|
||||||
onOpenDocument = { id -> navController.navigate(Routes.document(id)) },
|
onOpenDocument = { id -> navController.navigate(Routes.document(id)) },
|
||||||
|
connectionStatusViewModel = connectionStatusViewModel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(Routes.SETTINGS) {
|
composable(Routes.SETTINGS) {
|
||||||
@@ -89,6 +93,7 @@ fun NavGraph(
|
|||||||
selectedTab = selectedTab,
|
selectedTab = selectedTab,
|
||||||
onTabSelected = onTabSelected,
|
onTabSelected = onTabSelected,
|
||||||
authViewModel = authViewModel,
|
authViewModel = authViewModel,
|
||||||
|
connectionStatusViewModel = connectionStatusViewModel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(
|
composable(
|
||||||
@@ -105,6 +110,7 @@ fun NavGraph(
|
|||||||
onBack = { navController.popBackStack() },
|
onBack = { navController.popBackStack() },
|
||||||
onOpenFolder = { id -> navController.navigate(Routes.folder(id)) },
|
onOpenFolder = { id -> navController.navigate(Routes.folder(id)) },
|
||||||
onOpenDocument = { id -> navController.navigate(Routes.document(id)) },
|
onOpenDocument = { id -> navController.navigate(Routes.document(id)) },
|
||||||
|
connectionStatusViewModel = connectionStatusViewModel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(
|
composable(
|
||||||
@@ -119,6 +125,7 @@ fun NavGraph(
|
|||||||
DocumentViewerScreen(
|
DocumentViewerScreen(
|
||||||
initialResourceId = documentId,
|
initialResourceId = documentId,
|
||||||
onBack = { navController.popBackStack() },
|
onBack = { navController.popBackStack() },
|
||||||
|
connectionStatusViewModel = connectionStatusViewModel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.vaultdrop.mobile.features.connection.ConnectionStatusViewModel
|
||||||
import com.vaultdrop.mobile.features.sync.SyncViewModel
|
import com.vaultdrop.mobile.features.sync.SyncViewModel
|
||||||
import com.vaultdrop.mobile.ui.auth.AuthState
|
import com.vaultdrop.mobile.ui.auth.AuthState
|
||||||
import com.vaultdrop.mobile.ui.auth.AuthViewModel
|
import com.vaultdrop.mobile.ui.auth.AuthViewModel
|
||||||
@@ -35,18 +36,30 @@ private fun SplashScreen() {
|
|||||||
fun VaultDropApp(
|
fun VaultDropApp(
|
||||||
authViewModel: AuthViewModel = hiltViewModel(),
|
authViewModel: AuthViewModel = hiltViewModel(),
|
||||||
syncViewModel: SyncViewModel = hiltViewModel(),
|
syncViewModel: SyncViewModel = hiltViewModel(),
|
||||||
|
connectionStatusViewModel: ConnectionStatusViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val authState by authViewModel.authState.collectAsStateWithLifecycle()
|
val authState by authViewModel.authState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
// Une fois la session résolue, lancer la boucle de fond (idempotente).
|
// Une fois la session résolue, lancer les boucles de fond (idempotentes).
|
||||||
LaunchedEffect(authState) {
|
LaunchedEffect(authState) {
|
||||||
if (authState != AuthState.Loading) syncViewModel.ensureStarted()
|
if (authState != AuthState.Loading) {
|
||||||
|
syncViewModel.ensureStarted()
|
||||||
|
connectionStatusViewModel.start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when (authState) {
|
when (authState) {
|
||||||
AuthState.Loading -> SplashScreen()
|
AuthState.Loading -> SplashScreen()
|
||||||
AuthState.SignedOut -> LoginScreen()
|
AuthState.SignedOut -> LoginScreen()
|
||||||
AuthState.Local -> NavGraph(authViewModel = authViewModel, syncViewModel = syncViewModel)
|
AuthState.Local -> NavGraph(
|
||||||
is AuthState.SignedIn -> NavGraph(authViewModel = authViewModel, syncViewModel = syncViewModel)
|
authViewModel = authViewModel,
|
||||||
|
syncViewModel = syncViewModel,
|
||||||
|
connectionStatusViewModel = connectionStatusViewModel,
|
||||||
|
)
|
||||||
|
is AuthState.SignedIn -> NavGraph(
|
||||||
|
authViewModel = authViewModel,
|
||||||
|
syncViewModel = syncViewModel,
|
||||||
|
connectionStatusViewModel = connectionStatusViewModel,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,9 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import com.vaultdrop.mobile.R
|
import com.vaultdrop.mobile.R
|
||||||
import com.vaultdrop.mobile.data.local.entity.FileEntity
|
import com.vaultdrop.mobile.data.local.entity.FileEntity
|
||||||
import com.vaultdrop.mobile.domain.FileCategory
|
import com.vaultdrop.mobile.domain.FileCategory
|
||||||
|
import com.vaultdrop.mobile.features.connection.ConnectionStatusViewModel
|
||||||
import com.vaultdrop.mobile.ui.components.FileCategoryIcon
|
import com.vaultdrop.mobile.ui.components.FileCategoryIcon
|
||||||
|
import com.vaultdrop.mobile.ui.components.ServerStatusBadge
|
||||||
import com.vaultdrop.mobile.ui.components.color
|
import com.vaultdrop.mobile.ui.components.color
|
||||||
import com.vaultdrop.mobile.ui.components.icon
|
import com.vaultdrop.mobile.ui.components.icon
|
||||||
import com.vaultdrop.mobile.ui.navigation.FloatingNavBar
|
import com.vaultdrop.mobile.ui.navigation.FloatingNavBar
|
||||||
@@ -57,13 +59,23 @@ fun SearchScreen(
|
|||||||
selectedTab: NavTab,
|
selectedTab: NavTab,
|
||||||
onTabSelected: (NavTab) -> Unit,
|
onTabSelected: (NavTab) -> Unit,
|
||||||
onOpenDocument: (String) -> Unit,
|
onOpenDocument: (String) -> Unit,
|
||||||
|
connectionStatusViewModel: ConnectionStatusViewModel,
|
||||||
viewModel: SearchViewModel = hiltViewModel(),
|
viewModel: SearchViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
val connectionStatus by connectionStatusViewModel.status.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(title = { Text(stringResource(R.string.search)) })
|
TopAppBar(
|
||||||
|
title = { Text(stringResource(R.string.search)) },
|
||||||
|
actions = {
|
||||||
|
ServerStatusBadge(
|
||||||
|
status = connectionStatus,
|
||||||
|
onClick = connectionStatusViewModel::checkNow,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
FloatingNavBar(selected = selectedTab, onSelect = onTabSelected)
|
FloatingNavBar(selected = selectedTab, onSelect = onTabSelected)
|
||||||
|
|||||||
@@ -46,9 +46,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vaultdrop.mobile.R
|
import com.vaultdrop.mobile.R
|
||||||
import com.vaultdrop.mobile.domain.ThemePreference
|
import com.vaultdrop.mobile.domain.ThemePreference
|
||||||
|
import com.vaultdrop.mobile.features.connection.ConnectionStatusViewModel
|
||||||
import com.vaultdrop.mobile.ui.auth.AuthState
|
import com.vaultdrop.mobile.ui.auth.AuthState
|
||||||
import com.vaultdrop.mobile.ui.auth.AuthViewModel
|
import com.vaultdrop.mobile.ui.auth.AuthViewModel
|
||||||
import com.vaultdrop.mobile.ui.auth.authErrorResFor
|
import com.vaultdrop.mobile.ui.auth.authErrorResFor
|
||||||
|
import com.vaultdrop.mobile.ui.components.ServerStatusBadge
|
||||||
import com.vaultdrop.mobile.ui.navigation.FloatingNavBar
|
import com.vaultdrop.mobile.ui.navigation.FloatingNavBar
|
||||||
import com.vaultdrop.mobile.ui.navigation.NavTab
|
import com.vaultdrop.mobile.ui.navigation.NavTab
|
||||||
|
|
||||||
@@ -58,11 +60,13 @@ fun SettingsScreen(
|
|||||||
selectedTab: NavTab,
|
selectedTab: NavTab,
|
||||||
onTabSelected: (NavTab) -> Unit,
|
onTabSelected: (NavTab) -> Unit,
|
||||||
authViewModel: AuthViewModel,
|
authViewModel: AuthViewModel,
|
||||||
|
connectionStatusViewModel: ConnectionStatusViewModel,
|
||||||
viewModel: SettingsViewModel = hiltViewModel(),
|
viewModel: SettingsViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val theme by viewModel.theme.collectAsStateWithLifecycle()
|
val theme by viewModel.theme.collectAsStateWithLifecycle()
|
||||||
val serverUrl by viewModel.serverUrl.collectAsStateWithLifecycle()
|
val serverUrl by viewModel.serverUrl.collectAsStateWithLifecycle()
|
||||||
val testUiState by viewModel.testUiState.collectAsStateWithLifecycle()
|
val testUiState by viewModel.testUiState.collectAsStateWithLifecycle()
|
||||||
|
val connectionStatus by connectionStatusViewModel.status.collectAsStateWithLifecycle()
|
||||||
val authState by authViewModel.authState.collectAsStateWithLifecycle()
|
val authState by authViewModel.authState.collectAsStateWithLifecycle()
|
||||||
val loginUi by authViewModel.loginUiState.collectAsStateWithLifecycle()
|
val loginUi by authViewModel.loginUiState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
@@ -77,7 +81,15 @@ fun SettingsScreen(
|
|||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(title = { Text(stringResource(R.string.settings)) })
|
TopAppBar(
|
||||||
|
title = { Text(stringResource(R.string.settings)) },
|
||||||
|
actions = {
|
||||||
|
ServerStatusBadge(
|
||||||
|
status = connectionStatus,
|
||||||
|
onClick = connectionStatusViewModel::checkNow,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
FloatingNavBar(selected = selectedTab, onSelect = onTabSelected)
|
FloatingNavBar(selected = selectedTab, onSelect = onTabSelected)
|
||||||
|
|||||||
@@ -75,4 +75,11 @@
|
|||||||
<string name="login_error_unauthorized">Nom d\'utilisateur ou mot de passe incorrect</string>
|
<string name="login_error_unauthorized">Nom d\'utilisateur ou mot de passe incorrect</string>
|
||||||
<string name="login_skip">Continuer sans compte</string>
|
<string name="login_skip">Continuer sans compte</string>
|
||||||
<string name="skip_message">Mode local — tes dossiers restent sur cet appareil et ne sont pas synchronisés.</string>
|
<string name="skip_message">Mode local — tes dossiers restent sur cet appareil et ne sont pas synchronisés.</string>
|
||||||
|
|
||||||
|
<!-- Statut serveur (badge du header) -->
|
||||||
|
<string name="status_online">En ligne</string>
|
||||||
|
<string name="status_offline">Hors ligne</string>
|
||||||
|
<string name="status_checking">Vérification…</string>
|
||||||
|
<string name="status_local">Mode local</string>
|
||||||
|
<string name="status_tap_to_recheck">Statut serveur — appuyer pour vérifier</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user