mirror of
https://github.com/Docile-Alligator/Infinity-For-Reddit.git
synced 2026-08-18 11:03:26 +00:00
Continue implementing reminders.
This commit is contained in:
@ -5,13 +5,13 @@ import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@ -29,12 +29,14 @@ import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.TimePicker
|
||||
import androidx.compose.material3.TopAppBarDefaults.enterAlwaysScrollBehavior
|
||||
import androidx.compose.material3.rememberDatePickerState
|
||||
import androidx.compose.material3.rememberTimePickerState
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableLongStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -45,12 +47,14 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import ml.docilealligator.infinityforreddit.AppResult
|
||||
import ml.docilealligator.infinityforreddit.Infinity
|
||||
import ml.docilealligator.infinityforreddit.R
|
||||
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase
|
||||
@ -138,6 +142,7 @@ class SetReminderActivity: BaseActivity() {
|
||||
mViewModel = ViewModelProvider.create(
|
||||
this,
|
||||
provideFactory(
|
||||
accountName,
|
||||
intent.getParcelableExtra(EXTRA_POST),
|
||||
intent.getStringExtra(EXTRA_POST_ID),
|
||||
intent.getParcelableExtra(EXTRA_COMMENT),
|
||||
@ -161,8 +166,8 @@ class SetReminderActivity: BaseActivity() {
|
||||
val context = LocalContext.current
|
||||
val scrollBehavior = enterAlwaysScrollBehavior()
|
||||
|
||||
val commentContent = remember {
|
||||
mViewModel.comment?.commentRawText?.substring(200)
|
||||
val content = remember {
|
||||
mViewModel.content
|
||||
}
|
||||
|
||||
var showDatePicker by remember { mutableStateOf(false) }
|
||||
@ -180,6 +185,11 @@ class SetReminderActivity: BaseActivity() {
|
||||
mutableStateOf("")
|
||||
}
|
||||
|
||||
val setReminderResult by mViewModel.setReminderResult.collectAsStateWithLifecycle()
|
||||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
var snackbarMessage: String? by remember { mutableStateOf(null) }
|
||||
|
||||
LaunchedEffect(timePickerState.hour, timePickerState.minute, datePickerState.selectedDateMillis) {
|
||||
datePickerState.selectedDateMillis?.let {
|
||||
reminderTimeMillis = getDateAndTimeMillis(it, timePickerState.hour, timePickerState.minute)
|
||||
@ -191,6 +201,26 @@ class SetReminderActivity: BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(snackbarMessage) {
|
||||
snackbarMessage?.let {
|
||||
snackbarHostState.showSnackbar(it)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(setReminderResult) {
|
||||
setReminderResult?.let {
|
||||
when (it) {
|
||||
is AppResult.Success<*> -> {
|
||||
Toast.makeText(context, R.string.reminder_set, Toast.LENGTH_SHORT).show()
|
||||
finish()
|
||||
}
|
||||
is AppResult.Error<*> -> {
|
||||
snackbarMessage = getString(it.error as Int)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
ThemedTopAppBar(
|
||||
@ -199,7 +229,15 @@ class SetReminderActivity: BaseActivity() {
|
||||
windowInsetsController = windowInsetsController,
|
||||
actions = {
|
||||
IconButton(onClick = {
|
||||
|
||||
if (reminderTimeMillis == 0L || reminderTimeString.isEmpty()) {
|
||||
snackbarMessage = getString(R.string.please_set_reminder_time)
|
||||
return@IconButton
|
||||
}
|
||||
if (reminderTimeMillis < System.currentTimeMillis()) {
|
||||
snackbarMessage = getString(R.string.reminder_time_must_be_in_future)
|
||||
return@IconButton
|
||||
}
|
||||
mViewModel.setReminder(reminderTimeMillis)
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_check_circle_toolbar_24dp),
|
||||
@ -216,6 +254,9 @@ class SetReminderActivity: BaseActivity() {
|
||||
.fillMaxSize()
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.imePadding(),
|
||||
snackbarHost = {
|
||||
SnackbarHost(hostState = snackbarHostState)
|
||||
},
|
||||
contentWindowInsets = if (isImmersiveInterfaceEnabled) WindowInsets.safeDrawing else WindowInsets.navigationBars.only(WindowInsetsSides.Bottom)
|
||||
) { innerPadding ->
|
||||
Column(
|
||||
@ -224,14 +265,9 @@ class SetReminderActivity: BaseActivity() {
|
||||
.background(Color(LocalAppTheme.current.backgroundColor))
|
||||
.padding(innerPadding),
|
||||
) {
|
||||
if (commentContent != null) {
|
||||
if (content.isNotEmpty()) {
|
||||
PrimaryText(
|
||||
commentContent,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
} else if (mViewModel.post != null) {
|
||||
PrimaryText(
|
||||
mViewModel.post!!.title,
|
||||
content,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@ -2,12 +2,13 @@ package ml.docilealligator.infinityforreddit.reminder
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface ReminderDao {
|
||||
@Insert
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(reminder: Reminder)
|
||||
|
||||
@Query("SELECT * FROM reminders")
|
||||
|
||||
@ -6,17 +6,19 @@ import android.app.PendingIntent
|
||||
import android.content.Intent
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase
|
||||
import kotlin.jvm.java
|
||||
|
||||
class ReminderManager(
|
||||
private val applicationContext: Application,
|
||||
private val redditRoomDatabase: RedditDataRoomDatabase,
|
||||
private val alarmManager: AlarmManager
|
||||
) {
|
||||
fun setReminder(reminder: Reminder) {
|
||||
suspend fun setReminder(reminder: Reminder) {
|
||||
redditRoomDatabase.reminderDao().insert(reminder)
|
||||
|
||||
val alarmIntent = Intent(applicationContext,
|
||||
ReminderAlarmReceiver::class.java).let { intent ->
|
||||
PendingIntent.getBroadcast(applicationContext, 0, intent, 0)
|
||||
PendingIntent.getBroadcast(applicationContext, 0, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
alarmManager.set(
|
||||
|
||||
@ -1,27 +1,55 @@
|
||||
package ml.docilealligator.infinityforreddit.viewmodels
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.CreationExtras
|
||||
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import ml.docilealligator.infinityforreddit.AppResult
|
||||
import ml.docilealligator.infinityforreddit.R
|
||||
import ml.docilealligator.infinityforreddit.comment.Comment
|
||||
import ml.docilealligator.infinityforreddit.post.Post
|
||||
import ml.docilealligator.infinityforreddit.reminder.Reminder
|
||||
import ml.docilealligator.infinityforreddit.reminder.ReminderManager
|
||||
import retrofit2.Retrofit
|
||||
|
||||
class SetReminderViewModel(
|
||||
val accountName: String,
|
||||
val post: Post?,
|
||||
val postId: String?,
|
||||
val comment: Comment?,
|
||||
private val reminderManager: ReminderManager
|
||||
): ViewModel() {
|
||||
fun setReminder() {
|
||||
private val _setReminderResult: MutableStateFlow<AppResult<Unit, Int>?> = MutableStateFlow(null)
|
||||
val setReminderResult = _setReminderResult.asStateFlow()
|
||||
|
||||
val content: String
|
||||
get() = comment?.commentRawText?.substring(200) ?: post?.title ?: ""
|
||||
|
||||
fun setReminder(
|
||||
reminderTime: Long
|
||||
) {
|
||||
(post?.id ?: postId)?.let {
|
||||
viewModelScope.launch {
|
||||
reminderManager.setReminder(
|
||||
Reminder(
|
||||
accountName, it, comment?.id ?: "", content, System.currentTimeMillis(), reminderTime
|
||||
)
|
||||
)
|
||||
_setReminderResult.value = AppResult.Success(Unit)
|
||||
}
|
||||
} ?: run {
|
||||
_setReminderResult.value = AppResult.Error(R.string.invalid_reminder_post_id)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun provideFactory(
|
||||
accountName: String,
|
||||
post: Post?,
|
||||
postId: String?,
|
||||
comment: Comment?,
|
||||
@ -34,7 +62,7 @@ class SetReminderViewModel(
|
||||
extras: CreationExtras
|
||||
): T {
|
||||
return SetReminderViewModel(
|
||||
post, postId, comment, reminderManager
|
||||
accountName, post, postId, comment, reminderManager
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
||||
@ -1655,4 +1655,8 @@
|
||||
<string name="set_date">Set Date</string>
|
||||
<string name="set_time">Set Time</string>
|
||||
<string name="you_will_receive_reminder_notification">You\'ll receive a reminder notification on the date and time you set:</string>
|
||||
<string name="please_set_reminder_time">Please set a reminder time</string>
|
||||
<string name="reminder_time_must_be_in_future">The reminder time must be in the future.</string>
|
||||
<string name="invalid_reminder_post_id">Invalid post id</string>
|
||||
<string name="reminder_set">Reminder set</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user