mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 03:29:28 +01:00
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:
parent
6d1ffbdb14
commit
d114142d09
@ -40,6 +40,7 @@
|
|||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
<option name="composableFile" value="true" />
|
<option name="composableFile" value="true" />
|
||||||
|
<option name="previewFile" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="composableFile" value="true" />
|
<option name="composableFile" value="true" />
|
||||||
|
@ -54,11 +54,13 @@ import androidx.activity.result.ActivityResult
|
|||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.view.ContextThemeWrapper
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
import androidx.cardview.widget.CardView
|
import androidx.cardview.widget.CardView
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.core.content.PermissionChecker
|
import androidx.core.content.PermissionChecker
|
||||||
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
|
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
|
import androidx.core.os.bundleOf
|
||||||
import androidx.core.text.bold
|
import androidx.core.text.bold
|
||||||
import androidx.emoji2.text.EmojiCompat
|
import androidx.emoji2.text.EmojiCompat
|
||||||
import androidx.fragment.app.DialogFragment
|
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.PlaybackSpeedControl
|
||||||
import com.nextcloud.talk.ui.StatusDrawable
|
import com.nextcloud.talk.ui.StatusDrawable
|
||||||
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet
|
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.FileAttachmentPreviewFragment
|
||||||
import com.nextcloud.talk.ui.dialog.MessageActionsDialog
|
import com.nextcloud.talk.ui.dialog.MessageActionsDialog
|
||||||
import com.nextcloud.talk.ui.dialog.SaveToStorageDialogFragment
|
import com.nextcloud.talk.ui.dialog.SaveToStorageDialogFragment
|
||||||
@ -3502,8 +3504,19 @@ class ChatActivity :
|
|||||||
|
|
||||||
val chatApiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(ApiUtils.API_V1, 1))
|
val chatApiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(ApiUtils.API_V1, 1))
|
||||||
|
|
||||||
val newFragment: DialogFragment = DateTimePickerFragment.newInstance(roomToken, message!!.id, chatApiVersion)
|
// val newFragment: DialogFragment = DateTimePickerFragment.newInstance(roomToken, message!!.id, chatApiVersion)
|
||||||
newFragment.show(supportFragmentManager, DateTimePickerFragment.TAG)
|
// 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?) {
|
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:layout_height="wrap_content"
|
||||||
android:padding="0dp"
|
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>
|
</LinearLayout>
|
Loading…
Reference in New Issue
Block a user