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 dd040606e..5432675aa 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -3504,8 +3504,6 @@ 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) 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 index c63e57f16..c90521b24 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/DateTimeCompose.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/DateTimeCompose.kt @@ -9,6 +9,7 @@ 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 @@ -37,20 +38,19 @@ import androidx.compose.material3.rememberTimePickerState import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.collectAsState -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.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 @@ -95,6 +95,7 @@ class DateTimeCompose(val bundle: Bundle) { } val colorScheme = viewThemeUtils.getColorScheme(context) + val isCollapsed = remember { mutableStateOf(true) } MaterialTheme(colorScheme = colorScheme) { Dialog( @@ -103,11 +104,13 @@ class DateTimeCompose(val bundle: Bundle) { }, properties = DialogProperties( dismissOnBackPress = true, - dismissOnClickOutside = true + dismissOnClickOutside = true, + usePlatformDefaultWidth = isCollapsed.value ) ) { Surface( shape = RoundedCornerShape(8.dp), + modifier = Modifier.animateContentSize() ) { Column( modifier = Modifier @@ -116,7 +119,7 @@ class DateTimeCompose(val bundle: Bundle) { ) { Header() Body() - CollapsableDateTime(shouldDismiss) + CollapsableDateTime(shouldDismiss, isCollapsed) } } } @@ -206,7 +209,7 @@ class DateTimeCompose(val bundle: Bundle) { if (currTime < laterToday) { TimeOption( - label = "Later Today", + label = stringResource(R.string.later_today), timeString = laterTodayStr ) { timeState.value = laterToday @@ -215,7 +218,7 @@ class DateTimeCompose(val bundle: Bundle) { if (tomorrow.dayOfWeek < DayOfWeek.SATURDAY) { TimeOption( - label = "Tomorrow", + label = stringResource(R.string.tomorrow), timeString = tomorrowStr ) { timeState.value = tomorrow @@ -224,7 +227,7 @@ class DateTimeCompose(val bundle: Bundle) { if (currTime.dayOfWeek < DayOfWeek.SATURDAY) { TimeOption( - label = "This weekend", + label = stringResource(R.string.this_weekend), timeString = thisWeekendStr ) { timeState.value = thisWeekend @@ -232,7 +235,7 @@ class DateTimeCompose(val bundle: Bundle) { } TimeOption( - label = "Next weekend", + label = stringResource(R.string.next_week), timeString = nextWeekStr ) { timeState.value = nextWeek @@ -247,8 +250,8 @@ class DateTimeCompose(val bundle: Bundle) { modifier = Modifier .padding(8.dp) ) { - Text("Remind Me Later") - Spacer(modifier = Modifier.width(32.dp)) + Text("Remind Me Later", modifier = Modifier.weight(1f)) + // Spacer(modifier = Modifier.width(32.dp)) val reminderState = chatViewModel.getReminderExistState .asFlow() @@ -271,30 +274,28 @@ class DateTimeCompose(val bundle: Bundle) { @OptIn(ExperimentalMaterial3Api::class) @Composable - private fun CollapsableDateTime(shouldDismiss: MutableState) { - var isCollapsed by remember { mutableStateOf(true) } - GeneralIconButton(icon = Icons.Filled.DateRange, label = "Custom") { isCollapsed = !isCollapsed } + 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) { + if (!isCollapsed.value) { 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 { - // FIXME check out the offset logic here - // it works, i think. Need to test it out. I'm not sure if I'm missing something - LocalDateTime.ofEpochSecond(it / 1000, 0, ZoneOffset.ofTotalSeconds(0)) + val instant = Instant.ofEpochMilli(it) + LocalDateTime.ofInstant(instant, ZoneOffset.UTC) // Google sends time in UTC } if (date != null) { val year = date.year 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/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