android: add settings and profile shells and move logout action
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
@@ -313,3 +313,8 @@
|
||||
- Added `SessionCleanupRepository` + `DefaultSessionCleanupRepository` to wipe Room tables and clear per-chat notification overrides.
|
||||
- Added logout action in chat list UI and wired it to `AuthViewModel`, with automatic navigation back to login via auth state.
|
||||
- Added unit tests for logout use case orchestration and notification override cleanup.
|
||||
|
||||
### Step 52 - Settings/Profile shell and logout relocation
|
||||
- Added dedicated `Settings` and `Profile` routes/screens with mobile-safe insets and placeholder content.
|
||||
- Removed direct logout action from chat list and moved logout action to `Settings`.
|
||||
- Wired bottom navigation pills in chats to open `Settings` and `Profile`.
|
||||
|
||||
@@ -29,7 +29,6 @@ import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.TabRow
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -51,7 +50,8 @@ import java.time.format.DateTimeFormatter
|
||||
@Composable
|
||||
fun ChatListRoute(
|
||||
onOpenChat: (Long) -> Unit,
|
||||
onLogout: () -> Unit,
|
||||
onOpenSettings: () -> Unit,
|
||||
onOpenProfile: () -> Unit,
|
||||
inviteToken: String?,
|
||||
onInviteTokenConsumed: () -> Unit,
|
||||
viewModel: ChatListViewModel = hiltViewModel(),
|
||||
@@ -74,7 +74,8 @@ fun ChatListRoute(
|
||||
onFilterSelected = viewModel::onFilterSelected,
|
||||
onSearchChanged = viewModel::onSearchChanged,
|
||||
onRefresh = viewModel::onPullToRefresh,
|
||||
onLogout = onLogout,
|
||||
onOpenSettings = onOpenSettings,
|
||||
onOpenProfile = onOpenProfile,
|
||||
onOpenChat = onOpenChat,
|
||||
)
|
||||
}
|
||||
@@ -87,7 +88,8 @@ fun ChatListScreen(
|
||||
onFilterSelected: (ChatListFilter) -> Unit,
|
||||
onSearchChanged: (String) -> Unit,
|
||||
onRefresh: () -> Unit,
|
||||
onLogout: () -> Unit,
|
||||
onOpenSettings: () -> Unit,
|
||||
onOpenProfile: () -> Unit,
|
||||
onOpenChat: (Long) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
@@ -119,16 +121,6 @@ fun ChatListScreen(
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
) {
|
||||
TextButton(onClick = onLogout) {
|
||||
Text("Logout")
|
||||
}
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -224,8 +216,8 @@ fun ChatListScreen(
|
||||
) {
|
||||
BottomNavPill(label = "Chats", selected = true, onClick = {})
|
||||
BottomNavPill(label = "Contacts", selected = false, onClick = {})
|
||||
BottomNavPill(label = "Settings", selected = false, onClick = {})
|
||||
BottomNavPill(label = "Profile", selected = false, onClick = {})
|
||||
BottomNavPill(label = "Settings", selected = false, onClick = onOpenSettings)
|
||||
BottomNavPill(label = "Profile", selected = false, onClick = onOpenProfile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,15 @@ import ru.daemonlord.messenger.ui.auth.AuthViewModel
|
||||
import ru.daemonlord.messenger.ui.auth.LoginScreen
|
||||
import ru.daemonlord.messenger.ui.chat.ChatRoute
|
||||
import ru.daemonlord.messenger.ui.chats.ChatListRoute
|
||||
import ru.daemonlord.messenger.ui.profile.ProfileRoute
|
||||
import ru.daemonlord.messenger.ui.settings.SettingsRoute
|
||||
|
||||
private object Routes {
|
||||
const val AuthGraph = "auth_graph"
|
||||
const val Login = "login"
|
||||
const val Chats = "chats"
|
||||
const val Settings = "settings"
|
||||
const val Profile = "profile"
|
||||
const val Chat = "chat"
|
||||
}
|
||||
|
||||
@@ -125,13 +129,29 @@ fun MessengerNavHost(
|
||||
ChatListRoute(
|
||||
inviteToken = inviteToken,
|
||||
onInviteTokenConsumed = onInviteTokenConsumed,
|
||||
onLogout = viewModel::logout,
|
||||
onOpenSettings = { navController.navigate(Routes.Settings) },
|
||||
onOpenProfile = { navController.navigate(Routes.Profile) },
|
||||
onOpenChat = { chatId ->
|
||||
navController.navigate("${Routes.Chat}/$chatId")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
composable(route = Routes.Settings) {
|
||||
SettingsRoute(
|
||||
onBackToChats = { navController.popBackStack() },
|
||||
onOpenProfile = { navController.navigate(Routes.Profile) },
|
||||
onLogout = viewModel::logout,
|
||||
)
|
||||
}
|
||||
|
||||
composable(route = Routes.Profile) {
|
||||
ProfileRoute(
|
||||
onBackToChats = { navController.popBackStack() },
|
||||
onOpenSettings = { navController.navigate(Routes.Settings) },
|
||||
)
|
||||
}
|
||||
|
||||
composable(
|
||||
route = "${Routes.Chat}/{chatId}",
|
||||
arguments = listOf(
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package ru.daemonlord.messenger.ui.profile
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun ProfileRoute(
|
||||
onBackToChats: () -> Unit,
|
||||
onOpenSettings: () -> Unit,
|
||||
) {
|
||||
ProfileScreen(
|
||||
onBackToChats = onBackToChats,
|
||||
onOpenSettings = onOpenSettings,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ProfileScreen(
|
||||
onBackToChats: () -> Unit,
|
||||
onOpenSettings: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.windowInsetsPadding(WindowInsets.safeDrawing)
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = "Profile",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
)
|
||||
Text(
|
||||
text = "Profile editing screen placeholder. Telegram-like account editor will be implemented in a dedicated step.",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
OutlinedButton(
|
||||
onClick = onOpenSettings,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text("Open settings")
|
||||
}
|
||||
OutlinedButton(
|
||||
onClick = onBackToChats,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text("Back to chats")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package ru.daemonlord.messenger.ui.settings
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun SettingsRoute(
|
||||
onBackToChats: () -> Unit,
|
||||
onOpenProfile: () -> Unit,
|
||||
onLogout: () -> Unit,
|
||||
) {
|
||||
SettingsScreen(
|
||||
onBackToChats = onBackToChats,
|
||||
onOpenProfile = onOpenProfile,
|
||||
onLogout = onLogout,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingsScreen(
|
||||
onBackToChats: () -> Unit,
|
||||
onOpenProfile: () -> Unit,
|
||||
onLogout: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.windowInsetsPadding(WindowInsets.safeDrawing)
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = "Settings",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
)
|
||||
Text(
|
||||
text = "Core account actions are here. More Telegram-like settings will be added in next iterations.",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
OutlinedButton(
|
||||
onClick = onOpenProfile,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text("Open profile")
|
||||
}
|
||||
Button(
|
||||
onClick = onLogout,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text("Logout")
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
OutlinedButton(onClick = onBackToChats) {
|
||||
Text("Back to chats")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user