更新
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.taskttl.data.di
|
||||
|
||||
import com.taskttl.core.notification.NotificationManager
|
||||
import com.taskttl.data.repository.OnboardingRepository
|
||||
import com.taskttl.data.repository.SettingsRepository
|
||||
import com.taskttl.data.repository.impl.OnboardingRepositoryImpl
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.taskttl.data.state
|
||||
|
||||
import com.taskttl.core.notification.NotificationPermissionManager
|
||||
import com.taskttl.core.viewmodel.BaseUiState
|
||||
|
||||
/**
|
||||
@@ -14,6 +15,7 @@ data class SettingsState(
|
||||
override val isLoading: Boolean = false,
|
||||
override val isProcessing: Boolean = false,
|
||||
override val error: String? = null,
|
||||
val isNotification: Boolean = NotificationPermissionManager.verifyPermission(),
|
||||
) : BaseUiState()
|
||||
|
||||
/**
|
||||
@@ -38,6 +40,17 @@ sealed class SettingsIntent {
|
||||
* @param [url] 网址
|
||||
*/
|
||||
class OpenUrl(val url: String) : SettingsIntent()
|
||||
|
||||
object RequestPermission : SettingsIntent()
|
||||
|
||||
/**
|
||||
* 更新通知状态
|
||||
* @author DevTTL
|
||||
* @date 2025/10/17
|
||||
* @constructor 创建[UpdateNotificationStatus]
|
||||
* @param [status] 状态
|
||||
*/
|
||||
class UpdateNotificationStatus(val status: Boolean) : SettingsIntent()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ data class TaskState(
|
||||
* @constructor 创建[TaskIntent]
|
||||
*/
|
||||
sealed class TaskIntent {
|
||||
|
||||
/**
|
||||
* 加载任务
|
||||
* @author admin
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package com.taskttl.data.viewmodel
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.taskttl.core.notification.NotificationManager
|
||||
import com.taskttl.core.notification.NotificationPayload
|
||||
import com.taskttl.core.notification.NotificationRepeatType
|
||||
import com.taskttl.core.utils.DateUtils.toEpochMillis
|
||||
import com.taskttl.core.viewmodel.BaseViewModel
|
||||
import com.taskttl.data.local.model.Category
|
||||
import com.taskttl.data.local.model.CategoryType
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.taskttl.data.viewmodel
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.taskttl.core.notification.NotificationPermissionCallback
|
||||
import com.taskttl.core.notification.NotificationPermissionManager
|
||||
import com.taskttl.core.utils.ExternalAppLauncher
|
||||
import com.taskttl.core.utils.LogUtils
|
||||
import com.taskttl.core.viewmodel.BaseViewModel
|
||||
import com.taskttl.data.state.SettingsEffect
|
||||
import com.taskttl.data.state.SettingsIntent
|
||||
@@ -22,6 +25,8 @@ class SettingsViewModel() :
|
||||
when (intent) {
|
||||
is SettingsIntent.OpenAppRating -> openAppRating()
|
||||
is SettingsIntent.OpenUrl -> openUrl(intent.url)
|
||||
is SettingsIntent.RequestPermission -> requestPermission()
|
||||
is SettingsIntent.UpdateNotificationStatus -> updateNotificationStatus(intent.status)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +42,25 @@ class SettingsViewModel() :
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestPermission() {
|
||||
viewModelScope.launch {
|
||||
if (NotificationPermissionManager.verifyPermission()) {
|
||||
NotificationPermissionManager.disablePermission()
|
||||
} else {
|
||||
NotificationPermissionManager.requestPermission(
|
||||
object : NotificationPermissionCallback {
|
||||
override fun onGranted() = updateState { copy(isNotification = true) }
|
||||
override fun onDenied() = LogUtils.e("DevTTL", "❌ Android 通知权限被拒绝")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateNotificationStatus(status: Boolean) {
|
||||
updateState { copy(isNotification = status) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除错误
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.taskttl.data.viewmodel
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.taskttl.core.utils.LogUtils
|
||||
import com.taskttl.core.notification.NotificationManager
|
||||
import com.taskttl.core.notification.NotificationPayload
|
||||
import com.taskttl.core.notification.NotificationRepeatType
|
||||
import com.taskttl.core.utils.DateUtils.toEpochMillis
|
||||
import com.taskttl.core.viewmodel.BaseViewModel
|
||||
import com.taskttl.data.local.model.Category
|
||||
import com.taskttl.data.local.model.CategoryType
|
||||
@@ -24,6 +27,8 @@ import taskttl.composeapp.generated.resources.task_status_update_failed
|
||||
import taskttl.composeapp.generated.resources.task_status_update_success
|
||||
import taskttl.composeapp.generated.resources.task_update_failed
|
||||
import taskttl.composeapp.generated.resources.task_update_success
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.ExperimentalTime
|
||||
|
||||
/**
|
||||
* 任务视图模型
|
||||
@@ -87,10 +92,7 @@ class TaskViewModel(
|
||||
try {
|
||||
launch {
|
||||
categoryRepository.getCategoriesByType(CategoryType.TASK)
|
||||
.collect { categories ->
|
||||
LogUtils.e("DevTTL", categories.toString())
|
||||
updateState { copy(categories = categories) }
|
||||
}
|
||||
.collect { categories -> updateState { copy(categories = categories) } }
|
||||
}
|
||||
launch {
|
||||
taskRepository.getAllTasks().collect { tasks ->
|
||||
@@ -104,7 +106,6 @@ class TaskViewModel(
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
LogUtils.e("DevTTL", e.message.toString())
|
||||
val errStr = getString(Res.string.task_load_failed)
|
||||
updateState { copy(isLoading = false, error = e.message ?: errStr) }
|
||||
}
|
||||
@@ -131,19 +132,36 @@ class TaskViewModel(
|
||||
* 添加任务
|
||||
* @param [task] 任务
|
||||
*/
|
||||
@OptIn(ExperimentalTime::class)
|
||||
private fun addTask(task: Task) {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
if (state.value.isProcessing) return@launch
|
||||
updateState { copy(isLoading = false, isProcessing = true) }
|
||||
// 1️⃣ 插入任务
|
||||
taskRepository.insertTask(task)
|
||||
|
||||
// 2️⃣ 创建通知
|
||||
task.dueDate?.let {
|
||||
NotificationManager.scheduleNotification(
|
||||
NotificationPayload(
|
||||
id = task.id,
|
||||
title = task.title,
|
||||
message = task.description,
|
||||
triggerTimeMillis = task.dueDate.toEpochMillis(),
|
||||
repeatType = NotificationRepeatType.NONE
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// 3️⃣ UI 提示
|
||||
sendEvent(TaskEffect.ShowMessage(getString(Res.string.task_add_success)))
|
||||
sendEvent(TaskEffect.NavigateBack)
|
||||
} catch (e: Exception) {
|
||||
val errStr = getString(Res.string.task_add_failed)
|
||||
updateState { copy(error = e.message ?: errStr) }
|
||||
} finally {
|
||||
updateState { copy(isLoading = false,isProcessing = false) }
|
||||
updateState { copy(isLoading = false, isProcessing = false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,13 +176,27 @@ class TaskViewModel(
|
||||
if (state.value.isProcessing) return@launch
|
||||
updateState { copy(isLoading = false, isProcessing = true) }
|
||||
taskRepository.updateTask(task)
|
||||
|
||||
NotificationManager.cancelNotification(task.id)
|
||||
task.dueDate?.let {
|
||||
NotificationManager.scheduleNotification(
|
||||
NotificationPayload(
|
||||
id = task.id,
|
||||
title = task.title,
|
||||
message = task.description,
|
||||
triggerTimeMillis = task.dueDate.toEpochMillis(),
|
||||
repeatType = NotificationRepeatType.NONE
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
sendEvent(TaskEffect.ShowMessage(getString(Res.string.task_update_success)))
|
||||
sendEvent(TaskEffect.NavigateBack)
|
||||
} catch (e: Exception) {
|
||||
val errStr = getString(Res.string.task_update_failed)
|
||||
updateState { copy(error = e.message ?: errStr) }
|
||||
} finally {
|
||||
updateState { copy(isLoading = false,isProcessing = false) }
|
||||
updateState { copy(isLoading = false, isProcessing = false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,12 +211,13 @@ class TaskViewModel(
|
||||
if (state.value.isProcessing) return@launch
|
||||
updateState { copy(isLoading = false, isProcessing = true) }
|
||||
taskRepository.deleteTask(taskId)
|
||||
NotificationManager.cancelNotification(taskId)
|
||||
sendEvent(TaskEffect.ShowMessage(getString(Res.string.task_delete_success)))
|
||||
} catch (e: Exception) {
|
||||
val errStr = getString(Res.string.task_delete_failed)
|
||||
updateState { copy(error = e.message ?: errStr) }
|
||||
} finally {
|
||||
updateState { copy(isLoading = false,isProcessing = false) }
|
||||
updateState { copy(isLoading = false, isProcessing = false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user