From 7610ae8b9c21c153babd6ce043e0364ef11963d1 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Minh Date: Sun, 1 Dec 2024 14:24:18 +0700 Subject: [PATCH] =?UTF-8?q?feat(folder):=20h=E1=BB=8Dc=20b=E1=BA=B1ng=20fo?= =?UTF-8?q?lder=20-=20s=E1=BB=ADa=20l=E1=BB=97i=20giao=20di=E1=BB=87n=20v?= =?UTF-8?q?=C3=A0o=20logic=20-=20=C4=91a=20ng=C3=B4n=20ng=E1=BB=AF=20cho?= =?UTF-8?q?=20m=E1=BB=99t=20v=C3=A0i=20m=C3=A0n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../classes/detail/ClassDetailViewModel.kt | 13 ++-- .../app/folder/detail/FolderDetailScreen.kt | 61 +++++++++++++++++-- .../folder/detail/FolderDetailViewModel.kt | 5 +- .../app/settings/SettingsScreen.kt | 35 +++++------ .../detail/StudySetDetailViewModel.kt | 5 +- .../detail/material/LearnModeCard.kt | 34 ++++++++--- app/src/main/res/values-vi/strings.xml | 11 ++++ app/src/main/res/values/strings.xml | 11 ++++ 8 files changed, 127 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/classes/detail/ClassDetailViewModel.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/classes/detail/ClassDetailViewModel.kt index ea252f07..7a8ee8f6 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/classes/detail/ClassDetailViewModel.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/classes/detail/ClassDetailViewModel.kt @@ -61,13 +61,14 @@ class ClassDetailViewModel @Inject constructor( } } _uiState.update { it.copy(id = id) } - getClassByID() + getClassById() + saveRecentAccessClass(classId = id) } fun onEvent(event: ClassDetailUiAction) { when (event) { is ClassDetailUiAction.Refresh -> { - getClassByID() + getClassById() } is ClassDetailUiAction.NavigateToWelcomeClicked -> { @@ -130,7 +131,7 @@ class ClassDetailViewModel @Inject constructor( } } - private fun getClassByID() { + private fun getClassById() { val id = _uiState.value.id viewModelScope.launch { val token = tokenManager.accessToken.firstOrNull() ?: "" @@ -170,7 +171,6 @@ class ClassDetailViewModel @Inject constructor( } ?: run { _uiEvent.send(ClassDetailUiEvent.ShowError("Class not found")) } - saveRecentAccessClass() } } } @@ -311,7 +311,7 @@ class ClassDetailViewModel @Inject constructor( } is Resources.Success -> { - getClassByID() + getClassById() _uiState.update { it.copy( isLoading = false, @@ -404,11 +404,10 @@ class ClassDetailViewModel @Inject constructor( } } - private fun saveRecentAccessClass() { + private fun saveRecentAccessClass(classId: String) { viewModelScope.launch { val token = tokenManager.accessToken.firstOrNull() ?: "" val userId = appManager.userId.firstOrNull() ?: "" - val classId = _uiState.value.id val saveRecentAccessClassRequestModel = SaveRecentAccessClassRequestModel(userId, classId) classRepository.saveRecentAccessClass(token, saveRecentAccessClassRequestModel) diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/folder/detail/FolderDetailScreen.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/folder/detail/FolderDetailScreen.kt index 238550da..743c98cf 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/folder/detail/FolderDetailScreen.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/folder/detail/FolderDetailScreen.kt @@ -3,6 +3,7 @@ package com.pwhs.quickmem.presentation.app.folder.detail import android.content.Intent import android.widget.Toast import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons @@ -11,6 +12,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme.colorScheme +import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Scaffold import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState @@ -22,7 +24,9 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -34,6 +38,7 @@ import com.pwhs.quickmem.domain.model.study_set.GetStudySetResponseModel import com.pwhs.quickmem.presentation.app.folder.detail.component.FolderDetailStudySetList import com.pwhs.quickmem.presentation.app.folder.detail.component.FolderDetailTopAppBar import com.pwhs.quickmem.presentation.app.folder.detail.component.FolderMenuBottomSheet +import com.pwhs.quickmem.presentation.app.study_set.detail.material.LearnModeCard import com.pwhs.quickmem.presentation.component.LoadingOverlay import com.pwhs.quickmem.presentation.component.QuickMemAlertDialog import com.pwhs.quickmem.ui.theme.QuickMemTheme @@ -145,7 +150,9 @@ fun FolderDetailScreen( ) }, onEditFolder = { viewModel.onEvent(FolderDetailUiAction.EditFolder) }, - onStudyFolderClick = { viewModel.onEvent(FolderDetailUiAction.Refresh) }, + onStudyFolderClick = { + //TODO: Implement study folder + }, onNavigateBack = { resultNavigator.navigateBack(true) }, @@ -192,15 +199,17 @@ fun FolderDetail( val formattedCreatedAt = formatDate(createdAt) val formattedUpdatedAt = formatDate(updatedAt) val dateLabel = if (createdAt != updatedAt) { - "Modified $formattedUpdatedAt" + stringResource(R.string.txt_modified, formattedUpdatedAt) } else { - "Created $formattedCreatedAt" + stringResource(R.string.txt_created, formattedCreatedAt) } val refreshState = rememberPullToRefreshState() var showMoreBottomSheet by remember { mutableStateOf(false) } val sheetShowMoreState = rememberModalBottomSheetState() var showDeleteConfirmationDialog by remember { mutableStateOf(false) } + var showStudyFolderBottomSheet by remember { mutableStateOf(false) } + val sheetStudyFolderState = rememberModalBottomSheetState() Scaffold( modifier = modifier, @@ -219,7 +228,9 @@ fun FolderDetail( floatingActionButton = { if (isOwner) { FloatingActionButton( - onClick = onStudyFolderClick, + onClick = { + showStudyFolderBottomSheet = true + }, containerColor = colorScheme.secondary, contentColor = colorScheme.onSecondary ) { @@ -292,6 +303,48 @@ fun FolderDetail( onDismissRequest = { showMoreBottomSheet = false }, isOwner = isOwner ) + if(showStudyFolderBottomSheet) { + ModalBottomSheet( + onDismissRequest = { showStudyFolderBottomSheet = false }, + sheetState = sheetStudyFolderState, + containerColor = colorScheme.surface, + ) { + Column ( + modifier = Modifier + .padding(vertical = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ){ + LearnModeCard( + title = stringResource(R.string.txt_flip_flashcards), + icon = R.drawable.ic_flipcard, + containerColor = colorScheme.surface, + elevation = 0.dp, + leadingText = stringResource(R.string.txt_coming_soon) + ) + LearnModeCard( + title = stringResource(R.string.txt_quiz), + icon = R.drawable.ic_quiz, + containerColor = colorScheme.surface, + elevation = 0.dp, + leadingText = stringResource(R.string.txt_coming_soon) + ) + LearnModeCard( + title = stringResource(R.string.txt_true_false), + icon = R.drawable.ic_tf, + containerColor = colorScheme.surface, + elevation = 0.dp, + leadingText = stringResource(R.string.txt_coming_soon) + ) + LearnModeCard( + title = stringResource(R.string.txt_write), + icon = R.drawable.ic_write, + containerColor = Color.Transparent, + elevation = 0.dp, + leadingText = stringResource(R.string.txt_coming_soon) + ) + } + } + } } @Preview(showBackground = true) diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/folder/detail/FolderDetailViewModel.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/folder/detail/FolderDetailViewModel.kt index 68d6babc..2f7d9a78 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/folder/detail/FolderDetailViewModel.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/folder/detail/FolderDetailViewModel.kt @@ -37,6 +37,7 @@ class FolderDetailViewModel @Inject constructor( val id: String = savedStateHandle["id"] ?: "" _uiState.update { it.copy(id = id) } getFolderSetById(id) + saveRecentAccessFolder(id) } fun onEvent(event: FolderDetailUiAction) { @@ -94,7 +95,6 @@ class FolderDetailViewModel @Inject constructor( } ?: run { _uiEvent.send(FolderDetailUiEvent.ShowError("Folder not found")) } - saveRecentAccessFolder() } is Resources.Error -> { @@ -138,11 +138,10 @@ class FolderDetailViewModel @Inject constructor( } } - private fun saveRecentAccessFolder() { + private fun saveRecentAccessFolder(folderId: String) { viewModelScope.launch { val token = tokenManager.accessToken.firstOrNull() ?: "" val userId = appManager.userId.firstOrNull() ?: "" - val folderId = _uiState.value.id val saveRecentAccessFolderRequestModel = SaveRecentAccessFolderRequestModel( userId = userId, folderId = folderId diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/settings/SettingsScreen.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/settings/SettingsScreen.kt index e1855b3e..d6a743b3 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/settings/SettingsScreen.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/settings/SettingsScreen.kt @@ -4,7 +4,6 @@ import android.content.Intent import android.net.Uri import android.os.Build import android.provider.Settings -import android.widget.Toast import androidx.annotation.RequiresApi import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement @@ -488,13 +487,13 @@ fun Setting( } } item { - SettingTitleSection(title = "Scheduled Notifications") + SettingTitleSection(title = stringResource(R.string.txt_scheduled_notifications)) SettingCard { Column( modifier = Modifier.padding(16.dp) ) { SettingSwitch( - title = "Study Reminders", + title = stringResource(R.string.txt_study_reminders), value = enabledStudySchedule, onChangeValue = { if (isPushNotificationsEnabled) { @@ -504,22 +503,16 @@ fun Setting( } } ) - HorizontalDivider() - SettingItem( - title = "Every day at", - leadingText = timeStudySchedule, - onClick = { - if (enabledStudySchedule) { + if (enabledStudySchedule) { + HorizontalDivider() + SettingItem( + title = stringResource(R.string.txt_every_day_at), + leadingText = timeStudySchedule, + onClick = { showTimePicker = true - } else { - Toast.makeText( - context, - "Please enable Study Reminders", - Toast.LENGTH_SHORT - ).show() } - } - ) + ) + } } } } @@ -732,10 +725,10 @@ fun Setting( onEnablePushNotifications(true) onChangeStudyAlarm(true) }, - title = "Turn on notifications to receive study reminders", - text = "You need to enable notifications in the app settings to receive study reminders", - confirmButtonTitle = "Turn on notifications", - dismissButtonTitle = "Not now", + title = stringResource(R.string.txt_turn_on_notifications_to_receive_study_reminders), + text = stringResource(R.string.txt_you_need_to_enable_notifications_in_the_app_settings_to_receive_study_reminders), + confirmButtonTitle = stringResource(R.string.txt_turn_on_notifications), + dismissButtonTitle = stringResource(R.string.txt_not_now), buttonColor = colorScheme.primary ) } diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/StudySetDetailViewModel.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/StudySetDetailViewModel.kt index 24222f91..9efa72a0 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/StudySetDetailViewModel.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/StudySetDetailViewModel.kt @@ -42,6 +42,7 @@ class StudySetDetailViewModel @Inject constructor( val id: String = savedStateHandle["id"] ?: "" _uiState.update { it.copy(id = id) } initData() + saveRecentAccessStudySet(studySetId = id) } private fun initData() { @@ -120,7 +121,6 @@ class StudySetDetailViewModel @Inject constructor( isOwner = isOwner, ) } - saveRecentAccessStudySet() } is Resources.Error -> { @@ -132,11 +132,10 @@ class StudySetDetailViewModel @Inject constructor( } } - private fun saveRecentAccessStudySet() { + private fun saveRecentAccessStudySet(studySetId: String) { viewModelScope.launch { val token = tokenManager.accessToken.firstOrNull() ?: "" val userId = appManager.userId.firstOrNull() ?: "" - val studySetId = _uiState.value.id val saveRecentAccessStudySetRequestModel = SaveRecentAccessStudySetRequestModel( userId = userId, studySetId = studySetId diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/material/LearnModeCard.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/material/LearnModeCard.kt index 5f47a2ca..483863a2 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/material/LearnModeCard.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/material/LearnModeCard.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.pwhs.quickmem.R @@ -32,15 +33,20 @@ fun LearnModeCard( @DrawableRes icon: Int, onClick: () -> Unit = {}, color: Color = colorScheme.primary, - learningPercentage: Int = 0 + leadingText: String = "", + learningPercentage: Int? = null, + containerColor: Color = Color.White, + contentColor: Color = colorScheme.onSurface, + elevation: Dp = 5.dp ) { Card( colors = CardDefaults.cardColors( - containerColor = Color.White, - contentColor = colorScheme.onSurface + containerColor = containerColor, + contentColor = contentColor ), elevation = CardDefaults.elevatedCardElevation( - defaultElevation = 5.dp + defaultElevation = elevation, + pressedElevation = elevation ), onClick = onClick, modifier = modifier @@ -71,13 +77,21 @@ fun LearnModeCard( ), modifier = Modifier.weight(1f) ) - Text( - text = "$learningPercentage%", - style = typography.bodyMedium.copy( - color = colorScheme.onSurface, - fontWeight = FontWeight.Bold + if (learningPercentage != null) { + LearnModeCard( + title = stringResource(R.string.txt_flip_flashcards), + icon = R.drawable.ic_flipcard, ) - ) + } + if (leadingText.isNotEmpty()) { + Text( + text = leadingText, + style = typography.bodyMedium.copy( + color = colorScheme.onSurface, + fontWeight = FontWeight.Bold + ) + ) + } } } } \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index c1503178..d42604ad 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -360,4 +360,15 @@ Vui lòng đăng ký hoặc đăng nhập vào ứng dụng Không tìm thấy class Restart + Bật thông báo để nhận nhắc nhở học tập + Bạn cần bật thông báo trong cài đặt ứng dụng để nhận nhắc nhở học tập + Bật thông báo + Không phải bây giờ + Thông báo đã lên lịch + Nhắc nhở học tập + Mỗi ngày vào lúc + Vui lòng bật nhắc nhở học tập + Đã chỉnh sửa vào %1$s + Đã tạo vào %1$s + Sắp ra mắt \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 83ff4192..eb16740d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -363,4 +363,15 @@ Unauthorized Class not found Restart + Turn on notifications to receive study reminders + You need to enable notifications in the app settings to receive study reminders + Turn on notifications + Not now + Scheduled Notifications + Study Reminders + Every day at + Please enable Study Reminders + Modified %1$s + Created %1$s + Coming soon \ No newline at end of file