diff --git a/app/src/main/java/com/example/notimanager/presentation/stateholder/viewmodel/NotificationAppViewModel.kt b/app/src/main/java/com/example/notimanager/presentation/stateholder/viewmodel/NotificationAppViewModel.kt index d90fc70..17a3989 100644 --- a/app/src/main/java/com/example/notimanager/presentation/stateholder/viewmodel/NotificationAppViewModel.kt +++ b/app/src/main/java/com/example/notimanager/presentation/stateholder/viewmodel/NotificationAppViewModel.kt @@ -42,10 +42,11 @@ class NotificationAppViewModel @Inject constructor( } } - fun deleteNotificationApp(appName: String) { + fun deleteNotificationApp(appName: String, onComplete: () -> Unit) { viewModelScope.launch { notificationAppUseCase.deleteNotificationApp(appName) loadNotificationApps() + onComplete() } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/BoxView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/BoxView.kt deleted file mode 100644 index 75f13c4..0000000 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/BoxView.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.notimanager.presentation.ui.component - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp - -@Composable -fun ClickableTextView(text: String, onClick: () -> Unit) { - Box( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(16.dp) - ) { - Text( - text = text, - style = MaterialTheme.typography.bodyMedium - ) - } -} diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/NotificationAppListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/NotificationAppListView.kt deleted file mode 100644 index 65885a5..0000000 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/NotificationAppListView.kt +++ /dev/null @@ -1,238 +0,0 @@ -package com.example.notimanager.presentation.ui.component - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.livedata.observeAsState -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.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.navigation.NavController -import com.example.notimanager.R -import com.example.notimanager.common.objects.DateFormatter.formatTimestamp -import com.example.notimanager.domain.model.NotificationApp -import com.example.notimanager.presentation.stateholder.state.NotificationAppPriorityState -import com.example.notimanager.presentation.stateholder.state.NotificationAppState -import com.example.notimanager.presentation.stateholder.viewmodel.FilteredNotificationViewModel -import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppPriorityViewModel -import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppViewModel - -@Composable -fun NotificationAppListView( - navController: NavController, - viewModel: NotificationAppViewModel, - priorityViewModel: NotificationAppPriorityViewModel -) { - val notificationAppState by viewModel.notificationAppState.observeAsState(NotificationAppState()) - val priorityState by priorityViewModel.notificationAppPriorityState.observeAsState((NotificationAppPriorityState())) - var currentNotiPriority by remember { mutableStateOf(priorityState.notificationAppList) } - var currentNoti by remember { mutableStateOf(notificationAppState.notificationAppList) } - - LaunchedEffect(priorityState.notificationAppList) { - if (!priorityState.isLoading) { - currentNotiPriority = priorityState.notificationAppList - } - } - - LaunchedEffect(notificationAppState.notificationAppList) { - if (!notificationAppState.isLoading) { - currentNoti = notificationAppState.notificationAppList - } - } - - LazyColumn( - Modifier.fillMaxSize() - ) { - items(currentNotiPriority) { notification -> - NotificationAppItemView( - notification = notification, - onClick = { - navController - .navigate( - "titleScreen/${notification.appName}" - ) - }, - viewModel = viewModel, - priorityViewModel = priorityViewModel - ) - } - - item { - HorizontalDivider() - } - - items(currentNoti) { notification -> - NotificationAppItemView( - notification = notification, - onClick = { - navController - .navigate( - "titleScreen/${notification.appName}" - ) - }, - viewModel = viewModel, - priorityViewModel = priorityViewModel - ) - } - } -} - -@Composable -fun NotificationAppItemView( - notification: NotificationApp, - onClick: () -> Unit, - viewModel: NotificationAppViewModel, - priorityViewModel: NotificationAppPriorityViewModel, - filteredNotificationViewModel: FilteredNotificationViewModel = hiltViewModel() -) { - // 언어 설정에 따라 문자열 리소스를 가져오기 - val context = LocalContext.current - val addFiltered = context.getString(R.string.modal_add_filtered) - val addPriority = context.getString(R.string.modal_add_priority) - val removeFiltered = context.getString(R.string.modal_remove_filtered) - val removePriority = context.getString(R.string.modal_remove_priority) - val delete = context.getString(R.string.modal_delete) - // 위의 문자열 리소스는 모달에서 사용할 텍스트 - - var showModal by remember { mutableStateOf(false) } - - Row( - modifier = Modifier - .padding(16.dp) - .fillMaxWidth() - .clickable(onClick = onClick) - , - verticalAlignment = Alignment.CenterVertically - ) { - AppIconView(notification.appIcon) - Spacer(modifier = Modifier.width(8.dp)) - Column( - modifier = Modifier.weight(1f) - ) { - Text( - text = notification.appName, - style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold)) - Text( - text = notification.title, - style = MaterialTheme.typography.bodySmall.copy(fontWeight = FontWeight.Bold) - ) - Text( - text = notification.content, - style = MaterialTheme.typography.bodySmall, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = formatTimestamp(context, notification.timestamp), - style = MaterialTheme.typography.labelSmall, - color = Color.LightGray - ) - } - - // 더보기 - IconButton(onClick = { showModal = true }) { - Icon(Icons.Filled.MoreVert, contentDescription = "중요 표시 또는 삭제") - } - } - // 더보기 클릭 시 나오는 모달창 - if (showModal) { - BottomSheet(showModal, onDismiss = { showModal = false }){ - Column( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - // 알림 제목 - Text( - text = notification.appName, - style = MaterialTheme.typography.labelLarge, - color = Color.Gray - ) - - // 상단 고정 여부 버튼 - if (notification.priorityActive) { - ClickableTextView(text = removePriority, onClick = { - priorityViewModel.removeAppPriority(notification.appName){ - viewModel.loadNotificationApps() - } - showModal = false - }) - } - else{ - ClickableTextView(text = addPriority, onClick = { - viewModel.setAppPriority(notification.appName, priorityViewModel.getLength()){ - priorityViewModel.loadNotificationAppPriority() - } - showModal = false - }) - } - - // 삭제 버튼 - ClickableTextView(text = delete, onClick = { - viewModel.deleteNotificationApp(notification.appName) - showModal = false - }) - - // 수집 여부 버튼 - ClickableTextView(text = if (notification.filteredId == 0L) addFiltered else removeFiltered, onClick = { - if (notification.filteredId == 0L) filteredNotificationViewModel.insertFilteredNoti(notification.appName, ""){ - viewModel.loadNotificationApps() - priorityViewModel.loadNotificationAppPriority() - } - else filteredNotificationViewModel.deleteFilteredNoti(notification.filteredId){ - viewModel.loadNotificationApps() - priorityViewModel.loadNotificationAppPriority() - } - showModal = false - }) - } - } - } -} - -@Composable -@Preview -fun PreviewNotificationAppItemView(){ - MaterialTheme{ - NotificationAppItemView( - notification = NotificationApp( - appName = "appName", - title = "title", - content = "content", - timestamp = 1234567890, - appIcon = null, - priorityActive = false, - priority = 0, - filteredId = 0L - ), onClick = {}, - viewModel = hiltViewModel(), - priorityViewModel = hiltViewModel() - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/NotificationTitleListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/NotificationTitleListView.kt deleted file mode 100644 index 4d7e3e4..0000000 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/NotificationTitleListView.kt +++ /dev/null @@ -1,255 +0,0 @@ -package com.example.notimanager.presentation.ui.component - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.material3.Badge -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.livedata.observeAsState -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.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.navigation.NavController -import com.example.notimanager.R -import com.example.notimanager.common.objects.DateFormatter.formatTimestamp -import com.example.notimanager.common.objects.Encoder.getEncodedString -import com.example.notimanager.domain.model.NotificationTitle -import com.example.notimanager.presentation.stateholder.state.NotificationTitlePriorityState -import com.example.notimanager.presentation.stateholder.state.NotificationTitleState -import com.example.notimanager.presentation.stateholder.viewmodel.FilteredNotificationViewModel -import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitlePriorityViewModel -import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitleViewModel - -@Composable -fun NotificationTitleListView( - navController: NavController, - viewModel: NotificationTitleViewModel, - priorityViewModel: NotificationTitlePriorityViewModel -) { - val notificationTitleState by viewModel.notificationTitleState.observeAsState( - NotificationTitleState() - ) - val priorityState by priorityViewModel.notificationTitlePriorityState.observeAsState( - NotificationTitlePriorityState() - ) - var currentNotiPriority by remember { mutableStateOf(priorityState.notificationTitleList) } - var currentNoti by remember { mutableStateOf(notificationTitleState.notificationTitleList) } - - LaunchedEffect(priorityState.notificationTitleList) { - if (!priorityState.isLoading) { - currentNotiPriority = priorityState.notificationTitleList - } - } - - LaunchedEffect(notificationTitleState.notificationTitleList) { - if (!notificationTitleState.isLoading) { - currentNoti = notificationTitleState.notificationTitleList - } - } - - LazyColumn( - modifier = Modifier.fillMaxSize() - ) { - items(currentNotiPriority) { notification -> - NotificationTitleItemView(notification = notification, onClick = { - if (notification.subText == "") navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.title)}/False") - else navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.subText)}/True") - - - }, viewModel = viewModel, priorityViewModel = priorityViewModel) - } - - item { - HorizontalDivider() - } - - items(currentNoti) { notification -> - NotificationTitleItemView(notification = notification, onClick = { - if (notification.subText == "") { - viewModel.updateAsRead(notification.title) - navController.navigate( - "notificationScreen/${viewModel.getAppName()}/${ - getEncodedString( - notification.title - ) - }/False" - ) - } - else { - viewModel.updateAsSubText(notification.subText) - navController.navigate( - "notificationScreen/${viewModel.getAppName()}/${ - getEncodedString( - notification.subText - ) - }/True" - ) - }}, viewModel = viewModel, priorityViewModel = priorityViewModel) - } - } -} - -@Composable -fun NotificationTitleItemView( - notification: NotificationTitle, - onClick: () -> Unit, - viewModel: NotificationTitleViewModel, - priorityViewModel: NotificationTitlePriorityViewModel, - filteredNotificationViewModel: FilteredNotificationViewModel = hiltViewModel() -) { - // 언어 설정에 따라 문자열 리소스를 가져오기 - val context = LocalContext.current - val addFiltered = context.getString(R.string.modal_add_filtered) - val addPriority = context.getString(R.string.modal_add_priority) - val removeFiltered = context.getString(R.string.modal_remove_filtered) - val removePriority = context.getString(R.string.modal_remove_priority) - val delete = context.getString(R.string.modal_delete) - // 위의 문자열 리소스는 모달에서 사용할 텍스트 - - var showModal by remember { mutableStateOf(false) } - Row( - modifier = Modifier - .padding(16.dp) - .fillMaxWidth() - .clickable(onClick = onClick), - verticalAlignment = Alignment.CenterVertically - ) { - AppIconView(notification.notificationIcon) - Spacer(modifier = Modifier.width(8.dp)) - Column ( - modifier = Modifier.weight(1f) - ){ - Text( - text = if (notification.subText == "") notification.title else notification.subText , - style = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.Bold) - ) - Text( - text = notification.content, - style = MaterialTheme.typography.bodySmall, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = formatTimestamp(context, notification.timestamp), - style = MaterialTheme.typography.labelSmall, - color = Color.LightGray - ) - } - if (notification.unreadCount != 0){ - Badge { - Text(notification.unreadCount.toString()) - } - } - - IconButton(onClick = { showModal = true }) { - Icon(Icons.Filled.MoreVert, contentDescription = "더보기") - } - } - - if (showModal) { - BottomSheet(showModal, onDismiss = { showModal = false }){ - Column( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - Text( - text = if (notification.subText == "") notification.title else notification.subText, - style = MaterialTheme.typography.labelLarge, - color = Color.Gray - ) - - if (notification.priorityActive) { - ClickableTextView(text = removePriority, onClick = { - priorityViewModel.removeTitlePriority(notificationId = notification.id){ - viewModel.loadNotificationTitles() - } - showModal = false - }) - } - else{ - ClickableTextView(text = addPriority, onClick = { - viewModel.setTitlePriority(notification.id, priorityViewModel.getLength()){ - priorityViewModel.loadNotificationTitles() - } - showModal = false - }) - } - - ClickableTextView(text = delete, onClick = { - if (notification.subText == "") - viewModel.deleteByTitle(notification.title) { priorityViewModel.loadNotificationTitles() } - else - viewModel.deleteBySubText(notification.subText) { priorityViewModel.loadNotificationTitles() } - showModal = false - }) - - val onComplete: () -> Unit = { - viewModel.loadNotificationTitles() - priorityViewModel.loadNotificationTitles() - } - - if(notification.filteredId == 0L) { - ClickableTextView( - text = addFiltered, - onClick = { - if (notification.subText == "") { - filteredNotificationViewModel.insertFilteredNoti( - viewModel.getAppName(), - notification.title, - onComplete - ) - } - else{ - filteredNotificationViewModel.insertFilteredNoti( - viewModel.getAppName(), - notification.subText, - onComplete - ) - } - showModal = false - } - ) - }else{ - ClickableTextView( - text = removeFiltered, - onClick = { - if (notification.subText == "") - filteredNotificationViewModel.deleteFilteredNoti(notification.filteredId, onComplete) - - else - filteredNotificationViewModel.deleteFilteredNoti(notification.filteredId, onComplete) - showModal = false - } - ) - } - } - } - } -} - diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/SettingView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/SettingView.kt index d1c8a57..56fca71 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/SettingView.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/SettingView.kt @@ -12,6 +12,7 @@ import androidx.navigation.NavController import com.example.notimanager.R import com.example.notimanager.presentation.stateholder.viewmodel.NotificationPermissionViewModel import com.example.notimanager.presentation.stateholder.viewmodel.NotificationServicePermissionViewModel +import com.example.notimanager.presentation.ui.component.box.ClickableTextView @Composable fun SettingView( @@ -33,23 +34,23 @@ fun SettingView( .padding(innerPadding) ) { // 받지 않는 알림 목록 - ClickableTextView(filteredList) { - navController.navigate("FilteredListScreen") + ClickableTextView(filteredList, onClick = {navController.navigate("FilteredListScreen")}) { + } // 알림 접근 권한 - ClickableTextView(accessPermission) { - servicePermissionViewModel.requestServicePermission() + ClickableTextView(accessPermission, onClick = {servicePermissionViewModel.requestServicePermission()}) { + } // 알림 발송 권한 - ClickableTextView(sendPermission) { - notificationPermissionViewModel.requestPermission(context as Activity) + ClickableTextView(sendPermission, onClick = {notificationPermissionViewModel.requestPermission(context as Activity)}) { + } // 시간 형식 변경 - ClickableTextView(dateFormatter) { - navController.navigate("DateFormatterScreen") + ClickableTextView(dateFormatter, onClick = {navController.navigate("DateFormatterScreen")}) { + } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/TopAppBar.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/TopAppBar.kt deleted file mode 100644 index d2b1e98..0000000 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/TopAppBar.kt +++ /dev/null @@ -1,119 +0,0 @@ -package com.example.notimanager.presentation.ui.component - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.filled.Menu -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import com.example.notimanager.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MainTopAppBar(settingOnClick: () -> Unit){ - // 언어 설정에 따라 문자열 리소스를 가져오기 - val context = LocalContext.current - val appName = context.getString(R.string.app_name) - - TopAppBar( - title = { - Text(text = appName) - }, - navigationIcon = { - IconButton(onClick = settingOnClick) { - Icon(Icons.Filled.Menu, contentDescription = "설정") - } - } - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun TitleTopAppBar(title: String, onBackClick: () -> Unit){ - TopAppBar( - title = { - Text( - text = title, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - }, - navigationIcon = { - IconButton(onClick = onBackClick) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "뒤로 가기") - } - } - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun NotificationTopAppBar(title: String, onBackClick: () -> Unit){ - TopAppBar( - title = { - Text( - text = title, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - }, - navigationIcon = { - IconButton(onClick = onBackClick) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "뒤로 가기") - } - }, - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SettingTopAppBar(onBackClick: () -> Unit){ - // 언어 설정에 따라 문자열 리소스를 가져오기 - val context = LocalContext.current - val name = context.getString(R.string.setting_name) - - TopAppBar( - title = { - Text(text = name) - }, - navigationIcon = { - IconButton(onClick = onBackClick) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "뒤로 가기") - } - } - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun FilteredTopAppBar(onBackClick: () -> Unit){ - // 언어 설정에 따라 문자열 리소스를 가져오기 - val context = LocalContext.current - val name = context.getString(R.string.setting_filtered_list) - - TopAppBar( - title = { - Text(text = name) - }, - navigationIcon = { - IconButton(onClick = onBackClick) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "뒤로 가기") - } - } - ) -} - -@Preview(backgroundColor = 1) -@Composable -fun PreviewMainTopAppBar(){ - MaterialTheme{ - MainTopAppBar({}) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/box/BoxView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/BoxView.kt new file mode 100644 index 0000000..dcbcf5f --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/BoxView.kt @@ -0,0 +1,39 @@ +package com.example.notimanager.presentation.ui.component.box + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.MaterialTheme +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 ClickableTextView( + text: String, + onClick: () -> Unit, + icon: @Composable (() -> Unit)? = null +) { + Box( + modifier = Modifier + .fillMaxWidth() + .clickable(onClick = onClick) + .padding(16.dp) + ) { + Row(verticalAlignment = Alignment.CenterVertically) { + icon?.invoke() + if(icon != null) Spacer(modifier = Modifier.width(16.dp)) + Text( + text = text, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.align(Alignment.CenterVertically) + ) + } + } +} diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/box/DeleteBox.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/DeleteBox.kt new file mode 100644 index 0000000..a309d7e --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/DeleteBox.kt @@ -0,0 +1,26 @@ +package com.example.notimanager.presentation.ui.component.box + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.example.notimanager.R + +@Composable +fun DeleteBox(onClick: () -> Unit){ + val context = LocalContext.current + val delete = context.getString(R.string.modal_delete) + ClickableTextView(text = delete, onClick = onClick) { + Image( + painter = painterResource(id = R.drawable.delete), + contentDescription = "delete icon", + modifier = Modifier.size(24.dp), + colorFilter = ColorFilter.tint(Color.Gray) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/box/FilteredBox.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/FilteredBox.kt new file mode 100644 index 0000000..dc19d21 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/FilteredBox.kt @@ -0,0 +1,40 @@ +package com.example.notimanager.presentation.ui.component.box + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.example.notimanager.R + +@Composable +fun AddFilteredBox(onClick: () -> Unit){ + val context = LocalContext.current + val addFiltered = context.getString(R.string.modal_add_filtered) + ClickableTextView(text = addFiltered, onClick = onClick){ + Image( + painter = painterResource(id = R.drawable.notifications_off), + contentDescription = "notifications off icon", + modifier = Modifier.size(24.dp), + colorFilter = ColorFilter.tint(Color.Gray) + ) + } +} + +@Composable +fun RemoveFilteredBox(onClick: () -> Unit){ + val context = LocalContext.current + val removeFiltered = context.getString(R.string.modal_remove_filtered) + ClickableTextView(text = removeFiltered, onClick = onClick){ + Image( + painter = painterResource(id = R.drawable.notifications), + contentDescription = "notifications icon", + modifier = Modifier.size(24.dp), + colorFilter = ColorFilter.tint(Color.Gray) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/box/MoveToAppBox.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/MoveToAppBox.kt new file mode 100644 index 0000000..cf1732c --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/MoveToAppBox.kt @@ -0,0 +1,26 @@ +package com.example.notimanager.presentation.ui.component.box + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.example.notimanager.R + +@Composable +fun MoveToAppBox(onClick: () -> Unit){ + val context = LocalContext.current + val moveToApp = context.getString(R.string.modal_move_to_app) + ClickableTextView(text = moveToApp, onClick = onClick){ + Image( + painter = painterResource(id = R.drawable.input), + contentDescription = "moveToApp icon", + modifier = Modifier.size(24.dp), + colorFilter = ColorFilter.tint(Color.Gray) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/box/PrioirityBox.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/PrioirityBox.kt new file mode 100644 index 0000000..e96ef45 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/box/PrioirityBox.kt @@ -0,0 +1,43 @@ +package com.example.notimanager.presentation.ui.component.box + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Star +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.example.notimanager.R + +@Composable +fun AddPriorityBox(onClick: () -> Unit){ + val context = LocalContext.current + val addPriority = context.getString(R.string.modal_add_priority) + ClickableTextView(text = addPriority, onClick = onClick){ + Icon( + imageVector = Icons.Filled.Star, + contentDescription = "filled star icon", + modifier = Modifier.size(24.dp), + tint = Color.Gray + ) + } +} + +@Composable +fun RemovePriorityBox(onClick: () -> Unit){ + val context = LocalContext.current + val removePriority = context.getString(R.string.modal_remove_priority) + ClickableTextView(text = removePriority, onClick = onClick){ + Image( + painter = painterResource(id = R.drawable.star), + contentDescription = "star icon", + modifier = Modifier.size(24.dp), + colorFilter = ColorFilter.tint(Color.Gray) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/AppIconView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/common/AppIconView.kt similarity index 91% rename from app/src/main/java/com/example/notimanager/presentation/ui/component/AppIconView.kt rename to app/src/main/java/com/example/notimanager/presentation/ui/component/common/AppIconView.kt index 03594bd..c3425d8 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/AppIconView.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/common/AppIconView.kt @@ -1,4 +1,4 @@ -package com.example.notimanager.presentation.ui.component +package com.example.notimanager.presentation.ui.component.common import android.graphics.Bitmap import androidx.compose.foundation.Image diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/ModalView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/common/ModalView.kt similarity index 93% rename from app/src/main/java/com/example/notimanager/presentation/ui/component/ModalView.kt rename to app/src/main/java/com/example/notimanager/presentation/ui/component/common/ModalView.kt index d1ae502..fa4ffca 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/ModalView.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/common/ModalView.kt @@ -1,4 +1,4 @@ -package com.example.notimanager.presentation.ui.component +package com.example.notimanager.presentation.ui.component.common import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalBottomSheet diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/PermissionDialog.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/common/PermissionDialog.kt similarity index 96% rename from app/src/main/java/com/example/notimanager/presentation/ui/component/PermissionDialog.kt rename to app/src/main/java/com/example/notimanager/presentation/ui/component/common/PermissionDialog.kt index 08b1c5b..7ce56cd 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/PermissionDialog.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/common/PermissionDialog.kt @@ -1,4 +1,4 @@ -package com.example.notimanager.presentation.ui.component +package com.example.notimanager.presentation.ui.component.common import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/common/TopAppBar.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/common/TopAppBar.kt new file mode 100644 index 0000000..87537e9 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/common/TopAppBar.kt @@ -0,0 +1,52 @@ +package com.example.notimanager.presentation.ui.component.common + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Menu +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.style.TextOverflow +import com.example.notimanager.R + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MainTopAppBar(settingOnClick: () -> Unit){ + // 언어 설정에 따라 문자열 리소스를 가져오기 + val context = LocalContext.current + val appName = context.getString(R.string.app_name) + + TopAppBar( + title = { + Text(text = appName) + }, + navigationIcon = { + IconButton(onClick = settingOnClick) { + Icon(Icons.Filled.Menu, contentDescription = "설정") + } + } + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun CommonTopAppBar(title: String, onBackClick: () -> Unit){ + TopAppBar( + title = { + Text( + text = title, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + }, + navigationIcon = { + IconButton(onClick = onBackClick) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "뒤로 가기") + } + } + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/FilteredListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/item/FilteredListItemView.kt similarity index 67% rename from app/src/main/java/com/example/notimanager/presentation/ui/component/FilteredListView.kt rename to app/src/main/java/com/example/notimanager/presentation/ui/component/item/FilteredListItemView.kt index 794f0c7..fa9a748 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/FilteredListView.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/item/FilteredListItemView.kt @@ -1,21 +1,16 @@ -package com.example.notimanager.presentation.ui.component +package com.example.notimanager.presentation.ui.component.item import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -27,42 +22,16 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.example.notimanager.R import com.example.notimanager.domain.model.FilteredNotification -import com.example.notimanager.presentation.stateholder.state.FilteredNotificationState import com.example.notimanager.presentation.stateholder.viewmodel.FilteredNotificationViewModel - -@Composable -fun FilteredListView( - innerPadding: PaddingValues, - viewModel: FilteredNotificationViewModel -) { - val filteredNotificationState by viewModel.filteredNotiState.observeAsState(FilteredNotificationState()) - if (filteredNotificationState.filteredList.isEmpty()){ - Text("No notifications") - } - else{ - LazyColumn( - Modifier - .fillMaxSize() - .padding(innerPadding) - ) { - - items(filteredNotificationState.filteredList) { item -> - FilteredItemView(item, viewModel) - } - } - } - -} +import com.example.notimanager.presentation.ui.component.common.BottomSheet +import com.example.notimanager.presentation.ui.component.box.ClickableTextView +import com.example.notimanager.presentation.ui.component.box.RemoveFilteredBox @Composable fun FilteredItemView( filteredItem: FilteredNotification, viewModel: FilteredNotificationViewModel, ) { - // 언어 설정에 따라 문자열 리소스를 가져오기 - val context = LocalContext.current - val removeFiltered = context.getString(R.string.modal_remove_filtered) - var showModal by remember { mutableStateOf(false) } Row( @@ -101,12 +70,12 @@ fun FilteredItemView( color = Color.Gray ) - ClickableTextView(text = removeFiltered, onClick = { + RemoveFilteredBox { viewModel.deleteFilteredNoti(filteredItem.id){ viewModel.loadFilteredNoti() } showModal = false - }) + } } } } diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/item/NotiAppListItemView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/item/NotiAppListItemView.kt new file mode 100644 index 0000000..585f148 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/item/NotiAppListItemView.kt @@ -0,0 +1,182 @@ +package com.example.notimanager.presentation.ui.component.item + +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.filled.Star +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +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.graphics.ColorFilter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import com.example.notimanager.R +import com.example.notimanager.common.objects.DateFormatter.formatTimestamp +import com.example.notimanager.domain.model.NotificationApp +import com.example.notimanager.presentation.stateholder.viewmodel.FilteredNotificationViewModel +import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppPriorityViewModel +import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppViewModel +import com.example.notimanager.presentation.ui.component.box.AddFilteredBox +import com.example.notimanager.presentation.ui.component.box.AddPriorityBox +import com.example.notimanager.presentation.ui.component.box.DeleteBox +import com.example.notimanager.presentation.ui.component.box.RemoveFilteredBox +import com.example.notimanager.presentation.ui.component.box.RemovePriorityBox +import com.example.notimanager.presentation.ui.component.common.AppIconView +import com.example.notimanager.presentation.ui.component.common.BottomSheet + +@Composable +fun NotificationAppItemView( + notification: NotificationApp, + onClick: () -> Unit, + viewModel: NotificationAppViewModel, + priorityViewModel: NotificationAppPriorityViewModel, + filteredNotificationViewModel: FilteredNotificationViewModel = hiltViewModel() +) { + val context = LocalContext.current + var showModal by remember { mutableStateOf(false) } + + Row( + modifier = Modifier + .padding(16.dp) + .fillMaxWidth() + .clickable(onClick = onClick) + , + verticalAlignment = Alignment.CenterVertically + ) { + AppIconView(notification.appIcon) + Spacer(modifier = Modifier.width(8.dp)) + Column( + modifier = Modifier.weight(1f) + ) { + Row( + verticalAlignment = Alignment.CenterVertically + ){ + Text( + text = notification.appName, + style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold) + ) + Spacer(modifier = Modifier.width(2.dp)) + if(notification.priorityActive) { + Icon( + imageVector = Icons.Filled.Star, + contentDescription = "중요 표시", + modifier = Modifier.size(12.dp), + tint = Color.Gray + ) + } + if(notification.filteredId != 0L) { + Image( + painter = painterResource(id = R.drawable.notifications_off), + contentDescription = "notification off icon", + modifier = Modifier.size(12.dp), + colorFilter = ColorFilter.tint(Color.Gray) + ) + } + } + + Text( + text = notification.title, + style = MaterialTheme.typography.bodySmall.copy(fontWeight = FontWeight.Bold) + ) + Text( + text = notification.content, + style = MaterialTheme.typography.bodySmall, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + Text( + text = formatTimestamp(context, notification.timestamp), + style = MaterialTheme.typography.labelSmall, + color = Color.LightGray + ) + } + + // 더보기 + IconButton(onClick = { showModal = true }) { + Icon(Icons.Filled.MoreVert, contentDescription = "중요 표시 또는 삭제") + } + } + // 더보기 클릭 시 나오는 모달창 + if (showModal) { + BottomSheet(showModal, onDismiss = { showModal = false }){ + Column( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + // 알림 제목 + Text( + text = notification.appName, + style = MaterialTheme.typography.labelLarge, + color = Color.Gray + ) + + // 삭제 버튼 + DeleteBox { + viewModel.deleteNotificationApp(notification.appName){ + priorityViewModel.loadNotificationAppPriority() + } + showModal = false + } + + // 관리 여부 버튼 + if (notification.filteredId == 0L){ + AddFilteredBox { + filteredNotificationViewModel.insertFilteredNoti(notification.appName, ""){ + viewModel.loadNotificationApps() + priorityViewModel.loadNotificationAppPriority() + } + showModal = false + } + } + else { + RemoveFilteredBox { + filteredNotificationViewModel.deleteFilteredNoti(notification.filteredId) { + viewModel.loadNotificationApps() + priorityViewModel.loadNotificationAppPriority() + } + showModal = false + } + } + // 중요 알림 설정 + if (notification.priorityActive) { + RemovePriorityBox { + priorityViewModel.removeAppPriority(notification.appName){ + viewModel.loadNotificationApps() + } + showModal = false + } + } + else{ + AddPriorityBox { + viewModel.setAppPriority(notification.appName, priorityViewModel.getLength()){ + priorityViewModel.loadNotificationAppPriority() + } + showModal = false + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/NotificationListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/item/NotiListItemView.kt similarity index 65% rename from app/src/main/java/com/example/notimanager/presentation/ui/component/NotificationListView.kt rename to app/src/main/java/com/example/notimanager/presentation/ui/component/item/NotiListItemView.kt index b0b7602..c0a0535 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/component/NotificationListView.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/item/NotiListItemView.kt @@ -1,17 +1,13 @@ -package com.example.notimanager.presentation.ui.component +package com.example.notimanager.presentation.ui.component.item import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -23,39 +19,12 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import com.example.notimanager.R import com.example.notimanager.common.objects.DateFormatter.formatTimestamp import com.example.notimanager.domain.model.Notification -import com.example.notimanager.presentation.stateholder.state.NotificationState - - -@Composable -fun NotificationListView( - notificationState: NotificationState, - onDelete: (Long) -> Unit - -) { - val context = LocalContext.current - var currentNoti by remember { mutableStateOf(notificationState.notificationList) } - - LaunchedEffect(notificationState.notificationList) { - if (!notificationState.isLoading) { - currentNoti = notificationState.notificationList - } - } - - LazyColumn( - modifier = Modifier.fillMaxSize() - ) { - items(currentNoti) { notification -> - NotificationItemView (notification = notification, onClick = { - if (notification.intent?.action != null) - context.startActivity(notification.intent) }, - onDelete = onDelete - ) - } - } -} +import com.example.notimanager.presentation.ui.component.box.DeleteBox +import com.example.notimanager.presentation.ui.component.box.MoveToAppBox +import com.example.notimanager.presentation.ui.component.common.AppIconView +import com.example.notimanager.presentation.ui.component.common.BottomSheet @Composable fun NotificationItemView( @@ -63,11 +32,7 @@ fun NotificationItemView( onClick: () -> Unit, onDelete: (Long) -> Unit ) { - // 언어 설정에 따라 문자열 리소스를 가져오기 val context = LocalContext.current - val moveToApp = context.getString(R.string.modal_move_to_app) - val delete = context.getString(R.string.modal_delete) - // 위의 문자열 리소스는 모달에서 사용할 텍스트 var showModal by remember { mutableStateOf(false) } Row( @@ -98,6 +63,7 @@ fun NotificationItemView( ) } + // 모달창 if (showModal) { BottomSheet(showModal, onDismiss = { showModal = false }){ Column( @@ -117,15 +83,18 @@ fun NotificationItemView( overflow = TextOverflow.Ellipsis, color = Color.Gray ) - ClickableTextView(text = moveToApp, onClick = { - onClick() - showModal = false - }) - ClickableTextView(text = delete, onClick = { + // 삭제 + DeleteBox { onDelete(notification.id) showModal = false - }) + } + + // 앱으로 이동하기 + MoveToAppBox { + onClick() + showModal = false + } } } } diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/item/NotiTitleListItemView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/item/NotiTitleListItemView.kt new file mode 100644 index 0000000..1161896 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/item/NotiTitleListItemView.kt @@ -0,0 +1,207 @@ +package com.example.notimanager.presentation.ui.component.item + +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.filled.Star +import androidx.compose.material3.Badge +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +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.graphics.ColorFilter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import com.example.notimanager.R +import com.example.notimanager.common.objects.DateFormatter.formatTimestamp +import com.example.notimanager.domain.model.NotificationTitle +import com.example.notimanager.presentation.stateholder.viewmodel.FilteredNotificationViewModel +import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitlePriorityViewModel +import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitleViewModel +import com.example.notimanager.presentation.ui.component.box.AddFilteredBox +import com.example.notimanager.presentation.ui.component.box.AddPriorityBox +import com.example.notimanager.presentation.ui.component.common.AppIconView +import com.example.notimanager.presentation.ui.component.common.BottomSheet +import com.example.notimanager.presentation.ui.component.box.DeleteBox +import com.example.notimanager.presentation.ui.component.box.RemoveFilteredBox +import com.example.notimanager.presentation.ui.component.box.RemovePriorityBox + +@Composable +fun NotificationTitleItemView( + notification: NotificationTitle, + onClick: () -> Unit, + viewModel: NotificationTitleViewModel, + priorityViewModel: NotificationTitlePriorityViewModel, + filteredNotificationViewModel: FilteredNotificationViewModel = hiltViewModel() +) { + val context = LocalContext.current + var showModal by remember { mutableStateOf(false) } + Row( + modifier = Modifier + .padding(16.dp) + .fillMaxWidth() + .clickable(onClick = onClick), + verticalAlignment = Alignment.CenterVertically + ) { + AppIconView(notification.notificationIcon) + Spacer(modifier = Modifier.width(8.dp)) + Column ( + modifier = Modifier.weight(1f) + ){ + // 알림 제목, 옆에 중요 알림, 필터링 알림일 경우에 대한 아이콘 표시 + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = if (notification.subText == "") notification.title else notification.subText , + style = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.Bold) + ) + Spacer(modifier = Modifier.width(2.dp)) + if(notification.priorityActive) { + Icon( + imageVector = Icons.Filled.Star, + contentDescription = "중요 표시", + modifier = Modifier.size(12.dp), + tint = Color.Gray + ) + } + if(notification.filteredId != 0L) { + Image( + painter = painterResource(id = R.drawable.notifications_off), + contentDescription = "notification off icon", + modifier = Modifier.size(12.dp), + colorFilter = ColorFilter.tint(Color.Gray) + ) + } + } + + // 알림 내용 + Text( + text = notification.content, + style = MaterialTheme.typography.bodySmall, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + + // 알림 받은 시간 + Text( + text = formatTimestamp(context, notification.timestamp), + style = MaterialTheme.typography.labelSmall, + color = Color.LightGray + ) + } + + // 읽지 않은 알림 수 표시 뱃지 + if (notification.unreadCount != 0){ + Badge { + Text(notification.unreadCount.toString()) + } + } + + // 더보기 버튼, 클릭 시 모달창 켜짐 + IconButton(onClick = { showModal = true }) { + Icon(Icons.Filled.MoreVert, contentDescription = "더보기") + } + } + + // 모달창 + if (showModal) { + BottomSheet(showModal, onDismiss = { showModal = false }){ + Column( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + // 알림 제목 + Text( + text = if (notification.subText == "") notification.title else notification.subText, + style = MaterialTheme.typography.labelLarge, + color = Color.Gray + ) + + // 삭제 버튼 + DeleteBox { + if (notification.subText == "") + viewModel.deleteByTitle(notification.title) { priorityViewModel.loadNotificationTitles() } + else + viewModel.deleteBySubText(notification.subText) { priorityViewModel.loadNotificationTitles() } + showModal = false + } + + // 특정 동작 완료 후 동작 + val onComplete: () -> Unit = { + viewModel.loadNotificationTitles() + priorityViewModel.loadNotificationTitles() + } + + // 알림 관리하지 않기 버튼 + if(notification.filteredId == 0L) { // 관리 중 -> 관리 중 X + AddFilteredBox { + if (notification.subText == "") { // subText가 제목인 경우 + filteredNotificationViewModel.insertFilteredNoti( + viewModel.getAppName(), + notification.title, + onComplete + ) + } + else{ // title이 제목인 경우 + filteredNotificationViewModel.insertFilteredNoti( + viewModel.getAppName(), + notification.subText, + onComplete + ) + } + showModal = false + } + } else{ // 관리 중 X -> 관리 중 + RemoveFilteredBox { + if (notification.subText == "") + filteredNotificationViewModel.deleteFilteredNoti(notification.filteredId, onComplete) + else + filteredNotificationViewModel.deleteFilteredNoti(notification.filteredId, onComplete) + showModal = false + } + } + + // 중요 알림 설정 버튼 + if (notification.priorityActive) { // 중요 알림일 때 + RemovePriorityBox { + priorityViewModel.removeTitlePriority(notificationId = notification.id){ + viewModel.loadNotificationTitles() + } + showModal = false + } + } + else{ // 중요 알림이 아닐 때 + AddPriorityBox { + viewModel.setTitlePriority(notification.id, priorityViewModel.getLength()){ + priorityViewModel.loadNotificationTitles() + } + showModal = false + } + } + } + } + } +} + diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/FilteredListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/FilteredListView.kt new file mode 100644 index 0000000..f2cd215 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/FilteredListView.kt @@ -0,0 +1,40 @@ +package com.example.notimanager.presentation.ui.component.list + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.ui.Modifier +import com.example.notimanager.presentation.stateholder.state.FilteredNotificationState +import com.example.notimanager.presentation.stateholder.viewmodel.FilteredNotificationViewModel +import com.example.notimanager.presentation.ui.component.item.FilteredItemView + +@Composable +fun FilteredListView( + innerPadding: PaddingValues, + viewModel: FilteredNotificationViewModel +) { + val filteredNotificationState by viewModel.filteredNotiState.observeAsState( + FilteredNotificationState() + ) + if (filteredNotificationState.filteredList.isEmpty()) { + Text("No notifications") + } else { + LazyColumn( + Modifier + .fillMaxSize() + .padding(innerPadding) + ) { + + items(filteredNotificationState.filteredList) { item -> + FilteredItemView(item, viewModel) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt new file mode 100644 index 0000000..03805a4 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationAppListView.kt @@ -0,0 +1,88 @@ +package com.example.notimanager.presentation.ui.component.list + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.HorizontalDivider +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.navigation.NavController +import com.example.notimanager.presentation.stateholder.state.NotificationAppPriorityState +import com.example.notimanager.presentation.stateholder.state.NotificationAppState +import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppPriorityViewModel +import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppViewModel +import com.example.notimanager.presentation.ui.component.item.NotificationAppItemView + +@Composable +fun NotificationAppListView( + navController: NavController, + viewModel: NotificationAppViewModel, + priorityViewModel: NotificationAppPriorityViewModel +) { + val notificationAppState by viewModel.notificationAppState.observeAsState(NotificationAppState()) + val priorityState by priorityViewModel.notificationAppPriorityState.observeAsState((NotificationAppPriorityState())) + var currentNotiPriority by remember { mutableStateOf(priorityState.notificationAppList) } + var currentNoti by remember { mutableStateOf(notificationAppState.notificationAppList) } + + LaunchedEffect(priorityState.notificationAppList) { + if (!priorityState.isLoading) { + currentNotiPriority = priorityState.notificationAppList + } + if (priorityState.notificationAppList.isEmpty()){ + currentNotiPriority = emptyList() + } + } + + LaunchedEffect(notificationAppState.notificationAppList) { + if (!notificationAppState.isLoading) { + currentNoti = notificationAppState.notificationAppList + } + if (notificationAppState.notificationAppList.isEmpty()){ + currentNoti = emptyList() + } + } + + LazyColumn( + Modifier.fillMaxSize() + ) { + items(currentNotiPriority) { notification -> + NotificationAppItemView( + notification = notification, + onClick = { + navController + .navigate( + "titleScreen/${notification.appName}" + ) + }, + viewModel = viewModel, + priorityViewModel = priorityViewModel + ) + } + if (currentNotiPriority.isNotEmpty()){ + item { + HorizontalDivider() + } + } + + + items(currentNoti) { notification -> + NotificationAppItemView( + notification = notification, + onClick = { + navController + .navigate( + "titleScreen/${notification.appName}" + ) + }, + viewModel = viewModel, + priorityViewModel = priorityViewModel + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt new file mode 100644 index 0000000..39b5a31 --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationListView.kt @@ -0,0 +1,47 @@ +package com.example.notimanager.presentation.ui.component.list + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import com.example.notimanager.presentation.stateholder.state.NotificationState +import com.example.notimanager.presentation.ui.component.item.NotificationItemView + + +@Composable +fun NotificationListView( + notificationState: NotificationState, + onDelete: (Long) -> Unit + +) { + val context = LocalContext.current + var currentNoti by remember { mutableStateOf(notificationState.notificationList) } + + LaunchedEffect(notificationState.notificationList) { + if (!notificationState.isLoading) { + currentNoti = notificationState.notificationList + } + if (notificationState.notificationList.isEmpty()){ + currentNoti = emptyList() + } + } + + LazyColumn( + modifier = Modifier.fillMaxSize() + ) { + items(currentNoti) { notification -> + NotificationItemView (notification = notification, onClick = { + if (notification.intent?.action != null) + context.startActivity(notification.intent) }, + onDelete = onDelete + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt new file mode 100644 index 0000000..539fa0a --- /dev/null +++ b/app/src/main/java/com/example/notimanager/presentation/ui/component/list/NotificationTitleListView.kt @@ -0,0 +1,96 @@ +package com.example.notimanager.presentation.ui.component.list + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.HorizontalDivider +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.navigation.NavController +import com.example.notimanager.common.objects.Encoder.getEncodedString +import com.example.notimanager.presentation.stateholder.state.NotificationTitlePriorityState +import com.example.notimanager.presentation.stateholder.state.NotificationTitleState +import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitlePriorityViewModel +import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitleViewModel +import com.example.notimanager.presentation.ui.component.item.NotificationTitleItemView + +@Composable +fun NotificationTitleListView( + navController: NavController, + viewModel: NotificationTitleViewModel, + priorityViewModel: NotificationTitlePriorityViewModel +) { + val notificationTitleState by viewModel.notificationTitleState.observeAsState( + NotificationTitleState() + ) + val priorityState by priorityViewModel.notificationTitlePriorityState.observeAsState( + NotificationTitlePriorityState() + ) + var currentNotiPriority by remember { mutableStateOf(priorityState.notificationTitleList) } + var currentNoti by remember { mutableStateOf(notificationTitleState.notificationTitleList) } + + LaunchedEffect(priorityState.notificationTitleList) { + if (!priorityState.isLoading) { + currentNotiPriority = priorityState.notificationTitleList + } + if (priorityState.notificationTitleList.isEmpty()){ + currentNotiPriority = emptyList() + } + } + + LaunchedEffect(notificationTitleState.notificationTitleList) { + if (!notificationTitleState.isLoading) { + currentNoti = notificationTitleState.notificationTitleList + } + if (notificationTitleState.notificationTitleList.isEmpty()){ + currentNoti = emptyList() + } + } + + LazyColumn( + modifier = Modifier.fillMaxSize() + ) { + items(currentNotiPriority) { notification -> + NotificationTitleItemView(notification = notification, onClick = { + if (notification.subText == "") navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.title)}/False") + else navController.navigate("notificationScreen/${viewModel.getAppName()}/${getEncodedString(notification.subText)}/True") + }, viewModel = viewModel, priorityViewModel = priorityViewModel) + } + + if (currentNotiPriority.isNotEmpty()){ + item { + HorizontalDivider() + } + } + + items(currentNoti) { notification -> + NotificationTitleItemView(notification = notification, onClick = { + if (notification.subText == "") { + viewModel.updateAsRead(notification.title) + navController.navigate( + "notificationScreen/${viewModel.getAppName()}/${ + getEncodedString( + notification.title + ) + }/False" + ) + } + else { + viewModel.updateAsSubText(notification.subText) + navController.navigate( + "notificationScreen/${viewModel.getAppName()}/${ + getEncodedString( + notification.subText + ) + }/True" + ) + }}, viewModel = viewModel, priorityViewModel = priorityViewModel) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/screen/DateFormatterScreen.kt b/app/src/main/java/com/example/notimanager/presentation/ui/screen/DateFormatterScreen.kt index bf1f89d..d2c9e8e 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/screen/DateFormatterScreen.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/screen/DateFormatterScreen.kt @@ -1,20 +1,34 @@ package com.example.notimanager.presentation.ui.screen +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp import androidx.navigation.NavController +import com.example.notimanager.R +import com.example.notimanager.presentation.ui.component.common.CommonTopAppBar import com.example.notimanager.presentation.ui.component.DateFormatterView -import com.example.notimanager.presentation.ui.component.SettingTopAppBar @Composable fun DateFormatterScreen( navController: NavController, ) { + // 언어 설정에 따라 문자열 리소스를 가져오기 + val context = LocalContext.current + val title = context.getString(R.string.setting_date_format) + Scaffold( topBar = { - SettingTopAppBar{ navController.popBackStack() } + CommonTopAppBar(title){ navController.popBackStack() } } ) { innerPadding -> + HorizontalDivider( + modifier = Modifier.padding(innerPadding), + thickness = 0.2.dp + ) DateFormatterView(innerPadding) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/screen/FilteredListScreen.kt b/app/src/main/java/com/example/notimanager/presentation/ui/screen/FilteredListScreen.kt index 589ae87..ecef73a 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/screen/FilteredListScreen.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/screen/FilteredListScreen.kt @@ -1,24 +1,37 @@ package com.example.notimanager.presentation.ui.screen +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController +import com.example.notimanager.R import com.example.notimanager.presentation.stateholder.viewmodel.FilteredNotificationViewModel -import com.example.notimanager.presentation.ui.component.FilteredListView -import com.example.notimanager.presentation.ui.component.FilteredTopAppBar - +import com.example.notimanager.presentation.ui.component.common.CommonTopAppBar +import com.example.notimanager.presentation.ui.component.list.FilteredListView @Composable fun FilteredListScreen( navController: NavController, viewModel: FilteredNotificationViewModel = hiltViewModel() ) { + // 언어 설정에 따라 문자열 리소스를 가져오기 + val context = LocalContext.current + val title = context.getString(R.string.setting_filtered_list) + Scaffold( topBar = { - FilteredTopAppBar{ navController.popBackStack() } + CommonTopAppBar(title = title, onBackClick = { navController.popBackStack() }) } ) { innerPadding -> + HorizontalDivider( + modifier = Modifier.padding(innerPadding), + thickness = 0.2.dp + ) FilteredListView(innerPadding, viewModel) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/screen/MainScreen.kt b/app/src/main/java/com/example/notimanager/presentation/ui/screen/MainScreen.kt index 28cde25..45e08a6 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/screen/MainScreen.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/screen/MainScreen.kt @@ -20,9 +20,9 @@ import androidx.lifecycle.compose.LifecycleEventEffect import androidx.navigation.NavController import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppPriorityViewModel import com.example.notimanager.presentation.stateholder.viewmodel.NotificationAppViewModel -import com.example.notimanager.presentation.ui.component.MainTopAppBar -import com.example.notimanager.presentation.ui.component.NotificationAppListView -import com.example.notimanager.presentation.ui.component.PermissionCheck +import com.example.notimanager.presentation.ui.component.common.MainTopAppBar +import com.example.notimanager.presentation.ui.component.list.NotificationAppListView +import com.example.notimanager.presentation.ui.component.common.PermissionCheck import kotlinx.coroutines.delay import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/screen/NotificationScreen.kt b/app/src/main/java/com/example/notimanager/presentation/ui/screen/NotificationScreen.kt index 88be77d..f26a1a3 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/screen/NotificationScreen.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/screen/NotificationScreen.kt @@ -16,12 +16,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import com.example.notimanager.presentation.stateholder.state.NotificationState import com.example.notimanager.presentation.stateholder.viewmodel.NotificationViewModel -import com.example.notimanager.presentation.ui.component.NotificationListView -import com.example.notimanager.presentation.ui.component.NotificationTopAppBar +import com.example.notimanager.presentation.ui.component.common.CommonTopAppBar +import com.example.notimanager.presentation.ui.component.list.NotificationListView import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -47,7 +46,7 @@ fun NotificationScreen(navController: NavController, appName: String = "", title } Scaffold( topBar = { - NotificationTopAppBar(title = title, onBackClick = { navController.popBackStack() }) + CommonTopAppBar(title = title, onBackClick = { navController.popBackStack() }) } ) { innerPadding -> HorizontalDivider( diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/screen/NotificationSubScreen.kt b/app/src/main/java/com/example/notimanager/presentation/ui/screen/NotificationSubScreen.kt index d3c20df..3ad6ceb 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/screen/NotificationSubScreen.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/screen/NotificationSubScreen.kt @@ -19,8 +19,8 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import com.example.notimanager.presentation.stateholder.state.NotificationState import com.example.notimanager.presentation.stateholder.viewmodel.NotificationSubTextViewModel -import com.example.notimanager.presentation.ui.component.NotificationListView -import com.example.notimanager.presentation.ui.component.NotificationTopAppBar +import com.example.notimanager.presentation.ui.component.common.CommonTopAppBar +import com.example.notimanager.presentation.ui.component.list.NotificationListView import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -46,7 +46,7 @@ fun NotificationSubScreen(navController: NavController, appName: String = "", su } Scaffold( topBar = { - NotificationTopAppBar(title = subText, onBackClick = { navController.popBackStack() }) + CommonTopAppBar(title = subText, onBackClick = { navController.popBackStack() }) } ) { innerPadding -> HorizontalDivider( diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/screen/SettingScreen.kt b/app/src/main/java/com/example/notimanager/presentation/ui/screen/SettingScreen.kt index fa8552f..ce3e9c5 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/screen/SettingScreen.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/screen/SettingScreen.kt @@ -1,20 +1,34 @@ package com.example.notimanager.presentation.ui.screen +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.example.notimanager.presentation.ui.component.SettingTopAppBar +import com.example.notimanager.R +import com.example.notimanager.presentation.ui.component.common.CommonTopAppBar import com.example.notimanager.presentation.ui.component.SettingView @Composable fun SettingScreen( navController: NavController, ) { + // 언어 설정에 따라 문자열 리소스를 가져오기 + val context = LocalContext.current + val title = context.getString(R.string.setting_name) + Scaffold( topBar = { - SettingTopAppBar{ navController.popBackStack() } + CommonTopAppBar(title){ navController.popBackStack() } } ) { innerPadding -> + HorizontalDivider( + modifier = Modifier.padding(innerPadding), + thickness = 0.2.dp + ) SettingView(innerPadding, navController) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/notimanager/presentation/ui/screen/TitleScreen.kt b/app/src/main/java/com/example/notimanager/presentation/ui/screen/TitleScreen.kt index 2435687..1407793 100644 --- a/app/src/main/java/com/example/notimanager/presentation/ui/screen/TitleScreen.kt +++ b/app/src/main/java/com/example/notimanager/presentation/ui/screen/TitleScreen.kt @@ -20,8 +20,8 @@ import androidx.lifecycle.compose.LifecycleEventEffect import androidx.navigation.NavController import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitlePriorityViewModel import com.example.notimanager.presentation.stateholder.viewmodel.NotificationTitleViewModel -import com.example.notimanager.presentation.ui.component.NotificationTitleListView -import com.example.notimanager.presentation.ui.component.TitleTopAppBar +import com.example.notimanager.presentation.ui.component.list.NotificationTitleListView +import com.example.notimanager.presentation.ui.component.common.CommonTopAppBar import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -46,7 +46,7 @@ fun TitleScreen(navController: NavController, appName: String = ""){ Scaffold( topBar = { - TitleTopAppBar(title = appName, onBackClick = { navController.popBackStack() }) + CommonTopAppBar(title = appName, onBackClick = { navController.popBackStack() }) } ) { innerPadding -> HorizontalDivider( diff --git a/app/src/main/res/drawable/delete.xml b/app/src/main/res/drawable/delete.xml new file mode 100644 index 0000000..f32818a --- /dev/null +++ b/app/src/main/res/drawable/delete.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/input.xml b/app/src/main/res/drawable/input.xml new file mode 100644 index 0000000..53cf620 --- /dev/null +++ b/app/src/main/res/drawable/input.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/notifications.xml b/app/src/main/res/drawable/notifications.xml new file mode 100644 index 0000000..3da0d5f --- /dev/null +++ b/app/src/main/res/drawable/notifications.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/notifications_off.xml b/app/src/main/res/drawable/notifications_off.xml new file mode 100644 index 0000000..853e9f6 --- /dev/null +++ b/app/src/main/res/drawable/notifications_off.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/star.xml b/app/src/main/res/drawable/star.xml new file mode 100644 index 0000000..07bcd69 --- /dev/null +++ b/app/src/main/res/drawable/star.xml @@ -0,0 +1,9 @@ + + +