mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-29 04:39:53 +00:00
core, mobile: correctly check whether date is recent (#2559)
This commit is contained in:
parent
fb72dfcdee
commit
f581e91f19
6 changed files with 124 additions and 15 deletions
|
@ -1624,8 +1624,9 @@ fun getTimestampText(t: Instant): String {
|
||||||
val tz = TimeZone.currentSystemDefault()
|
val tz = TimeZone.currentSystemDefault()
|
||||||
val now: LocalDateTime = Clock.System.now().toLocalDateTime(tz)
|
val now: LocalDateTime = Clock.System.now().toLocalDateTime(tz)
|
||||||
val time: LocalDateTime = t.toLocalDateTime(tz)
|
val time: LocalDateTime = t.toLocalDateTime(tz)
|
||||||
|
val period = now.date.minus(time.date)
|
||||||
val recent = now.date == time.date ||
|
val recent = now.date == time.date ||
|
||||||
(now.date.minus(time.date).days == 1 && now.hour < 12 && time.hour >= 18 )
|
(period.years == 0 && period.months == 0 && period.days == 1 && now.hour < 12 && time.hour >= 18 )
|
||||||
val dateFormatter =
|
val dateFormatter =
|
||||||
if (recent) {
|
if (recent) {
|
||||||
DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
|
DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
|
||||||
|
|
|
@ -2283,10 +2283,22 @@ let msgTimeFormat = Date.FormatStyle.dateTime.hour().minute()
|
||||||
let msgDateFormat = Date.FormatStyle.dateTime.day(.twoDigits).month(.twoDigits)
|
let msgDateFormat = Date.FormatStyle.dateTime.day(.twoDigits).month(.twoDigits)
|
||||||
|
|
||||||
public func formatTimestampText(_ date: Date) -> Text {
|
public func formatTimestampText(_ date: Date) -> Text {
|
||||||
let now = Calendar.current.dateComponents([.day, .hour], from: .now)
|
return Text(date, format: recent(date) ? msgTimeFormat : msgDateFormat)
|
||||||
let dc = Calendar.current.dateComponents([.day, .hour], from: date)
|
}
|
||||||
let recent = now.day == dc.day || ((now.day ?? 0) - (dc.day ?? 0) == 1 && (dc.hour ?? 0) >= 18 && (now.hour ?? 0) < 12)
|
|
||||||
return Text(date, format: recent ? msgTimeFormat : msgDateFormat)
|
private func recent(_ date: Date) -> Bool {
|
||||||
|
let now = Date()
|
||||||
|
let calendar = Calendar.current
|
||||||
|
|
||||||
|
guard let previousDay = calendar.date(byAdding: DateComponents(day: -1), to: now),
|
||||||
|
let previousDay18 = calendar.date(bySettingHour: 18, minute: 0, second: 0, of: previousDay),
|
||||||
|
let currentDay00 = calendar.date(bySettingHour: 0, minute: 0, second: 0, of: now),
|
||||||
|
let currentDay12 = calendar.date(bySettingHour: 12, minute: 0, second: 0, of: now) else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let isSameDay = calendar.isDate(date, inSameDayAs: now)
|
||||||
|
return isSameDay || (now < currentDay12 && date >= previousDay18 && date < currentDay00)
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CIStatus: Decodable {
|
public enum CIStatus: Decodable {
|
||||||
|
|
|
@ -374,6 +374,7 @@ test-suite simplex-chat-test
|
||||||
MobileTests
|
MobileTests
|
||||||
ProtocolTests
|
ProtocolTests
|
||||||
SchemaDump
|
SchemaDump
|
||||||
|
ViewTests
|
||||||
WebRTCTests
|
WebRTCTests
|
||||||
Paths_simplex_chat
|
Paths_simplex_chat
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
|
|
|
@ -24,9 +24,10 @@ import Data.Maybe (fromMaybe, isJust, isNothing, mapMaybe)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Data.Text.Encoding (decodeLatin1)
|
import Data.Text.Encoding (decodeLatin1)
|
||||||
import Data.Time.Clock (DiffTime, UTCTime)
|
import Data.Time (LocalTime (..), TimeOfDay (..), TimeZone (..), utcToLocalTime)
|
||||||
|
import Data.Time.Calendar (addDays)
|
||||||
|
import Data.Time.Clock (UTCTime)
|
||||||
import Data.Time.Format (defaultTimeLocale, formatTime)
|
import Data.Time.Format (defaultTimeLocale, formatTime)
|
||||||
import Data.Time.LocalTime (TimeZone, localDay, localTimeOfDay, timeOfDayToTime, utcToLocalTime)
|
|
||||||
import Data.Word (Word32)
|
import Data.Word (Word32)
|
||||||
import GHC.Generics (Generic)
|
import GHC.Generics (Generic)
|
||||||
import qualified Network.HTTP.Types as Q
|
import qualified Network.HTTP.Types as Q
|
||||||
|
@ -1107,16 +1108,22 @@ receivedWithTime_ ts tz from quote CIMeta {itemId, itemTs, itemEdited, itemDelet
|
||||||
_ -> ""
|
_ -> ""
|
||||||
|
|
||||||
ttyMsgTime :: CurrentTime -> TimeZone -> UTCTime -> StyledString
|
ttyMsgTime :: CurrentTime -> TimeZone -> UTCTime -> StyledString
|
||||||
ttyMsgTime currentTime tz time =
|
ttyMsgTime now tz time =
|
||||||
let localTime = utcToLocalTime tz time
|
let fmt = if recent now tz time then "%H:%M" else "%m-%d"
|
||||||
localCurrentTime = utcToLocalTime tz currentTime
|
localTime = utcToLocalTime tz time
|
||||||
fmt =
|
|
||||||
if (localDay localTime < localDay localCurrentTime)
|
|
||||||
&& (timeOfDayToTime (localTimeOfDay localTime) > (6 * 60 * 60 :: DiffTime))
|
|
||||||
then "%m-%d" -- if message is from yesterday or before and 6 hours has passed since midnight
|
|
||||||
else "%H:%M"
|
|
||||||
in styleTime $ formatTime defaultTimeLocale fmt localTime
|
in styleTime $ formatTime defaultTimeLocale fmt localTime
|
||||||
|
|
||||||
|
recent :: CurrentTime -> TimeZone -> UTCTime -> Bool
|
||||||
|
recent now tz time = do
|
||||||
|
let localNow = utcToLocalTime tz now
|
||||||
|
localNowDay = localDay localNow
|
||||||
|
localTime = utcToLocalTime tz time
|
||||||
|
localTimeDay = localDay localTime
|
||||||
|
previousDay18 = LocalTime (addDays (-1) localNowDay) (TimeOfDay 18 0 0)
|
||||||
|
currentDay12 = LocalTime localNowDay (TimeOfDay 12 0 0)
|
||||||
|
localNowDay == localTimeDay
|
||||||
|
|| (localNow < currentDay12 && localTime >= previousDay18 && localTimeDay < localNowDay)
|
||||||
|
|
||||||
viewSentMessage :: StyledString -> [StyledString] -> MsgContent -> CurrentTime -> TimeZone -> CIMeta c d -> [StyledString]
|
viewSentMessage :: StyledString -> [StyledString] -> MsgContent -> CurrentTime -> TimeZone -> CIMeta c d -> [StyledString]
|
||||||
viewSentMessage to quote mc ts tz meta@CIMeta {itemEdited, itemDeleted, itemLive} = sentWithTime_ ts tz (prependFirst to $ quote <> prependFirst (indent <> live) (ttyMsgContent mc)) meta
|
viewSentMessage to quote mc ts tz meta@CIMeta {itemEdited, itemDeleted, itemLive} = sentWithTime_ ts tz (prependFirst to $ quote <> prependFirst (indent <> live) (ttyMsgContent mc)) meta
|
||||||
where
|
where
|
||||||
|
|
|
@ -8,6 +8,7 @@ import ProtocolTests
|
||||||
import SchemaDump
|
import SchemaDump
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
import UnliftIO.Temporary (withTempDirectory)
|
import UnliftIO.Temporary (withTempDirectory)
|
||||||
|
import ViewTests
|
||||||
import WebRTCTests
|
import WebRTCTests
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
|
@ -15,6 +16,7 @@ main = do
|
||||||
setLogLevel LogError -- LogDebug
|
setLogLevel LogError -- LogDebug
|
||||||
withGlobalLogging logCfg . hspec $ do
|
withGlobalLogging logCfg . hspec $ do
|
||||||
describe "SimpleX chat markdown" markdownTests
|
describe "SimpleX chat markdown" markdownTests
|
||||||
|
describe "SimpleX chat view" viewTests
|
||||||
describe "SimpleX chat protocol" protocolTests
|
describe "SimpleX chat protocol" protocolTests
|
||||||
describe "WebRTC encryption" webRTCTests
|
describe "WebRTC encryption" webRTCTests
|
||||||
describe "Schema dump" schemaDumpTest
|
describe "Schema dump" schemaDumpTest
|
||||||
|
|
86
tests/ViewTests.hs
Normal file
86
tests/ViewTests.hs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
{-# LANGUAGE BlockArguments #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
|
module ViewTests where
|
||||||
|
|
||||||
|
import Data.Time
|
||||||
|
import Simplex.Chat.View
|
||||||
|
import Test.Hspec
|
||||||
|
|
||||||
|
viewTests :: Spec
|
||||||
|
viewTests = do
|
||||||
|
testRecent
|
||||||
|
|
||||||
|
testRecent :: Spec
|
||||||
|
testRecent = describe "recent" $ do
|
||||||
|
let tz = hoursToTimeZone 1
|
||||||
|
now1159 = UTCTime (fromGregorian 2023 6 7) (secondsToDiffTime $ 10 * 3600 + 59 * 60) -- 11:59 in tz
|
||||||
|
now1200 = UTCTime (fromGregorian 2023 6 7) (secondsToDiffTime $ 11 * 3600) -- 12:00 in tz
|
||||||
|
today0000 = UTCTime (fromGregorian 2023 6 6) (secondsToDiffTime $ 23 * 3600) -- 00:00 in tz
|
||||||
|
today0600 = UTCTime (fromGregorian 2023 6 7) (secondsToDiffTime $ 5 * 3600) -- 06:00 in tz
|
||||||
|
today1200 = UTCTime (fromGregorian 2023 6 7) (secondsToDiffTime $ 11 * 3600) -- 12:00 in tz
|
||||||
|
today1800 = UTCTime (fromGregorian 2023 6 7) (secondsToDiffTime $ 17 * 3600) -- 18:00 in tz
|
||||||
|
today2359 = UTCTime (fromGregorian 2023 6 7) (secondsToDiffTime $ 22 * 3600 + 59 * 60) -- 23:59 in tz
|
||||||
|
yesterday0000 = UTCTime (fromGregorian 2023 6 5) (secondsToDiffTime $ 23 * 3600) -- 00:00 in tz
|
||||||
|
yesterday1759 = UTCTime (fromGregorian 2023 6 6) (secondsToDiffTime $ 16 * 3600 + 59 * 60) -- 17:59 in tz
|
||||||
|
yesterday1800 = UTCTime (fromGregorian 2023 6 6) (secondsToDiffTime $ 17 * 3600) -- 18:00 in tz
|
||||||
|
yesterday2359 = UTCTime (fromGregorian 2023 6 6) (secondsToDiffTime $ 22 * 3600 + 59 * 60) -- 23:59 in tz
|
||||||
|
sameDayLastMonth1900 = UTCTime (fromGregorian 2023 5 7) (secondsToDiffTime $ 18 * 3600) -- 19:00 in tz
|
||||||
|
prevDayLastMonth1900 = UTCTime (fromGregorian 2023 5 6) (secondsToDiffTime $ 18 * 3600) -- 19:00 in tz
|
||||||
|
sameDayLastYear1900 = UTCTime (fromGregorian 2022 6 7) (secondsToDiffTime $ 18 * 3600) -- 19:00 in tz
|
||||||
|
prevDayLastYear1900 = UTCTime (fromGregorian 2022 6 6) (secondsToDiffTime $ 18 * 3600) -- 19:00 in tz
|
||||||
|
tomorrow0000 = UTCTime (fromGregorian 2023 6 7) (secondsToDiffTime $ 23 * 3600) -- 00:00 in tz
|
||||||
|
tomorrow1759 = UTCTime (fromGregorian 2023 6 8) (secondsToDiffTime $ 16 * 3600 + 59 * 60) -- 17:59 in tz
|
||||||
|
tomorrow1800 = UTCTime (fromGregorian 2023 6 8) (secondsToDiffTime $ 17 * 3600) -- 18:00 in tz
|
||||||
|
tomorrow2359 = UTCTime (fromGregorian 2023 6 8) (secondsToDiffTime $ 22 * 3600 + 59 * 60) -- 23:59 in tz
|
||||||
|
sameDayNextMonth1900 = UTCTime (fromGregorian 2023 7 7) (secondsToDiffTime $ 18 * 3600) -- 19:00 in tz
|
||||||
|
prevDayNextMonth1900 = UTCTime (fromGregorian 2023 7 6) (secondsToDiffTime $ 18 * 3600) -- 19:00 in tz
|
||||||
|
sameDayNextYear1900 = UTCTime (fromGregorian 2024 6 7) (secondsToDiffTime $ 18 * 3600) -- 19:00 in tz
|
||||||
|
prevDayNextYear1900 = UTCTime (fromGregorian 2024 6 6) (secondsToDiffTime $ 18 * 3600) -- 19:00 in tz
|
||||||
|
test tz now1159 today0000 True
|
||||||
|
test tz now1159 today0600 True
|
||||||
|
test tz now1159 today1200 True
|
||||||
|
test tz now1159 today1800 True
|
||||||
|
test tz now1159 today2359 True
|
||||||
|
test tz now1159 yesterday0000 False
|
||||||
|
test tz now1159 yesterday1759 False
|
||||||
|
test tz now1159 yesterday1800 True
|
||||||
|
test tz now1159 yesterday2359 True
|
||||||
|
test tz now1159 sameDayLastMonth1900 False
|
||||||
|
test tz now1159 prevDayLastMonth1900 False
|
||||||
|
test tz now1159 sameDayLastYear1900 False
|
||||||
|
test tz now1159 prevDayLastYear1900 False
|
||||||
|
test tz now1159 tomorrow0000 False
|
||||||
|
test tz now1159 tomorrow1759 False
|
||||||
|
test tz now1159 tomorrow1800 False
|
||||||
|
test tz now1159 tomorrow2359 False
|
||||||
|
test tz now1159 sameDayNextMonth1900 False
|
||||||
|
test tz now1159 prevDayNextMonth1900 False
|
||||||
|
test tz now1159 sameDayNextYear1900 False
|
||||||
|
test tz now1159 prevDayNextYear1900 False
|
||||||
|
|
||||||
|
test tz now1200 today0000 True
|
||||||
|
test tz now1200 today0600 True
|
||||||
|
test tz now1200 today1200 True
|
||||||
|
test tz now1200 today1800 True
|
||||||
|
test tz now1200 today2359 True
|
||||||
|
test tz now1200 yesterday0000 False
|
||||||
|
test tz now1200 yesterday1759 False
|
||||||
|
test tz now1200 yesterday1800 False
|
||||||
|
test tz now1200 yesterday2359 False
|
||||||
|
test tz now1200 sameDayLastMonth1900 False
|
||||||
|
test tz now1200 prevDayLastMonth1900 False
|
||||||
|
test tz now1200 sameDayLastYear1900 False
|
||||||
|
test tz now1200 prevDayLastYear1900 False
|
||||||
|
test tz now1200 tomorrow0000 False
|
||||||
|
test tz now1200 tomorrow1759 False
|
||||||
|
test tz now1200 tomorrow1800 False
|
||||||
|
test tz now1200 tomorrow2359 False
|
||||||
|
test tz now1200 sameDayNextMonth1900 False
|
||||||
|
test tz now1200 prevDayNextMonth1900 False
|
||||||
|
test tz now1200 sameDayNextYear1900 False
|
||||||
|
test tz now1200 prevDayNextYear1900 False
|
||||||
|
where
|
||||||
|
test tz now time expected =
|
||||||
|
it ("returns " <> show expected <> " for time " <> show time <> " when time zone is " <> show tz <> " and current time is " <> show now) $
|
||||||
|
recent now tz time `shouldBe` expected
|
Loading…
Add table
Add a link
Reference in a new issue