feat(talk): меню сообщения — Напоминание с пресетами (P1 talk.diff)
This commit is contained in:
@@ -807,6 +807,7 @@ fun TalkMessageActionSheet(
|
||||
onCopy: (TalkMessage) -> Unit,
|
||||
onCopyLink: (TalkMessage) -> Unit,
|
||||
onForwardNoteToSelf: (TalkMessage) -> Unit,
|
||||
onSetReminder: (TalkMessage, ReminderPreset) -> Unit,
|
||||
) {
|
||||
if (message == null) return
|
||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
@@ -841,6 +842,21 @@ fun TalkMessageActionSheet(
|
||||
text = "Переслать в «Личные заметки»",
|
||||
onClick = { onForwardNoteToSelf(message) },
|
||||
)
|
||||
Text(
|
||||
"Напоминание:",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = F7Colors.TextSecondary,
|
||||
)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
listOf(
|
||||
"Сегодня" to ReminderPreset.TODAY,
|
||||
"Завтра" to ReminderPreset.TOMORROW,
|
||||
"Выходные" to ReminderPreset.WEEKEND,
|
||||
"Неделя" to ReminderPreset.NEXT_WEEK,
|
||||
).forEach { (label, preset) ->
|
||||
F7TextButton(text = label, onClick = { onSetReminder(message, preset) })
|
||||
}
|
||||
}
|
||||
}
|
||||
if (canModify) {
|
||||
F7TextButton(text = "Изменить", onClick = { onEdit(message) })
|
||||
|
||||
@@ -321,6 +321,24 @@ class TalkRepository {
|
||||
}
|
||||
}
|
||||
|
||||
/** Напоминание на сообщение (timestamp в секундах). OCS v1. */
|
||||
suspend fun setReminder(session: AuthSession, roomToken: String, messageId: Long, timestamp: Long) {
|
||||
val client = authedClient(session)
|
||||
val url = spreedApi(session, "v1") + "/chat/$roomToken/$messageId/reminder?format=json"
|
||||
val body = FormBody.Builder().add("timestamp", timestamp.toString()).build()
|
||||
val request = Request.Builder()
|
||||
.url(url)
|
||||
.header("OCS-APIRequest", "true")
|
||||
.header("Accept", "application/json")
|
||||
.post(body)
|
||||
.build()
|
||||
client.newCall(request).execute().use { response ->
|
||||
if (response.code != 201 && !response.isSuccessful) {
|
||||
error("Talk reminder failed: HTTP ${response.code}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun authedClient(session: AuthSession): OkHttpClient =
|
||||
NetworkFactory.newAuthedClient(session.username, session.appPassword, session.trustAllCerts)
|
||||
|
||||
|
||||
@@ -296,6 +296,7 @@ fun TalkScreen(
|
||||
onDeleteMessage = { vm.deleteMessage(session, it.id) },
|
||||
onEditMessage = { msg, text -> vm.editMessage(session, msg.id, text) },
|
||||
onForwardNoteToSelf = { vm.forwardToNoteToSelf(session, it) },
|
||||
onSetReminder = { msg, preset -> vm.setMessageReminder(session, msg.id, preset) },
|
||||
onMentionQuery = { vm.setMentionQuery(session, it) },
|
||||
onMentionSelected = { mention ->
|
||||
draft = insertMentionIntoDraft(draft, mention)
|
||||
@@ -435,6 +436,7 @@ private fun ChatContent(
|
||||
onDeleteMessage: (TalkMessage) -> Unit,
|
||||
onEditMessage: (TalkMessage, String) -> Unit,
|
||||
onForwardNoteToSelf: (TalkMessage) -> Unit,
|
||||
onSetReminder: (TalkMessage, ReminderPreset) -> Unit,
|
||||
onMentionQuery: (String?) -> Unit,
|
||||
onMentionSelected: (TalkMention) -> Unit,
|
||||
onClearReply: () -> Unit,
|
||||
@@ -532,6 +534,11 @@ private fun ChatContent(
|
||||
Toast.makeText(context, "Переслано в «Личные заметки»", Toast.LENGTH_SHORT).show()
|
||||
actionMessage = null
|
||||
},
|
||||
onSetReminder = { msg, preset ->
|
||||
onSetReminder(msg, preset)
|
||||
Toast.makeText(context, "Напоминание установлено", Toast.LENGTH_SHORT).show()
|
||||
actionMessage = null
|
||||
},
|
||||
)
|
||||
|
||||
editingMessage?.let { message ->
|
||||
|
||||
@@ -13,6 +13,15 @@ import kotlinx.coroutines.isActive
|
||||
import ru.forbion.f7cloud.core.auth.AuthSession
|
||||
import ru.forbion.f7cloud.core.designsystem.AppForegroundTracker
|
||||
import ru.forbion.f7cloud.core.network.UnauthorizedException
|
||||
import java.util.Calendar
|
||||
|
||||
/** Пресеты напоминания по сообщению (как в веб-Talk). */
|
||||
enum class ReminderPreset {
|
||||
TODAY,
|
||||
TOMORROW,
|
||||
WEEKEND,
|
||||
NEXT_WEEK,
|
||||
}
|
||||
|
||||
data class TalkUiState(
|
||||
val loading: Boolean = false,
|
||||
@@ -616,6 +625,52 @@ class TalkViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
/** Напоминание на сообщение по пресету (сегодня/завтра/выходные/неделя). */
|
||||
fun setMessageReminder(session: AuthSession, messageId: Long, preset: ReminderPreset) {
|
||||
val token = _state.value.selectedRoomToken ?: return
|
||||
val timestamp = reminderTimestamp(preset)
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
runCatching { repository.setReminder(session, token, messageId, timestamp) }
|
||||
.onFailure { t ->
|
||||
_state.value = _state.value.copy(
|
||||
error = t.message ?: "Не удалось поставить напоминание",
|
||||
unauthorized = t is UnauthorizedException,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun reminderTimestamp(preset: ReminderPreset): Long {
|
||||
val cal = Calendar.getInstance()
|
||||
when (preset) {
|
||||
ReminderPreset.TODAY -> cal.setTime(REMINDER_HOUR_EVENING)
|
||||
ReminderPreset.TOMORROW -> {
|
||||
cal.add(Calendar.DAY_OF_YEAR, 1)
|
||||
cal.setTime(REMINDER_HOUR_MORNING)
|
||||
}
|
||||
ReminderPreset.WEEKEND -> {
|
||||
while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) {
|
||||
cal.add(Calendar.DAY_OF_YEAR, 1)
|
||||
}
|
||||
cal.setTime(REMINDER_HOUR_MORNING)
|
||||
}
|
||||
ReminderPreset.NEXT_WEEK -> {
|
||||
do {
|
||||
cal.add(Calendar.DAY_OF_YEAR, 1)
|
||||
} while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY)
|
||||
cal.setTime(REMINDER_HOUR_MORNING)
|
||||
}
|
||||
}
|
||||
return cal.timeInMillis / MILLIS_IN_SECOND
|
||||
}
|
||||
|
||||
private fun Calendar.setTime(hour: Int) {
|
||||
set(Calendar.HOUR_OF_DAY, hour)
|
||||
set(Calendar.MINUTE, 0)
|
||||
set(Calendar.SECOND, 0)
|
||||
set(Calendar.MILLISECOND, 0)
|
||||
}
|
||||
|
||||
fun deleteMessage(session: AuthSession, messageId: Long) {
|
||||
val token = _state.value.selectedRoomToken ?: return
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
@@ -774,5 +829,9 @@ class TalkViewModel(
|
||||
|
||||
/** spreed conversation type: note-to-self (Личные заметки). */
|
||||
private const val ROOM_TYPE_NOTE_TO_SELF = 6
|
||||
|
||||
private const val MILLIS_IN_SECOND = 1000L
|
||||
private const val REMINDER_HOUR_EVENING = 18
|
||||
private const val REMINDER_HOUR_MORNING = 8
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user