Start reworking date formatting
This commit is contained in:
parent
bf0b6d738a
commit
73ab32fd92
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.date
|
||||||
|
|
||||||
|
import android.text.format.DateFormat
|
||||||
|
import im.vector.app.core.resources.LocaleProvider
|
||||||
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class AbbrevDateFormatterProvider @Inject constructor(private val localeProvider: LocaleProvider) : DateFormatterProvider {
|
||||||
|
|
||||||
|
override val dateWithMonthFormatter: DateTimeFormatter by lazy {
|
||||||
|
DateTimeFormatter.ofPattern("d MMM", localeProvider.current())
|
||||||
|
}
|
||||||
|
|
||||||
|
override val dateWithYearFormatter: DateTimeFormatter by lazy {
|
||||||
|
DateTimeFormatter.ofPattern("dd.MM.yyyy",localeProvider.current())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.date
|
||||||
|
|
||||||
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
|
|
||||||
|
interface DateFormatterProvider {
|
||||||
|
|
||||||
|
val dateWithMonthFormatter: DateTimeFormatter
|
||||||
|
|
||||||
|
val dateWithYearFormatter: DateTimeFormatter
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.date
|
||||||
|
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class DateFormatterProviders @Inject constructor(private val defaultDateFormatterProvider: DefaultDateFormatterProvider,
|
||||||
|
private val abbrevDateFormatterProvider: AbbrevDateFormatterProvider) {
|
||||||
|
|
||||||
|
fun provide(abbrev: Boolean): DateFormatterProvider {
|
||||||
|
return if (abbrev) {
|
||||||
|
abbrevDateFormatterProvider
|
||||||
|
} else {
|
||||||
|
defaultDateFormatterProvider
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.date
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.text.format.DateFormat
|
||||||
|
import im.vector.app.core.resources.LocaleProvider
|
||||||
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class DefaultDateFormatterProvider @Inject constructor(private val context: Context,
|
||||||
|
private val localeProvider: LocaleProvider)
|
||||||
|
: DateFormatterProvider {
|
||||||
|
|
||||||
|
override val dateWithMonthFormatter: DateTimeFormatter by lazy {
|
||||||
|
DateTimeFormatter.ofPattern(DateFormat.getBestDateTimePattern(localeProvider.current(), "d MMMMM"))
|
||||||
|
}
|
||||||
|
|
||||||
|
override val dateWithYearFormatter: DateTimeFormatter by lazy {
|
||||||
|
DateTimeFormatter.ofPattern(DateFormat.getBestDateTimePattern(localeProvider.current(), "d MMM y"))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,8 +19,11 @@ package im.vector.app.core.date
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.format.DateFormat
|
import android.text.format.DateFormat
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
|
import im.vector.app.core.resources.DateProvider
|
||||||
import im.vector.app.core.resources.LocaleProvider
|
import im.vector.app.core.resources.LocaleProvider
|
||||||
|
import im.vector.app.core.resources.toTimestamp
|
||||||
import org.threeten.bp.LocalDateTime
|
import org.threeten.bp.LocalDateTime
|
||||||
|
import org.threeten.bp.Period
|
||||||
import org.threeten.bp.format.DateTimeFormatter
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@ -41,22 +44,77 @@ fun startOfDay(time: Long): Long {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class VectorDateFormatter @Inject constructor(private val context: Context,
|
class VectorDateFormatter @Inject constructor(private val context: Context,
|
||||||
private val localeProvider: LocaleProvider) {
|
private val localeProvider: LocaleProvider,
|
||||||
|
private val dateFormatterProviders: DateFormatterProviders) {
|
||||||
|
|
||||||
private val messageHourFormatter by lazy {
|
private val hourFormatter by lazy {
|
||||||
DateTimeFormatter.ofPattern("H:mm", localeProvider.current())
|
if (DateFormat.is24HourFormat(context)) {
|
||||||
|
DateTimeFormatter.ofPattern("H:mm", localeProvider.current())
|
||||||
|
} else {
|
||||||
|
DateTimeFormatter.ofPattern("h:mm a", localeProvider.current())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val messageDayFormatter by lazy {
|
private val dayFormatter by lazy {
|
||||||
DateTimeFormatter.ofPattern(DateFormat.getBestDateTimePattern(localeProvider.current(), "EEE d MMM"))
|
DateTimeFormatter.ofPattern("EEE", localeProvider.current())
|
||||||
|
}
|
||||||
|
|
||||||
|
private val fullDateFormatter by lazy {
|
||||||
|
if (DateFormat.is24HourFormat(context)) {
|
||||||
|
DateTimeFormatter.ofPattern("EEE, d MMM yyyy H:mm", localeProvider.current())
|
||||||
|
} else {
|
||||||
|
DateTimeFormatter.ofPattern("EEE, d MMM yyyy h:mm a", localeProvider.current())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun formatMessageHour(localDateTime: LocalDateTime): String {
|
fun formatMessageHour(localDateTime: LocalDateTime): String {
|
||||||
return messageHourFormatter.format(localDateTime)
|
return hourFormatter.format(localDateTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun formatMessageDay(localDateTime: LocalDateTime): String {
|
fun formatMessageDay(localDateTime: LocalDateTime): String {
|
||||||
return messageDayFormatter.format(localDateTime)
|
return dayFormatter.format(localDateTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun formatMessageDayWithMonth(localDateTime: LocalDateTime, abbrev: Boolean = false): String {
|
||||||
|
return dateFormatterProviders.provide(abbrev).dateWithMonthFormatter.format(localDateTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun formatMessageDayWithYear(localDateTime: LocalDateTime, abbrev: Boolean = false): String {
|
||||||
|
return dateFormatterProviders.provide(abbrev).dateWithYearFormatter.format(localDateTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun formatMessageDate(
|
||||||
|
date: LocalDateTime?,
|
||||||
|
showFullDate: Boolean = false,
|
||||||
|
onlyTimeIfSameDay: Boolean = false,
|
||||||
|
useRelative: Boolean = false,
|
||||||
|
alwaysShowYear: Boolean = false,
|
||||||
|
abbrev: Boolean = false
|
||||||
|
): String {
|
||||||
|
if (date == null) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if (showFullDate) {
|
||||||
|
return fullDateFormatter.format(date)
|
||||||
|
}
|
||||||
|
val currentDate = DateProvider.currentLocalDateTime()
|
||||||
|
val isSameDay = date.toLocalDate() == currentDate.toLocalDate()
|
||||||
|
return if (onlyTimeIfSameDay && isSameDay) {
|
||||||
|
formatMessageHour(date)
|
||||||
|
} else {
|
||||||
|
val period = Period.between(date.toLocalDate(), currentDate.toLocalDate())
|
||||||
|
if (period.years >= 1 || alwaysShowYear) {
|
||||||
|
formatMessageDayWithYear(date, abbrev)
|
||||||
|
} else if (period.months >= 1) {
|
||||||
|
formatMessageDayWithMonth(date, abbrev)
|
||||||
|
} else if (useRelative && period.days < 2) {
|
||||||
|
getRelativeDay(date.toTimestamp())
|
||||||
|
} else if (useRelative && period.days < 7) {
|
||||||
|
formatMessageDay(date)
|
||||||
|
} else {
|
||||||
|
formatMessageDayWithMonth(date, abbrev)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,12 +129,22 @@ class VectorDateFormatter @Inject constructor(private val context: Context,
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
|
var flags = DateUtils.FORMAT_SHOW_WEEKDAY
|
||||||
|
|
||||||
return DateUtils.getRelativeDateTimeString(
|
return DateUtils.getRelativeDateTimeString(
|
||||||
context,
|
context,
|
||||||
time,
|
time,
|
||||||
DateUtils.DAY_IN_MILLIS,
|
DateUtils.DAY_IN_MILLIS,
|
||||||
now - startOfDay(now - 2 * DateUtils.DAY_IN_MILLIS),
|
now - startOfDay(now - 2 * DateUtils.DAY_IN_MILLIS),
|
||||||
DateUtils.FORMAT_SHOW_WEEKDAY or DateUtils.FORMAT_SHOW_TIME
|
flags
|
||||||
).toString()
|
).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getRelativeDay(ts: Long): String {
|
||||||
|
return DateUtils.getRelativeTimeSpanString(
|
||||||
|
ts,
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
DateUtils.DAY_IN_MILLIS,
|
||||||
|
DateUtils.FORMAT_SHOW_WEEKDAY).toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,12 @@ package im.vector.app.core.resources
|
|||||||
import org.threeten.bp.Instant
|
import org.threeten.bp.Instant
|
||||||
import org.threeten.bp.LocalDateTime
|
import org.threeten.bp.LocalDateTime
|
||||||
import org.threeten.bp.ZoneId
|
import org.threeten.bp.ZoneId
|
||||||
|
import org.threeten.bp.ZoneOffset
|
||||||
|
|
||||||
object DateProvider {
|
object DateProvider {
|
||||||
|
|
||||||
private val zoneId = ZoneId.systemDefault()
|
private val zoneId = ZoneId.systemDefault()
|
||||||
|
private val zoneOffset = ZoneOffset.UTC
|
||||||
|
|
||||||
fun toLocalDateTime(timestamp: Long?): LocalDateTime {
|
fun toLocalDateTime(timestamp: Long?): LocalDateTime {
|
||||||
val instant = Instant.ofEpochMilli(timestamp ?: 0)
|
val instant = Instant.ofEpochMilli(timestamp ?: 0)
|
||||||
@ -33,4 +35,11 @@ object DateProvider {
|
|||||||
val instant = Instant.now()
|
val instant = Instant.now()
|
||||||
return LocalDateTime.ofInstant(instant, zoneId)
|
return LocalDateTime.ofInstant(instant, zoneId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toTimestamp(localDateTime: LocalDateTime): Long {
|
||||||
|
return localDateTime.toInstant(zoneOffset).toEpochMilli()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun LocalDateTime.toTimestamp(): Long = DateProvider.toTimestamp(this)
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import im.vector.app.core.date.VectorDateFormatter
|
|||||||
import im.vector.app.core.epoxy.LoadingItem_
|
import im.vector.app.core.epoxy.LoadingItem_
|
||||||
import im.vector.app.core.extensions.localDateTime
|
import im.vector.app.core.extensions.localDateTime
|
||||||
import im.vector.app.core.extensions.nextOrNull
|
import im.vector.app.core.extensions.nextOrNull
|
||||||
|
import im.vector.app.core.resources.DateProvider
|
||||||
import im.vector.app.features.home.room.detail.RoomDetailAction
|
import im.vector.app.features.home.room.detail.RoomDetailAction
|
||||||
import im.vector.app.features.home.room.detail.RoomDetailViewState
|
import im.vector.app.features.home.room.detail.RoomDetailViewState
|
||||||
import im.vector.app.features.home.room.detail.UnreadState
|
import im.vector.app.features.home.room.detail.UnreadState
|
||||||
@ -53,7 +54,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageImageInfoCon
|
|||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import org.threeten.bp.LocalDateTime
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TimelineEventController @Inject constructor(private val dateFormatter: VectorDateFormatter,
|
class TimelineEventController @Inject constructor(private val dateFormatter: VectorDateFormatter,
|
||||||
@ -333,13 +333,16 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
|||||||
) {
|
) {
|
||||||
requestModelBuild()
|
requestModelBuild()
|
||||||
}
|
}
|
||||||
val daySeparatorItem = buildDaySeparatorItem(addDaySeparator, date)
|
val daySeparatorItem = buildDaySeparatorItem(addDaySeparator, event.root.originServerTs)
|
||||||
return CacheItemData(event.localId, event.root.eventId, eventModel, mergedHeaderModel, daySeparatorItem)
|
return CacheItemData(event.localId, event.root.eventId, eventModel, mergedHeaderModel, daySeparatorItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildDaySeparatorItem(addDaySeparator: Boolean, date: LocalDateTime): DaySeparatorItem? {
|
private fun buildDaySeparatorItem(addDaySeparator: Boolean, originServerTs: Long?): DaySeparatorItem? {
|
||||||
return if (addDaySeparator) {
|
return if (addDaySeparator) {
|
||||||
val formattedDay = dateFormatter.formatMessageDay(date)
|
val formattedDay = dateFormatter.formatMessageDate(
|
||||||
|
date = DateProvider.toLocalDateTime(originServerTs),
|
||||||
|
alwaysShowYear = true
|
||||||
|
)
|
||||||
DaySeparatorItem_().formattedDay(formattedDay).id(formattedDay)
|
DaySeparatorItem_().formattedDay(formattedDay).id(formattedDay)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
|
@ -23,6 +23,7 @@ import im.vector.app.core.extensions.canReact
|
|||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
|
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
import java.time.LocalDateTime
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
@ -56,11 +57,7 @@ data class MessageActionState(
|
|||||||
|
|
||||||
constructor(args: TimelineEventFragmentArgs) : this(roomId = args.roomId, eventId = args.eventId, informationData = args.informationData)
|
constructor(args: TimelineEventFragmentArgs) : this(roomId = args.roomId, eventId = args.eventId, informationData = args.informationData)
|
||||||
|
|
||||||
private val dateFormat = SimpleDateFormat("EEE, d MMM yyyy HH:mm", Locale.getDefault())
|
|
||||||
|
|
||||||
fun senderName(): String = informationData.memberName?.toString() ?: ""
|
fun senderName(): String = informationData.memberName?.toString() ?: ""
|
||||||
|
|
||||||
fun time(): String? = timelineEvent()?.root?.originServerTs?.let { dateFormat.format(Date(it)) } ?: ""
|
|
||||||
|
|
||||||
fun canReact() = timelineEvent()?.canReact() == true && actionPermissions.canReact
|
fun canReact() = timelineEvent()?.canReact() == true && actionPermissions.canReact
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,14 @@ import com.airbnb.epoxy.TypedEpoxyController
|
|||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import im.vector.app.EmojiCompatFontProvider
|
import im.vector.app.EmojiCompatFontProvider
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.date.VectorDateFormatter
|
||||||
import im.vector.app.core.epoxy.bottomsheet.BottomSheetQuickReactionsItem
|
import im.vector.app.core.epoxy.bottomsheet.BottomSheetQuickReactionsItem
|
||||||
import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem
|
import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem
|
||||||
import im.vector.app.core.epoxy.bottomsheet.bottomSheetMessagePreviewItem
|
import im.vector.app.core.epoxy.bottomsheet.bottomSheetMessagePreviewItem
|
||||||
import im.vector.app.core.epoxy.bottomsheet.bottomSheetQuickReactionsItem
|
import im.vector.app.core.epoxy.bottomsheet.bottomSheetQuickReactionsItem
|
||||||
import im.vector.app.core.epoxy.bottomsheet.bottomSheetSendStateItem
|
import im.vector.app.core.epoxy.bottomsheet.bottomSheetSendStateItem
|
||||||
import im.vector.app.core.epoxy.dividerItem
|
import im.vector.app.core.epoxy.dividerItem
|
||||||
|
import im.vector.app.core.extensions.localDateTime
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||||
@ -40,13 +42,16 @@ import javax.inject.Inject
|
|||||||
class MessageActionsEpoxyController @Inject constructor(
|
class MessageActionsEpoxyController @Inject constructor(
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
private val fontProvider: EmojiCompatFontProvider
|
private val fontProvider: EmojiCompatFontProvider,
|
||||||
|
private val dateFormatter: VectorDateFormatter
|
||||||
) : TypedEpoxyController<MessageActionState>() {
|
) : TypedEpoxyController<MessageActionState>() {
|
||||||
|
|
||||||
var listener: MessageActionsEpoxyControllerListener? = null
|
var listener: MessageActionsEpoxyControllerListener? = null
|
||||||
|
|
||||||
override fun buildModels(state: MessageActionState) {
|
override fun buildModels(state: MessageActionState) {
|
||||||
// Message preview
|
// Message preview
|
||||||
|
val date = state.timelineEvent()?.root?.localDateTime()
|
||||||
|
val formattedDate = dateFormatter.formatMessageDate(date, showFullDate = true)
|
||||||
bottomSheetMessagePreviewItem {
|
bottomSheetMessagePreviewItem {
|
||||||
id("preview")
|
id("preview")
|
||||||
avatarRenderer(avatarRenderer)
|
avatarRenderer(avatarRenderer)
|
||||||
@ -54,7 +59,7 @@ class MessageActionsEpoxyController @Inject constructor(
|
|||||||
movementMethod(createLinkMovementMethod(listener))
|
movementMethod(createLinkMovementMethod(listener))
|
||||||
userClicked { listener?.didSelectMenuAction(EventSharedAction.OpenUserProfile(state.informationData.senderId)) }
|
userClicked { listener?.didSelectMenuAction(EventSharedAction.OpenUserProfile(state.informationData.senderId)) }
|
||||||
body(state.messageBody.linkify(listener))
|
body(state.messageBody.linkify(listener))
|
||||||
time(state.time())
|
time(formattedDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send state
|
// Send state
|
||||||
|
@ -83,7 +83,7 @@ class ViewEditHistoryEpoxyController(private val context: Context,
|
|||||||
if (lastDate?.get(Calendar.DAY_OF_YEAR) != evDate.get(Calendar.DAY_OF_YEAR)) {
|
if (lastDate?.get(Calendar.DAY_OF_YEAR) != evDate.get(Calendar.DAY_OF_YEAR)) {
|
||||||
// need to display header with day
|
// need to display header with day
|
||||||
val dateString = if (DateUtils.isToday(evDate.timeInMillis)) context.getString(R.string.today)
|
val dateString = if (DateUtils.isToday(evDate.timeInMillis)) context.getString(R.string.today)
|
||||||
else dateFormatter.formatMessageDay(timelineEvent.localDateTime())
|
else dateFormatter.formatMessageDayWithMonth(timelineEvent.localDateTime())
|
||||||
genericItemHeader {
|
genericItemHeader {
|
||||||
id(evDate.hashCode())
|
id(evDate.hashCode())
|
||||||
text(dateString)
|
text(dateString)
|
||||||
|
@ -29,12 +29,12 @@ import im.vector.app.core.platform.EmptyAction
|
|||||||
import im.vector.app.core.platform.EmptyViewEvents
|
import im.vector.app.core.platform.EmptyViewEvents
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFragmentArgs
|
import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFragmentArgs
|
||||||
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.Single
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.room.model.ReactionAggregatedSummary
|
import org.matrix.android.sdk.api.session.room.model.ReactionAggregatedSummary
|
||||||
import org.matrix.android.sdk.rx.RxRoom
|
import org.matrix.android.sdk.rx.RxRoom
|
||||||
import org.matrix.android.sdk.rx.unwrap
|
import org.matrix.android.sdk.rx.unwrap
|
||||||
import io.reactivex.Observable
|
|
||||||
import io.reactivex.Single
|
|
||||||
|
|
||||||
data class DisplayReactionsViewState(
|
data class DisplayReactionsViewState(
|
||||||
val eventId: String,
|
val eventId: String,
|
||||||
|
@ -21,7 +21,6 @@ import im.vector.app.R
|
|||||||
import im.vector.app.core.date.VectorDateFormatter
|
import im.vector.app.core.date.VectorDateFormatter
|
||||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||||
import im.vector.app.core.extensions.localDateTime
|
import im.vector.app.core.extensions.localDateTime
|
||||||
import im.vector.app.core.resources.DateProvider
|
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.utils.DebouncedClickListener
|
import im.vector.app.core.utils.DebouncedClickListener
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
@ -53,8 +52,8 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createInvitationItem(roomSummary: RoomSummary,
|
private fun createInvitationItem(roomSummary: RoomSummary,
|
||||||
changeMembershipState: ChangeMembershipState,
|
changeMembershipState: ChangeMembershipState,
|
||||||
listener: RoomSummaryController.Listener?): VectorEpoxyModel<*> {
|
listener: RoomSummaryController.Listener?): VectorEpoxyModel<*> {
|
||||||
val secondLine = if (roomSummary.isDirect) {
|
val secondLine = if (roomSummary.isDirect) {
|
||||||
roomSummary.inviterId
|
roomSummary.inviterId
|
||||||
} else {
|
} else {
|
||||||
@ -87,15 +86,13 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
|
|||||||
var latestEventTime: CharSequence = ""
|
var latestEventTime: CharSequence = ""
|
||||||
val latestEvent = roomSummary.latestPreviewableEvent
|
val latestEvent = roomSummary.latestPreviewableEvent
|
||||||
if (latestEvent != null) {
|
if (latestEvent != null) {
|
||||||
val date = latestEvent.root.localDateTime()
|
|
||||||
val currentDate = DateProvider.currentLocalDateTime()
|
|
||||||
val isSameDay = date.toLocalDate() == currentDate.toLocalDate()
|
|
||||||
latestFormattedEvent = displayableEventFormatter.format(latestEvent, roomSummary.isDirect.not())
|
latestFormattedEvent = displayableEventFormatter.format(latestEvent, roomSummary.isDirect.not())
|
||||||
latestEventTime = if (isSameDay) {
|
latestEventTime = dateFormatter.formatMessageDate(
|
||||||
dateFormatter.formatMessageHour(date)
|
date = latestEvent.root.localDateTime(),
|
||||||
} else {
|
useRelative = true,
|
||||||
dateFormatter.formatMessageDay(date)
|
onlyTimeIfSameDay = true,
|
||||||
}
|
abbrev = true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val typingMessage = typingHelper.getTypingMessage(roomSummary.typingUsers)
|
val typingMessage = typingHelper.getTypingMessage(roomSummary.typingUsers)
|
||||||
return RoomSummaryItem_()
|
return RoomSummaryItem_()
|
||||||
|
@ -79,7 +79,7 @@ class DataAttachmentRoomProvider(
|
|||||||
val timeLineEvent = room?.getTimeLineEvent(item.eventId)
|
val timeLineEvent = room?.getTimeLineEvent(item.eventId)
|
||||||
if (timeLineEvent != null) {
|
if (timeLineEvent != null) {
|
||||||
val dateString = timeLineEvent.root.localDateTime().let {
|
val dateString = timeLineEvent.root.localDateTime().let {
|
||||||
"${dateFormatter.formatMessageDay(it)} at ${dateFormatter.formatMessageHour(it)} "
|
"${dateFormatter.formatMessageDayWithMonth(it)} at ${dateFormatter.formatMessageHour(it)} "
|
||||||
}
|
}
|
||||||
overlayView?.updateWith("${position + 1} of ${attachments.size}", "${timeLineEvent.senderInfo.displayName} $dateString")
|
overlayView?.updateWith("${position + 1} of ${attachments.size}", "${timeLineEvent.senderInfo.displayName} $dateString")
|
||||||
overlayView?.videoControlsGroup?.isVisible = timeLineEvent.root.isVideoMessage()
|
overlayView?.videoControlsGroup?.isVisible = timeLineEvent.root.isVideoMessage()
|
||||||
|
@ -129,7 +129,7 @@ class RoomEventsAttachmentProvider(
|
|||||||
super.overlayViewAtPosition(context, position)
|
super.overlayViewAtPosition(context, position)
|
||||||
val item = attachments[position]
|
val item = attachments[position]
|
||||||
val dateString = item.root.localDateTime().let {
|
val dateString = item.root.localDateTime().let {
|
||||||
"${dateFormatter.formatMessageDay(it)} at ${dateFormatter.formatMessageHour(it)} "
|
"${dateFormatter.formatMessageDayWithMonth(it)} at ${dateFormatter.formatMessageHour(it)} "
|
||||||
}
|
}
|
||||||
overlayView?.updateWith("${position + 1} of ${attachments.size}", "${item.senderInfo.displayName} $dateString")
|
overlayView?.updateWith("${position + 1} of ${attachments.size}", "${item.senderInfo.displayName} $dateString")
|
||||||
overlayView?.videoControlsGroup?.isVisible = item.root.isVideoMessage()
|
overlayView?.videoControlsGroup?.isVisible = item.root.isVideoMessage()
|
||||||
|
@ -18,12 +18,12 @@ package im.vector.app.features.roomprofile.uploads.files
|
|||||||
|
|
||||||
import com.airbnb.epoxy.TypedEpoxyController
|
import com.airbnb.epoxy.TypedEpoxyController
|
||||||
import com.airbnb.epoxy.VisibilityState
|
import com.airbnb.epoxy.VisibilityState
|
||||||
import org.matrix.android.sdk.api.session.room.uploads.UploadEvent
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.date.VectorDateFormatter
|
import im.vector.app.core.date.VectorDateFormatter
|
||||||
import im.vector.app.core.epoxy.loadingItem
|
import im.vector.app.core.epoxy.loadingItem
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.roomprofile.uploads.RoomUploadsViewState
|
import im.vector.app.features.roomprofile.uploads.RoomUploadsViewState
|
||||||
|
import org.matrix.android.sdk.api.session.room.uploads.UploadEvent
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class UploadsFileController @Inject constructor(
|
class UploadsFileController @Inject constructor(
|
||||||
|
@ -94,7 +94,7 @@ class GossipingEventsEpoxyController @Inject constructor(
|
|||||||
)
|
)
|
||||||
description(
|
description(
|
||||||
span {
|
span {
|
||||||
+vectorDateFormatter.formatMessageDay(DateProvider.toLocalDateTime(event.ageLocalTs))
|
+vectorDateFormatter.formatMessageDayWithMonth(DateProvider.toLocalDateTime(event.ageLocalTs))
|
||||||
+" ${vectorDateFormatter.formatMessageHour(DateProvider.toLocalDateTime(event.ageLocalTs))}"
|
+" ${vectorDateFormatter.formatMessageHour(DateProvider.toLocalDateTime(event.ageLocalTs))}"
|
||||||
span("\nfrom: ") {
|
span("\nfrom: ") {
|
||||||
textStyle = "bold"
|
textStyle = "bold"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user