#52 poging tot herstructureren -- WERK NIET
This commit is contained in:
		
							parent
							
								
									724087362a
								
							
						
					
					
						commit
						12fe0c852e
					
				
					 12 changed files with 133 additions and 128 deletions
				
			
		|  | @ -16,7 +16,6 @@ import androidx.navigation.NavHostController | ||||||
| import androidx.navigation.compose.NavHost | import androidx.navigation.compose.NavHost | ||||||
| import androidx.navigation.compose.composable | import androidx.navigation.compose.composable | ||||||
| import androidx.navigation.compose.rememberNavController | import androidx.navigation.compose.rememberNavController | ||||||
| import be.ugent.sel.studeez.screens.drawer.Drawer |  | ||||||
| import be.ugent.sel.studeez.common.snackbar.SnackbarManager | import be.ugent.sel.studeez.common.snackbar.SnackbarManager | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations | import be.ugent.sel.studeez.navigation.StudeezDestinations | ||||||
| import be.ugent.sel.studeez.screens.home.HomeScreen | import be.ugent.sel.studeez.screens.home.HomeScreen | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package be.ugent.sel.studeez.screens.drawer | package be.ugent.sel.studeez.common.composable | ||||||
| 
 | 
 | ||||||
| import androidx.compose.foundation.Image | import androidx.compose.foundation.Image | ||||||
| import androidx.compose.foundation.clickable | import androidx.compose.foundation.clickable | ||||||
|  | @ -17,7 +17,6 @@ import androidx.compose.ui.res.painterResource | ||||||
| import androidx.compose.ui.res.stringResource | import androidx.compose.ui.res.stringResource | ||||||
| import androidx.compose.ui.res.vectorResource | import androidx.compose.ui.res.vectorResource | ||||||
| import androidx.compose.ui.tooling.preview.Preview | import androidx.compose.ui.tooling.preview.Preview | ||||||
| import androidx.hilt.navigation.compose.hiltViewModel |  | ||||||
| import be.ugent.sel.studeez.R | import be.ugent.sel.studeez.R | ||||||
| import be.ugent.sel.studeez.resources | import be.ugent.sel.studeez.resources | ||||||
| import be.ugent.sel.studeez.ui.theme.StudeezTheme | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
|  | @ -25,11 +24,11 @@ import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun Drawer( | fun Drawer( | ||||||
|     openAndPopup: (String, String) -> Unit, |     currentUser: String, | ||||||
|     viewModel: DrawerViewModel = hiltViewModel() |     onLogoutClick: () -> Unit | ||||||
| ) { | ) { | ||||||
|     Column(modifier = Modifier.fillMaxSize()) { |     Column(modifier = Modifier.fillMaxSize()) { | ||||||
|         LoggedInUserCard(viewModel.currentUser) |         LoggedInUserCard(currentUser) | ||||||
| 
 | 
 | ||||||
|         Divider() |         Divider() | ||||||
| 
 | 
 | ||||||
|  | @ -55,7 +54,7 @@ fun Drawer( | ||||||
|             icon = ImageVector.vectorResource(id = R.drawable.ic_logout), |             icon = ImageVector.vectorResource(id = R.drawable.ic_logout), | ||||||
|             text = resources().getString(R.string.log_out) |             text = resources().getString(R.string.log_out) | ||||||
|         ) { |         ) { | ||||||
|             viewModel.onLogoutClick(openAndPopup) |             onLogoutClick() | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         DrawerEntry( |         DrawerEntry( | ||||||
|  | @ -110,7 +109,10 @@ fun LoggedInUserCard( | ||||||
| @Composable | @Composable | ||||||
| fun DrawerPreview() { | fun DrawerPreview() { | ||||||
|     StudeezTheme { |     StudeezTheme { | ||||||
|         Drawer({ a, b -> {}}) |         Drawer( | ||||||
|  |             "John Doe", | ||||||
|  |             {} | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -4,72 +4,14 @@ import androidx.compose.foundation.layout.PaddingValues | ||||||
| import androidx.compose.material.* | import androidx.compose.material.* | ||||||
| import androidx.compose.material.icons.Icons | import androidx.compose.material.icons.Icons | ||||||
| import androidx.compose.material.icons.filled.ArrowBack | import androidx.compose.material.icons.filled.ArrowBack | ||||||
| import androidx.compose.material.icons.filled.Menu |  | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
| import androidx.compose.runtime.remember |  | ||||||
| import androidx.compose.runtime.rememberCoroutineScope |  | ||||||
| import androidx.compose.ui.tooling.preview.Preview | import androidx.compose.ui.tooling.preview.Preview | ||||||
| import be.ugent.sel.studeez.screens.drawer.Drawer | import be.ugent.sel.studeez.R | ||||||
| import be.ugent.sel.studeez.screens.drawer.StudeezDrawerState | import be.ugent.sel.studeez.resources | ||||||
| import be.ugent.sel.studeez.ui.theme.StudeezTheme | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
| import kotlinx.coroutines.CoroutineScope |  | ||||||
| 
 | 
 | ||||||
| // TODO Add option for button in top right corner as extra button | // TODO Add option for button in top right corner as extra button | ||||||
| 
 | 
 | ||||||
| @Composable |  | ||||||
| // Contains floatingActionButton and bottom bar, used in the main four screens. |  | ||||||
| fun PrimaryScreenToolbar( |  | ||||||
|     title: String, |  | ||||||
|     openAndPopUp: (String, String) -> Unit, |  | ||||||
|     content: @Composable (PaddingValues) -> Unit |  | ||||||
| ) { |  | ||||||
|     val primaryScreenToolbarState = rememberPrimaryScreenToolbarState() |  | ||||||
| 
 |  | ||||||
|     Scaffold( |  | ||||||
|         scaffoldState = primaryScreenToolbarState.scaffoldState, |  | ||||||
| 
 |  | ||||||
|         // Everything at the top of the screen |  | ||||||
|         topBar = { TopAppBar( |  | ||||||
|             title = { Text(text = title) }, |  | ||||||
|             navigationIcon = { |  | ||||||
|                 IconButton(onClick = { primaryScreenToolbarState.openDrawer() }) { |  | ||||||
|                     Icon(imageVector = Icons.Default.Menu, contentDescription = "Menu") |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         ) }, |  | ||||||
| 
 |  | ||||||
|         // Drawer |  | ||||||
|         drawerContent = @Composable { |  | ||||||
|             Drawer(openAndPopUp) |  | ||||||
|         }, |  | ||||||
| 
 |  | ||||||
|         // Everything at the bottom of the screen |  | ||||||
|         bottomBar = { NavigationBar() }, // TODO Pass arguments so that the current tab etc can be shown |  | ||||||
|         floatingActionButtonPosition = FabPosition.Center, |  | ||||||
|         isFloatingActionButtonDocked = true, |  | ||||||
|         floatingActionButton = { CollapsedAddButton() } |  | ||||||
|     ) { paddingValues -> |  | ||||||
|         content(paddingValues) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @Composable |  | ||||||
| fun rememberPrimaryScreenToolbarState( |  | ||||||
|     scaffoldState: ScaffoldState = rememberScaffoldState(), |  | ||||||
|     coroutineScope: CoroutineScope = rememberCoroutineScope() |  | ||||||
| ) = remember(scaffoldState, coroutineScope) { |  | ||||||
|     StudeezDrawerState(scaffoldState, coroutineScope) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @Preview |  | ||||||
| @Composable |  | ||||||
| fun PrimaryScreenToolbarPreview() { |  | ||||||
|     StudeezTheme { PrimaryScreenToolbar( |  | ||||||
|         "Preview screen", |  | ||||||
|         { a, b -> {}} |  | ||||||
|     ) {} } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @Composable | @Composable | ||||||
| // Does not contain floatingActionButton and bottom bar, used in all the other screens | // Does not contain floatingActionButton and bottom bar, used in all the other screens | ||||||
| fun SecondaryScreenToolbar( | fun SecondaryScreenToolbar( | ||||||
|  | @ -82,8 +24,11 @@ fun SecondaryScreenToolbar( | ||||||
|         topBar = { TopAppBar( |         topBar = { TopAppBar( | ||||||
|             title = { Text(text = title) }, |             title = { Text(text = title) }, | ||||||
|             navigationIcon = { |             navigationIcon = { | ||||||
|                 IconButton(onClick = { /* TODO Go back */ }) { |                 IconButton(onClick = { popUp() }) { | ||||||
|                     Icon(imageVector = Icons.Default.ArrowBack, contentDescription = "Go back") |                     Icon( | ||||||
|  |                         imageVector = Icons.Default.ArrowBack, | ||||||
|  |                         contentDescription = resources().getString(R.string.go_back) | ||||||
|  |                     ) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         ) }, |         ) }, | ||||||
|  | @ -94,17 +39,9 @@ fun SecondaryScreenToolbar( | ||||||
| 
 | 
 | ||||||
| @Preview | @Preview | ||||||
| @Composable | @Composable | ||||||
| fun PrimaryScreenToolbarPreview() { | fun SecondaryScreenToolbarPreview() { | ||||||
|     StudeezTheme { PrimaryScreenToolbar( |     StudeezTheme { SecondaryScreenToolbar( | ||||||
|         "Preview screen", |         "Preview screen", | ||||||
|         {} |         {} | ||||||
|     ) {} } |     ) {} } | ||||||
| } | } | ||||||
| 
 |  | ||||||
| @Preview |  | ||||||
| @Composable |  | ||||||
| fun SecondaryScreenToolbarPreview() { |  | ||||||
|     StudeezTheme { SecondaryScreenToolbar( |  | ||||||
|         "Preview screen" |  | ||||||
|     ) {} } |  | ||||||
| } |  | ||||||
|  | @ -1,24 +0,0 @@ | ||||||
| package be.ugent.sel.studeez.screens.drawer |  | ||||||
| 
 |  | ||||||
| import be.ugent.sel.studeez.domain.AccountDAO |  | ||||||
| import be.ugent.sel.studeez.domain.LogService |  | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN |  | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations.LOGIN_SCREEN |  | ||||||
| import be.ugent.sel.studeez.screens.StudeezViewModel |  | ||||||
| import dagger.hilt.android.lifecycle.HiltViewModel |  | ||||||
| import javax.inject.Inject |  | ||||||
| 
 |  | ||||||
| @HiltViewModel |  | ||||||
| class DrawerViewModel @Inject constructor( |  | ||||||
|     private val accountDAO: AccountDAO, |  | ||||||
|     logService: LogService |  | ||||||
| ): StudeezViewModel(logService) { |  | ||||||
|     val currentUser: String = accountDAO.currentUserId |  | ||||||
| 
 |  | ||||||
|     fun onLogoutClick(openAndPopup: (String, String) -> Unit) { |  | ||||||
|         launchCatching { |  | ||||||
|             accountDAO.signOut() |  | ||||||
|             openAndPopup(LOGIN_SCREEN, HOME_SCREEN) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | @ -1,16 +0,0 @@ | ||||||
| package be.ugent.sel.studeez.screens.drawer |  | ||||||
| 
 |  | ||||||
| import androidx.compose.material.ScaffoldState |  | ||||||
| import androidx.compose.runtime.Stable |  | ||||||
| import kotlinx.coroutines.CoroutineScope |  | ||||||
| import kotlinx.coroutines.launch |  | ||||||
| 
 |  | ||||||
| @Stable |  | ||||||
| class StudeezDrawerState( |  | ||||||
|     val scaffoldState: ScaffoldState, |  | ||||||
|     private val coroutineScope: CoroutineScope |  | ||||||
| ) { |  | ||||||
|     fun openDrawer() { |  | ||||||
|         coroutineScope.launch { scaffoldState.drawerState.open() } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | @ -1,13 +1,15 @@ | ||||||
| package be.ugent.sel.studeez.screens.home | package be.ugent.sel.studeez.screens.home | ||||||
| 
 | 
 | ||||||
|  | import androidx.compose.material.rememberScaffoldState | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
| 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.viewModelScope | ||||||
| import be.ugent.sel.studeez.R | import be.ugent.sel.studeez.R | ||||||
| import be.ugent.sel.studeez.common.composable.BasicButton | import be.ugent.sel.studeez.common.composable.BasicButton | ||||||
| import be.ugent.sel.studeez.common.composable.PrimaryScreenToolbar |  | ||||||
| import be.ugent.sel.studeez.common.ext.basicButton | import be.ugent.sel.studeez.common.ext.basicButton | ||||||
| import be.ugent.sel.studeez.resources | import be.ugent.sel.studeez.resources | ||||||
|  | import be.ugent.sel.studeez.screens.templates.primary_screen.PrimaryScreen | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun HomeScreen( | fun HomeScreen( | ||||||
|  | @ -15,9 +17,11 @@ fun HomeScreen( | ||||||
|     viewModel: HomeViewModel = hiltViewModel() |     viewModel: HomeViewModel = hiltViewModel() | ||||||
| ) { | ) { | ||||||
| 
 | 
 | ||||||
|     PrimaryScreenToolbar( |     PrimaryScreen( | ||||||
|         title = resources().getString(R.string.home), |         title = resources().getString(R.string.home), | ||||||
|         openAndPopUp = openAndPopUp |         openDrawer = { viewModel.openDrawer() }, | ||||||
|  |         onLogoutClick = { viewModel.onLogoutClick(openAndPopUp) }, | ||||||
|  |         viewModel.scaffoldState | ||||||
|     ) { |     ) { | ||||||
|         BasicButton(R.string.start_session, Modifier.basicButton()) { |         BasicButton(R.string.start_session, Modifier.basicButton()) { | ||||||
|             viewModel.onStartSessionClick(openAndPopUp) |             viewModel.onStartSessionClick(openAndPopUp) | ||||||
|  |  | ||||||
|  | @ -1,14 +1,36 @@ | ||||||
| package be.ugent.sel.studeez.screens.home | package be.ugent.sel.studeez.screens.home | ||||||
| 
 | 
 | ||||||
|  | import androidx.compose.material.ScaffoldState | ||||||
|  | import androidx.compose.material.rememberScaffoldState | ||||||
|  | import be.ugent.sel.studeez.domain.AccountDAO | ||||||
| import be.ugent.sel.studeez.domain.LogService | import be.ugent.sel.studeez.domain.LogService | ||||||
|  | import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN | ||||||
|  | import be.ugent.sel.studeez.navigation.StudeezDestinations.LOGIN_SCREEN | ||||||
| import be.ugent.sel.studeez.screens.StudeezViewModel | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
| import dagger.hilt.android.lifecycle.HiltViewModel | import dagger.hilt.android.lifecycle.HiltViewModel | ||||||
| import javax.inject.Inject | import javax.inject.Inject | ||||||
| 
 | 
 | ||||||
| @HiltViewModel | @HiltViewModel | ||||||
| class HomeViewModel @Inject constructor(logService: LogService) : StudeezViewModel(logService) { | class HomeViewModel @Inject constructor( | ||||||
|  |     private val accountDAO: AccountDAO, | ||||||
|  |     logService: LogService | ||||||
|  | ) : StudeezViewModel(logService) { | ||||||
|  |     val scaffoldState: ScaffoldState = rememberScaffoldState() | ||||||
| 
 | 
 | ||||||
|     fun onStartSessionClick(openAndPopUp: (String, String) -> Unit) { |     fun onStartSessionClick(openAndPopUp: (String, String) -> Unit) { | ||||||
|         // openAndPopUp(StudeezDestinations.xxx, StudeezDestinations.HOME_SCREEN) |         // TODO openAndPopUp(StudeezDestinations.xxx, StudeezDestinations.HOME_SCREEN) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun onLogoutClick(openAndPopup: (String, String) -> Unit) { | ||||||
|  |         launchCatching { | ||||||
|  |             accountDAO.signOut() | ||||||
|  |             openAndPopup(LOGIN_SCREEN, HOME_SCREEN) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun openDrawer() { | ||||||
|  |         launchCatching { | ||||||
|  |             scaffoldState.drawerState.open() | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -27,7 +27,7 @@ fun LoginScreen( | ||||||
|     val uiState by viewModel.uiState |     val uiState by viewModel.uiState | ||||||
| 
 | 
 | ||||||
|     // TODO Make this a separate kind of screen? |     // TODO Make this a separate kind of screen? | ||||||
|     SecondaryScreenToolbar(title = resources().getString(AppText.sign_in)) { |     SecondaryScreenToolbar(title = resources().getString(AppText.sign_in), {}) { | ||||||
|         Column( |         Column( | ||||||
|             modifier = modifier |             modifier = modifier | ||||||
|                 .fillMaxWidth() |                 .fillMaxWidth() | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ fun SignUpScreen( | ||||||
|     val uiState by viewModel.uiState |     val uiState by viewModel.uiState | ||||||
|     val fieldModifier = Modifier.fieldModifier() |     val fieldModifier = Modifier.fieldModifier() | ||||||
| 
 | 
 | ||||||
|     SecondaryScreenToolbar(title = resources().getString(AppText.create_account)) { |     SecondaryScreenToolbar(title = resources().getString(AppText.create_account), {}) { | ||||||
|         Column( |         Column( | ||||||
|             modifier = modifier |             modifier = modifier | ||||||
|                 .fillMaxWidth() |                 .fillMaxWidth() | ||||||
|  |  | ||||||
|  | @ -0,0 +1,65 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.templates.primary_screen | ||||||
|  | 
 | ||||||
|  | import androidx.compose.foundation.layout.PaddingValues | ||||||
|  | import androidx.compose.material.* | ||||||
|  | import androidx.compose.material.icons.Icons | ||||||
|  | import androidx.compose.material.icons.filled.Menu | ||||||
|  | import androidx.compose.runtime.Composable | ||||||
|  | import androidx.compose.ui.tooling.preview.Preview | ||||||
|  | import be.ugent.sel.studeez.R | ||||||
|  | import be.ugent.sel.studeez.common.composable.CollapsedAddButton | ||||||
|  | import be.ugent.sel.studeez.common.composable.Drawer | ||||||
|  | import be.ugent.sel.studeez.common.composable.NavigationBar | ||||||
|  | import be.ugent.sel.studeez.resources | ||||||
|  | import be.ugent.sel.studeez.ui.theme.StudeezTheme | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun PrimaryScreen( | ||||||
|  |     title: String, | ||||||
|  |     openDrawer: () -> Unit, | ||||||
|  |     onLogoutClick: () -> Unit, | ||||||
|  |     scaffoldState: ScaffoldState, | ||||||
|  |     content: @Composable (PaddingValues) -> Unit | ||||||
|  | ) { | ||||||
|  | 
 | ||||||
|  |     Scaffold( | ||||||
|  |         scaffoldState = scaffoldState, | ||||||
|  | 
 | ||||||
|  |         topBar = { TopAppBar( | ||||||
|  |             title = { Text(text = title) }, | ||||||
|  |             navigationIcon = { | ||||||
|  |                 IconButton(onClick = { openDrawer() }) { | ||||||
|  |                     Icon( | ||||||
|  |                         imageVector = Icons.Default.Menu, | ||||||
|  |                         contentDescription = resources().getString(R.string.menu) | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ) }, | ||||||
|  | 
 | ||||||
|  |         drawerContent = { | ||||||
|  |             Drawer( | ||||||
|  |                 currentUser = "TODO John Doe", | ||||||
|  |                 onLogoutClick = { onLogoutClick() } | ||||||
|  |             ) | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         bottomBar = { NavigationBar() }, // TODO Pass arguments so that the current tab etc can be shown | ||||||
|  |         floatingActionButtonPosition = FabPosition.Center, | ||||||
|  |         isFloatingActionButtonDocked = true, | ||||||
|  |         floatingActionButton = { CollapsedAddButton() } | ||||||
|  |     ) { | ||||||
|  |         content(it) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun PrimaryScreenPreview() { | ||||||
|  |     StudeezTheme { | ||||||
|  |         PrimaryScreen( | ||||||
|  |             "Preview screen", | ||||||
|  |             {}, {}, rememberScaffoldState() | ||||||
|  |         ) {} | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.templates.primary_screen | ||||||
|  | 
 | ||||||
|  | import androidx.compose.material.ScaffoldState | ||||||
|  | import androidx.compose.material.rememberScaffoldState | ||||||
|  | import androidx.compose.runtime.Composable | ||||||
|  | import androidx.compose.runtime.remember | ||||||
|  | import be.ugent.sel.studeez.StudeezAppstate | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun rememberPrimaryScreenState( | ||||||
|  |     scaffoldState: ScaffoldState = rememberScaffoldState() | ||||||
|  | ) = remember(scaffoldState) { | ||||||
|  |     StudeezAppstate(scaffoldState) | ||||||
|  | } | ||||||
|  | @ -8,6 +8,8 @@ | ||||||
|     <string name="email_error">Please insert a valid email.</string> |     <string name="email_error">Please insert a valid email.</string> | ||||||
|     <string name="cancel">Cancel</string> |     <string name="cancel">Cancel</string> | ||||||
|     <string name="try_again">Try again</string> |     <string name="try_again">Try again</string> | ||||||
|  |     <string name="go_back">Go back</string> | ||||||
|  |     <string name="menu">Menu</string> | ||||||
| 
 | 
 | ||||||
|     <!-- SignUpScreen --> |     <!-- SignUpScreen --> | ||||||
|     <string name="create_account">Create account</string> |     <string name="create_account">Create account</string> | ||||||
|  | @ -30,7 +32,7 @@ | ||||||
|     <!-- Drawer / SideMenu --> |     <!-- Drawer / SideMenu --> | ||||||
|     <string name="log_out">Log out</string> |     <string name="log_out">Log out</string> | ||||||
|     <string name="profile_picture_description">Profile Picture</string> |     <string name="profile_picture_description">Profile Picture</string> | ||||||
|     <string name="user_description">Studeez user</string> |     <string name="user_description">Normal user</string> | ||||||
| 
 | 
 | ||||||
|     <!-- Timers --> |     <!-- Timers --> | ||||||
|     <string name="timers">Timers</string> |     <string name="timers">Timers</string> | ||||||
|  |  | ||||||
		Reference in a new issue