diff --git a/.idea/inspectionProfiles/ktlint.xml b/.idea/inspectionProfiles/ktlint.xml
index 2d90dc13d..27ceb5ff2 100644
--- a/.idea/inspectionProfiles/ktlint.xml
+++ b/.idea/inspectionProfiles/ktlint.xml
@@ -40,6 +40,7 @@
+
diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
index 50d6f97cc..5432675aa 100644
--- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
+++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
@@ -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,17 @@ 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 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, this@ChatActivity)
+ }
+ }
}
fun markAsUnread(message: IMessage?) {
diff --git a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt
index ed349b5fc..64b029ae6 100644
--- a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt
+++ b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt
@@ -150,6 +150,7 @@ class ChatViewModel @Inject constructor(
object GetReminderStartState : ViewState
open class GetReminderExistState(val reminder: Reminder) : ViewState
+ object GetReminderStateSet : ViewState
private val _getReminderExistState: MutableLiveData = MutableLiveData(GetReminderStartState)
@@ -310,6 +311,10 @@ class ChatViewModel @Inject constructor(
?.subscribe(GetReminderObserver())
}
+ fun overrideReminderState() {
+ _getReminderExistState.value = GetReminderStateSet
+ }
+
fun deleteReminder(user: User, roomToken: String, messageId: String, chatApiVersion: Int) {
chatNetworkDataSource.deleteReminder(user, roomToken, messageId, chatApiVersion)
.subscribeOn(Schedulers.io())
@@ -754,7 +759,7 @@ class ChatViewModel @Inject constructor(
val model = ConversationModel.mapToConversationModel(it, userProvider.currentUser.blockingGet())
ConversationUtils.isNoteToSelfConversation(model)
}
- _getNoteToSelfAvailability.value = NoteToSelfAvailableState(noteToSelf.token!!)
+ _getNoteToSelfAvailability.value = NoteToSelfAvailableState(noteToSelf.token)
} catch (e: NoSuchElementException) {
_getNoteToSelfAvailability.value = NoteToSelfNotAvailableState
Log.e(TAG, "Note to self not found $e")
diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/DateTimeCompose.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/DateTimeCompose.kt
new file mode 100644
index 000000000..30ae6d0cd
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/DateTimeCompose.kt
@@ -0,0 +1,368 @@
+/*
+ * Nextcloud Talk - Android Client
+ *
+ * SPDX-FileCopyrightText: 2025 Julius Linus
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package com.nextcloud.talk.ui.dialog
+
+import android.content.Context
+import android.os.Bundle
+import androidx.compose.animation.animateContentSize
+import androidx.compose.foundation.clickable
+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.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.MaterialTheme
+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.collectAsState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.window.Dialog
+import androidx.compose.ui.window.DialogProperties
+import androidx.lifecycle.asFlow
+import autodagger.AutoInjector
+import com.nextcloud.talk.R
+import com.nextcloud.talk.application.NextcloudTalkApplication
+import com.nextcloud.talk.chat.viewmodels.ChatViewModel
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
+import com.nextcloud.talk.users.UserManager
+import com.nextcloud.talk.utils.bundle.BundleKeys
+import java.time.DayOfWeek
+import java.time.Instant
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.ZoneId
+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.ofEpochSecond(0, 0, ZoneOffset.MIN))
+
+ init {
+ NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
+ 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.getReminder(user, roomToken, messageId, apiVersion)
+ }
+
+ @Inject
+ lateinit var chatViewModel: ChatViewModel
+
+ @Inject
+ lateinit var userManager: UserManager
+
+ @Inject
+ lateinit var viewThemeUtils: ViewThemeUtils
+
+ @Composable
+ fun GetDateTimeDialog(shouldDismiss: MutableState, context: Context) {
+ if (shouldDismiss.value) {
+ return
+ }
+
+ val colorScheme = viewThemeUtils.getColorScheme(context)
+ val isCollapsed = remember { mutableStateOf(true) }
+
+ MaterialTheme(colorScheme = colorScheme) {
+ Dialog(
+ onDismissRequest = {
+ shouldDismiss.value = true
+ },
+ properties = DialogProperties(
+ dismissOnBackPress = true,
+ dismissOnClickOutside = true,
+ usePlatformDefaultWidth = isCollapsed.value
+ )
+ ) {
+ Surface(
+ shape = RoundedCornerShape(INT_8.dp),
+ modifier = Modifier.animateContentSize()
+ ) {
+ Column(
+ modifier = Modifier
+ .padding(INT_16.dp)
+ .fillMaxWidth()
+ ) {
+ Header()
+ Body()
+ CollapsableDateTime(shouldDismiss, isCollapsed)
+ }
+ }
+ }
+ }
+ }
+
+ @Composable
+ private fun Submission(shouldDismiss: MutableState) {
+ 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(CUBED_PADDING)
+ ) {
+ Text(
+ stringResource(R.string.nc_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)
+ val offset = timeState.value.atZone(ZoneOffset.systemDefault()).offset
+ val timeVal = timeState.value.toEpochSecond(offset)
+ chatViewModel.setReminder(user, roomToken, messageId, timeVal.toInt(), apiVersion)
+ shouldDismiss.value = true
+ },
+ modifier = Modifier
+ .weight(CUBED_PADDING)
+ ) {
+ Text(stringResource(R.string.set))
+ }
+
+ TextButton(
+ onClick = {
+ shouldDismiss.value = true
+ },
+ modifier = Modifier
+ .weight(CUBED_PADDING)
+ ) {
+ Text(stringResource(R.string.close))
+ }
+ }
+ }
+
+ @Composable
+ private fun Body() {
+ val currTime = LocalDateTime.now()
+
+ val laterToday = LocalDateTime.now()
+ .withHour(INT_18)
+ .withMinute(0)
+ .withSecond(0)
+ val laterTodayStr = laterToday.format(DateTimeFormatter.ofPattern(PATTERN))
+
+ val tomorrow = LocalDateTime.now()
+ .plusDays(1)
+ .withHour(INT_8)
+ .withMinute(0)
+ .withSecond(0)
+ val tomorrowStr = tomorrow.format(DateTimeFormatter.ofPattern(PATTERN))
+
+ val thisWeekend = LocalDateTime.now()
+ .with(nextOrSame(DayOfWeek.SATURDAY))
+ .withHour(INT_8)
+ .withMinute(0)
+ .withSecond(0)
+ val thisWeekendStr = thisWeekend.format(DateTimeFormatter.ofPattern(PATTERN))
+
+ val nextWeek = LocalDateTime.now()
+ .plusWeeks(1)
+ .with(DayOfWeek.MONDAY)
+ .withHour(INT_8)
+ .withMinute(0)
+ .withSecond(0)
+ val nextWeekStr = nextWeek.format(DateTimeFormatter.ofPattern(PATTERN))
+
+ if (currTime < laterToday) {
+ TimeOption(
+ label = stringResource(R.string.later_today),
+ timeString = laterTodayStr
+ ) {
+ setTime(laterToday)
+ }
+ }
+
+ if (tomorrow.dayOfWeek < DayOfWeek.SATURDAY) {
+ TimeOption(
+ label = stringResource(R.string.tomorrow),
+ timeString = tomorrowStr
+ ) {
+ setTime(tomorrow)
+ }
+ }
+
+ if (currTime.dayOfWeek < DayOfWeek.SATURDAY) {
+ TimeOption(
+ label = stringResource(R.string.this_weekend),
+ timeString = thisWeekendStr
+ ) {
+ setTime(thisWeekend)
+ }
+ }
+
+ TimeOption(
+ label = stringResource(R.string.next_week),
+ timeString = nextWeekStr
+ ) {
+ setTime(nextWeek)
+ }
+
+ HorizontalDivider()
+ }
+
+ private fun setTime(localDateTime: LocalDateTime) {
+ timeState.value = localDateTime
+ chatViewModel.overrideReminderState()
+ }
+
+ @Composable
+ private fun Header() {
+ Row(
+ modifier = Modifier
+ .padding(INT_8.dp)
+ ) {
+ Text(stringResource(R.string.nc_remind), modifier = Modifier.weight(1f))
+
+ val reminderState = chatViewModel.getReminderExistState
+ .asFlow()
+ .collectAsState(ChatViewModel.GetReminderStartState)
+
+ when (reminderState.value) {
+ is ChatViewModel.GetReminderExistState -> {
+ val timeL =
+ (reminderState.value as ChatViewModel.GetReminderExistState).reminder.timestamp!!.toLong()
+ timeState.value = LocalDateTime.ofInstant(Instant.ofEpochSecond(timeL), ZoneId.systemDefault())
+ }
+
+ else -> {}
+ }
+
+ if (timeState.value != LocalDateTime.ofEpochSecond(0, 0, ZoneOffset.MIN)) {
+ Text(timeState.value.format(DateTimeFormatter.ofPattern(PATTERN)))
+ }
+ }
+ HorizontalDivider()
+ }
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ @Composable
+ private fun CollapsableDateTime(shouldDismiss: MutableState, isCollapsed: MutableState) {
+ GeneralIconButton(icon = Icons.Filled.DateRange, label = "Custom") { isCollapsed.value = !isCollapsed.value }
+ val scrollState = rememberScrollState()
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.verticalScroll(scrollState)
+ ) {
+ if (!isCollapsed.value) {
+ val datePickerState = rememberDatePickerState()
+ val timePickerState = rememberTimePickerState()
+
+ DatePicker(
+ state = datePickerState
+ )
+
+ TimePicker(
+ state = timePickerState
+ )
+
+ val date = datePickerState.selectedDateMillis?.let {
+ val instant = Instant.ofEpochMilli(it)
+ LocalDateTime.ofInstant(instant, ZoneOffset.UTC) // Google sends time in UTC
+ }
+ if (date != null) {
+ val year = date.year
+ val month = date.month
+ val day = date.dayOfMonth
+ val hour = timePickerState.hour
+ val minute = timePickerState.minute
+ val newTime = LocalDateTime.of(year, month, day, hour, minute)
+ setTime(newTime)
+ } else {
+ val newTime = LocalDate.now().atTime(timePickerState.hour, timePickerState.minute)
+ setTime(newTime)
+ }
+ }
+ 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(INT_24.dp)
+ )
+ Spacer(modifier = Modifier.width(INT_8.dp))
+ Text(text = label)
+ }
+ }
+ }
+
+ @Composable
+ private fun TimeOption(label: String, timeString: String, onClick: () -> Unit) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(INT_8.dp)
+ .clickable { onClick() }
+ ) {
+ Text(label, modifier = Modifier.weight(HALF_WEIGHT))
+ Text(timeString, modifier = Modifier.weight(HALF_WEIGHT))
+ }
+ }
+
+ companion object {
+ private const val PATTERN = "dd MMM, HH:mm a"
+ private const val HALF_WEIGHT = 0.5f
+ private const val INT_8 = 8
+ private const val INT_16 = 16
+ private const val INT_18 = 18
+ private const val INT_24 = 24
+ private const val CUBED_PADDING = 0.33f
+ }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/DateTimePickerFragment.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/DateTimePickerFragment.kt
deleted file mode 100644
index fb2bc1aca..000000000
--- a/app/src/main/java/com/nextcloud/talk/ui/dialog/DateTimePickerFragment.kt
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Nextcloud Talk - Android Client
- *
- * SPDX-FileCopyrightText: 2023 Julius Linus
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-package com.nextcloud.talk.ui.dialog
-
-import android.app.Dialog
-import android.os.Bundle
-import android.text.format.DateFormat
-import android.text.format.DateUtils
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.fragment.app.DialogFragment
-import autodagger.AutoInjector
-import com.google.android.material.datepicker.CalendarConstraints
-import com.google.android.material.datepicker.DateValidatorPointForward
-import com.google.android.material.datepicker.MaterialDatePicker
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.google.android.material.timepicker.MaterialTimePicker
-import com.google.android.material.timepicker.TimeFormat
-import com.nextcloud.android.common.ui.theme.utils.ColorRole
-import com.nextcloud.talk.R
-import com.nextcloud.talk.application.NextcloudTalkApplication
-import com.nextcloud.talk.chat.ChatActivity
-import com.nextcloud.talk.chat.viewmodels.ChatViewModel
-import com.nextcloud.talk.databinding.DialogDateTimePickerBinding
-import com.nextcloud.talk.ui.theme.ViewThemeUtils
-import com.nextcloud.talk.users.UserManager
-import java.util.Calendar
-import java.util.TimeZone
-import javax.inject.Inject
-
-@Suppress("TooManyFunctions")
-@AutoInjector(NextcloudTalkApplication::class)
-class DateTimePickerFragment : DialogFragment() {
-
- lateinit var binding: DialogDateTimePickerBinding
- private var dialogView: View? = null
- private lateinit var viewModel: ChatViewModel
- private var currentTimeStamp: Long? = null
- private lateinit var roomToken: String
- private lateinit var messageId: String
- private var chatApiVersion: Int = -1
- private var laterTodayTimeStamp = 0L
- private var tomorrowTimeStamp = 0L
- private var weekendTimeStamp = 0L
- private var nextWeekTimeStamp = 0L
-
- @Inject
- lateinit var userManager: UserManager
-
- @Inject
- lateinit var viewThemeUtils: ViewThemeUtils
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- binding = DialogDateTimePickerBinding.inflate(layoutInflater)
- dialogView = binding.root
- viewModel = (requireActivity() as ChatActivity).chatViewModel
- arguments?.let {
- roomToken = it.getString(TOKEN_ARG, "")
- messageId = it.getString(ID_ARG, "")
- chatApiVersion = it.getInt(CHAT_API_VERSION_ARG)
- }
- return MaterialAlertDialogBuilder(requireContext()).setView(dialogView).create()
- }
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
- setUpDefaults()
- setUpColors()
- setListeners()
- getReminder()
- viewModel.getReminderExistState.observe(this) { state ->
- when (state) {
- is ChatViewModel.GetReminderExistState -> {
- val timeStamp = state.reminder.timestamp?.toLong()?.times(ONE_SEC)
- showDelete(true)
- setTimeStamp(getTimeFromTimeStamp(timeStamp!!))
- }
-
- else -> {
- showDelete(false)
- binding.dateTimePickerTimestamp.text = ""
- }
- }
- }
-
- return inflater.inflate(R.layout.dialog_date_time_picker, container, false)
- }
-
- private fun setUpDefaults() {
- val currTime = getTimeFromCalendar()
- val currentWeekInYear = Calendar.getInstance().get(Calendar.WEEK_OF_YEAR)
-
- laterTodayTimeStamp = getTimeFromCalendar(hour = HOUR_SIX_PM, minute = 0)
- binding.dateTimePickerLaterTodayTextview.text = getTimeFromTimeStamp(laterTodayTimeStamp)
-
- if (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
- tomorrowTimeStamp = getTimeFromCalendar(
- hour = HOUR_EIGHT_AM,
- minute = 0,
- daysToAdd = 1
- )
-
- binding.dateTimePickerWeekend.visibility = View.GONE // because today is the weekend
- } else {
- tomorrowTimeStamp = getTimeFromCalendar(hour = HOUR_EIGHT_AM, minute = 0, daysToAdd = 1)
- weekendTimeStamp = getTimeFromCalendar(hour = HOUR_EIGHT_AM, weekDay = Calendar.SATURDAY, minute = 0)
- }
- binding.dateTimePickerTomorrowTextview.text = getTimeFromTimeStamp(tomorrowTimeStamp)
- binding.dateTimePickerWeekendTextview.text = getTimeFromTimeStamp(weekendTimeStamp)
-
- nextWeekTimeStamp = getTimeFromCalendar(
- hour = HOUR_EIGHT_AM,
- weekDay = Calendar.MONDAY,
- minute = 0,
- weekInYear =
- currentWeekInYear + 1
- ) // this should only pick mondays from next week only
- binding.dateTimePickerNextWeekTextview.text = getTimeFromTimeStamp(nextWeekTimeStamp)
-
- // This is to hide the later today option, if it's past 6pm
- if (currTime > laterTodayTimeStamp) {
- binding.dateTimePickerLaterToday.visibility = View.GONE
- }
-
- // This is to hide the tomorrow option, if that's also the weekend
- if (binding.dateTimePickerTomorrowTextview.text == binding.dateTimePickerWeekendTextview.text) {
- binding.dateTimePickerTomorrow.visibility = View.GONE
- }
- }
-
- private fun getReminder() {
- viewModel.getReminder(userManager.currentUser.blockingGet(), roomToken, messageId, chatApiVersion)
- }
-
- private fun showDelete(value: Boolean) {
- if (value) {
- binding.buttonDelete.visibility = View.VISIBLE
- } else {
- binding.buttonDelete.visibility = View.GONE
- }
- }
-
- private fun setUpColors() {
- binding.root.let {
- viewThemeUtils.platform.colorViewBackground(it)
- }
-
- binding.dateTimePickerCustomIcon.let {
- viewThemeUtils.platform.colorImageView(it, ColorRole.PRIMARY)
- }
-
- binding.dateTimePickerTimestamp.let {
- viewThemeUtils.material.themeSearchBarText(it)
- }
-
- binding.run {
- listOf(
- binding.buttonClose,
- binding.buttonSet
- )
- }.forEach(viewThemeUtils.material::colorMaterialButtonPrimaryBorderless)
- }
-
- private fun setListeners() {
- binding.dateTimePickerLaterToday.setOnClickListener {
- currentTimeStamp = laterTodayTimeStamp / ONE_SEC
- setTimeStamp(getTimeFromTimeStamp(laterTodayTimeStamp))
- }
- binding.dateTimePickerTomorrow.setOnClickListener {
- currentTimeStamp = tomorrowTimeStamp / ONE_SEC
- setTimeStamp(getTimeFromTimeStamp(tomorrowTimeStamp))
- }
- binding.dateTimePickerWeekend.setOnClickListener {
- currentTimeStamp = weekendTimeStamp / ONE_SEC
- setTimeStamp(getTimeFromTimeStamp(weekendTimeStamp))
- }
- binding.dateTimePickerNextWeek.setOnClickListener {
- currentTimeStamp = nextWeekTimeStamp / ONE_SEC
- setTimeStamp(getTimeFromTimeStamp(nextWeekTimeStamp))
- }
- binding.dateTimePickerCustom.setOnClickListener {
- val constraintsBuilder = CalendarConstraints.Builder()
- .setValidator(DateValidatorPointForward.now())
- .build()
- val time = System.currentTimeMillis()
- val datePicker = MaterialDatePicker.Builder.datePicker()
- .setTitleText(R.string.nc_remind)
- .setSelection(time + TimeZone.getDefault().getOffset(time))
- .setCalendarConstraints(constraintsBuilder).build()
-
- datePicker.addOnPositiveButtonClickListener { selection ->
- val localTimeInMillis = selection - TimeZone.getDefault().getOffset(selection)
- val calendar = Calendar.getInstance()
- calendar.timeInMillis = localTimeInMillis
-
- val year = calendar.get(Calendar.YEAR)
- val month = calendar.get(Calendar.MONTH)
- val day = calendar.get(Calendar.DAY_OF_YEAR)
-
- setUpTimePicker(year, month, day)
- }
- datePicker.show(this.parentFragmentManager, TAG)
- }
-
- binding.buttonClose.setOnClickListener { dismiss() }
- binding.buttonSet.setOnClickListener {
- currentTimeStamp?.let { time ->
- viewModel.setReminder(
- userManager.currentUser.blockingGet(),
- roomToken,
- messageId,
- time.toInt(),
- chatApiVersion
- )
- }
- dismiss()
- }
- binding.buttonDelete.setOnClickListener {
- viewModel.deleteReminder(userManager.currentUser.blockingGet(), roomToken, messageId, chatApiVersion)
- }
- }
-
- private fun setUpTimePicker(year: Int, month: Int, day: Int) {
- val locale = if (DateFormat.is24HourFormat(requireContext())) TimeFormat.CLOCK_24H else TimeFormat.CLOCK_12H
- val timePicker = MaterialTimePicker.Builder()
- .setTitleText(R.string.nc_remind)
- .setTimeFormat(locale)
- .build()
-
- timePicker.addOnPositiveButtonClickListener {
- val timestamp = getTimeFromCalendar(
- year,
- month,
- day,
- timePicker.hour,
- timePicker.minute
- )
- setTimeStamp(getTimeFromTimeStamp(timestamp))
- currentTimeStamp = timestamp / ONE_SEC
- }
-
- timePicker.show(this.parentFragmentManager, TAG)
- }
-
- /**
- * You can use `weekDay` or `daysToAdd` or neither but don't use both b/c it messes up the calendar
- */
- @Suppress("LongParameterList")
- private fun getTimeFromCalendar(
- year: Int = Calendar.getInstance().get(Calendar.YEAR),
- month: Int = Calendar.getInstance().get(Calendar.MONTH),
- day: Int = Calendar.getInstance().get(Calendar.DAY_OF_YEAR),
- hour: Int = Calendar.getInstance().get(Calendar.HOUR_OF_DAY),
- minute: Int = Calendar.getInstance().get(Calendar.MINUTE),
- daysToAdd: Int = 0,
- weekInYear: Int = -1,
- weekDay: Int = -1
- ): Long {
- val calendar: Calendar = Calendar.getInstance().apply {
- set(Calendar.YEAR, year)
- set(Calendar.MONTH, month)
- set(Calendar.DAY_OF_YEAR, day)
- if (weekDay > -1) set(Calendar.DAY_OF_WEEK, weekDay)
- if (daysToAdd > 0) add(Calendar.DAY_OF_YEAR, daysToAdd)
- if (weekInYear != -1) set(Calendar.WEEK_OF_YEAR, weekInYear)
- set(Calendar.HOUR_OF_DAY, hour)
- set(Calendar.MINUTE, minute)
- set(Calendar.SECOND, 0)
- }
- return calendar.timeInMillis
- }
-
- private fun setTimeStamp(date: String) {
- binding.dateTimePickerTimestamp.text = date
- }
-
- private fun getTimeFromTimeStamp(time: Long): String {
- return DateUtils.formatDateTime(
- requireContext(),
- time,
- DateUtils.FORMAT_SHOW_DATE
- ) + ", " + DateUtils.formatDateTime(
- requireContext(),
- time,
- DateUtils.FORMAT_SHOW_TIME
- )
- }
-
- companion object {
- val TAG = DateTimePickerFragment::class.simpleName
- private const val ONE_SEC = 1000
- private const val HOUR_EIGHT_AM = 8
- private const val HOUR_SIX_PM = 18
- private const val TOKEN_ARG = "TOKEN_ARG"
- private const val ID_ARG = "ID_ARG"
- private const val CHAT_API_VERSION_ARG = "CHAT_API_VERSION_ARG"
-
- @JvmStatic
- fun newInstance(token: String, id: String, chatApiVersion: Int): DateTimePickerFragment {
- val args = Bundle()
- args.putString(TOKEN_ARG, token)
- args.putString(ID_ARG, id)
- args.putInt(CHAT_API_VERSION_ARG, chatApiVersion)
-
- val dateTimePickerFragment = DateTimePickerFragment()
- dateTimePickerFragment.arguments = args
- return dateTimePickerFragment
- }
- }
-}
diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml
index a69daec52..9652c2947 100644
--- a/app/src/main/res/layout/activity_chat.xml
+++ b/app/src/main/res/layout/activity_chat.xml
@@ -269,4 +269,9 @@
android:layout_height="wrap_content"
android:padding="0dp"
/>
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_date_time_picker.xml b/app/src/main/res/layout/dialog_date_time_picker.xml
deleted file mode 100644
index 2ce1dd7e0..000000000
--- a/app/src/main/res/layout/dialog_date_time_picker.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/scripts/analysis/lint-results.txt b/scripts/analysis/lint-results.txt
index 56aa77762..bc7f6c076 100644
--- a/scripts/analysis/lint-results.txt
+++ b/scripts/analysis/lint-results.txt
@@ -1,2 +1,2 @@
DO NOT TOUCH; GENERATED BY DRONE
- Lint Report: 66 errors and 158 warnings
+ Lint Report: 36 errors and 106 warnings