Migrating away from java.util.Date to java.time

- Also converted dialog fragment to compose

Signed-off-by: rapterjet2004 <juliuslinus1@gmail.com>
This commit is contained in:
rapterjet2004 2024-12-17 11:49:01 -06:00 коммит произвёл Marcel Hibbe
Родитель 6d1ffbdb14
Коммит d114142d09
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: C793F8B59F43CE7B
4 изменённых файлов: 338 добавлений и 3 удалений

Просмотреть файл

@ -40,6 +40,7 @@
</inspection_tool>
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />

Просмотреть файл

@ -54,11 +54,13 @@ import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.view.ContextThemeWrapper
import androidx.cardview.widget.CardView
import androidx.compose.runtime.mutableStateOf
import androidx.core.content.FileProvider
import androidx.core.content.PermissionChecker
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
import androidx.core.graphics.ColorUtils
import androidx.core.graphics.drawable.toBitmap
import androidx.core.os.bundleOf
import androidx.core.text.bold
import androidx.emoji2.text.EmojiCompat
import androidx.fragment.app.DialogFragment
@ -147,7 +149,7 @@ import com.nextcloud.talk.ui.PlaybackSpeed
import com.nextcloud.talk.ui.PlaybackSpeedControl
import com.nextcloud.talk.ui.StatusDrawable
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet
import com.nextcloud.talk.ui.dialog.DateTimePickerFragment
import com.nextcloud.talk.ui.dialog.DateTimeCompose
import com.nextcloud.talk.ui.dialog.FileAttachmentPreviewFragment
import com.nextcloud.talk.ui.dialog.MessageActionsDialog
import com.nextcloud.talk.ui.dialog.SaveToStorageDialogFragment
@ -3502,8 +3504,19 @@ class ChatActivity :
val chatApiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(ApiUtils.API_V1, 1))
val newFragment: DialogFragment = DateTimePickerFragment.newInstance(roomToken, message!!.id, chatApiVersion)
newFragment.show(supportFragmentManager, DateTimePickerFragment.TAG)
// val newFragment: DialogFragment = DateTimePickerFragment.newInstance(roomToken, message!!.id, chatApiVersion)
// newFragment.show(supportFragmentManager, DateTimePickerFragment.TAG)
val bundle = bundleOf()
bundle.putString(KEY_ROOM_TOKEN, roomToken)
bundle.putString(BundleKeys.KEY_MESSAGE_ID, message!!.id)
bundle.putInt(BundleKeys.KEY_CHAT_API_VERSION, chatApiVersion)
binding.genericComposeView.apply {
val shouldDismiss = mutableStateOf(false)
setContent {
DateTimeCompose(bundle).GetDateTimeDialog(shouldDismiss)
}
}
}
fun markAsUnread(message: IMessage?) {

Просмотреть файл

@ -0,0 +1,316 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.ui.dialog
import android.os.Bundle
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.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.DateRange
import androidx.compose.material3.DatePicker
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TimePicker
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
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.draw.scale
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import autodagger.AutoInjector
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.chat.viewmodels.ChatViewModel
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.bundle.BundleKeys
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.time.temporal.TemporalAdjusters.nextOrSame
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class DateTimeCompose(val bundle: Bundle) {
private var timeState = mutableStateOf(LocalDateTime.now())
init {
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
}
@Inject
lateinit var chatViewModel: ChatViewModel
@Inject
lateinit var userManager: UserManager
@Composable
fun GetDateTimeDialog(shouldDismiss: MutableState<Boolean>) {
if (shouldDismiss.value) {
return
}
Dialog(
onDismissRequest = {
shouldDismiss.value = true
},
properties = DialogProperties(
dismissOnBackPress = true,
dismissOnClickOutside = true
)
) {
Surface(
shape = RoundedCornerShape(8.dp),
color = Color.White
) {
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
) {
Header()
Body()
CollapsableDateTime(shouldDismiss)
}
}
}
}
@Composable
private fun Submission(shouldDismiss: MutableState<Boolean>) {
Row(
modifier = Modifier.fillMaxWidth()
) {
TextButton(onClick = {
val user = userManager.currentUser.blockingGet()
val roomToken = bundle.getString(BundleKeys.KEY_ROOM_TOKEN)!!
val messageId = bundle.getString(BundleKeys.KEY_MESSAGE_ID)!!
val apiVersion = bundle.getInt(BundleKeys.KEY_CHAT_API_VERSION)
chatViewModel.deleteReminder(user, roomToken, messageId, apiVersion)
shouldDismiss.value = true
},
modifier = Modifier
.weight(.33f)
) {
Text(
"Delete",
color = Color.Red,
)
}
TextButton(onClick = {
val user = userManager.currentUser.blockingGet()
val roomToken = bundle.getString(BundleKeys.KEY_ROOM_TOKEN)!!
val messageId = bundle.getString(BundleKeys.KEY_MESSAGE_ID)!!
val apiVersion = bundle.getInt(BundleKeys.KEY_CHAT_API_VERSION)
chatViewModel.setReminder(user, roomToken, messageId, timeState.value.nano, apiVersion) // TODO verify
shouldDismiss.value = true
},
modifier = Modifier
.weight(.33f)
) {
Text("Set")
}
TextButton(onClick = {
shouldDismiss.value = true
},
modifier = Modifier
.weight(.33f)
) {
Text("Close")
}
}
}
@Suppress("DEPRECATION")
@Composable
private fun Body() {
val currTime = LocalDateTime.now()
val laterToday = LocalDateTime.now()
.withHour(18)
.withMinute(0)
.withSecond(0)
val tomorrow = LocalDateTime.now()
.plusDays(1)
.withHour(8)
.withMinute(0)
.withSecond(0)
val thisWeekend = LocalDateTime.now()
.with(nextOrSame(DayOfWeek.SATURDAY))
.withHour(8)
.withMinute(0)
.withSecond(0)
val nextWeek = LocalDateTime.now()
.plusWeeks(1)
.with(nextOrSame(DayOfWeek.MONDAY))
.withHour(8)
.withMinute(0)
.withSecond(0)
if (currTime < laterToday) {
ClickableText(
AnnotatedString("Later today"),
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
) {
timeState.value = laterToday
}
}
ClickableText(
AnnotatedString("Tomorrow"),
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
) {
timeState.value = tomorrow
}
ClickableText(
AnnotatedString("This weekend"),
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
) {
timeState.value = thisWeekend
}
ClickableText(
AnnotatedString("Next week"),
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
) {
timeState.value = nextWeek
}
HorizontalDivider()
}
@Composable
private fun Header() {
Row(
modifier = Modifier
.padding(8.dp)
) {
Text("Remind Me Later")
Spacer(modifier = Modifier.width(32.dp))
// TODO this needs to get it from the server
// this will be tricky, need to figure this out
Text(timeState.value.format(DateTimeFormatter.ofPattern("dd MMM, HH:mm a")))
}
HorizontalDivider()
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun CollapsableDateTime(shouldDismiss: MutableState<Boolean>) {
var isCollapsed by remember { mutableStateOf(true) }
GeneralIconButton(icon = Icons.Filled.DateRange, label = "Custom") { isCollapsed = !isCollapsed }
val scrollState = rememberScrollState()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.verticalScroll(scrollState)
) {
if (!isCollapsed) {
val datePickerState = rememberDatePickerState()
val timePickerState = rememberTimePickerState()
DatePicker(
state = datePickerState,
modifier = Modifier.scale(0.9f)
)
TimePicker(
state = timePickerState,
modifier = Modifier.scale(0.9f)
)
val date = datePickerState.selectedDateMillis?.let {
LocalDateTime.ofEpochSecond(it / 1000, 0, ZoneOffset.UTC)
}
if (date != null) {
val year = date.year
val month = date.month
val day = date.dayOfMonth
val hour = timePickerState.hour
val minute = timePickerState.minute
timeState.value = LocalDateTime.of(year, month, day, hour, minute)
} else {
timeState.value = LocalDate.now().atTime(timePickerState.hour, timePickerState.minute)
}
}
Submission(shouldDismiss)
}
}
@Composable
fun GeneralIconButton(
icon: ImageVector,
label: String,
onClick: () -> Unit
) {
TextButton(
onClick = onClick) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Icon(
imageVector = icon,
contentDescription = null,
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(8.dp))
Text(text = label)
}
}
}
// Preview Logic
// class DummyProvider : PreviewParameterProvider<String> {
// override val values: Sequence<String> = sequenceOf()
// }
// @Preview()
// @PreviewParameter(DummyProvider::class)
// @Composable
// fun PreviewDateTimeDialog() {
// GetDateTimeDialog()
// }
}

Просмотреть файл

@ -269,4 +269,9 @@
android:layout_height="wrap_content"
android:padding="0dp"
/>
<androidx.compose.ui.platform.ComposeView
android:id="@+id/generic_compose_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>