diff --git a/app/containers/MessageActions/index.tsx b/app/containers/MessageActions/index.tsx index 90a516ce0c0..446f9d10545 100644 --- a/app/containers/MessageActions/index.tsx +++ b/app/containers/MessageActions/index.tsx @@ -2,8 +2,8 @@ import React, { forwardRef, useImperativeHandle } from 'react'; import { Alert, Share } from 'react-native'; import Clipboard from '@react-native-clipboard/clipboard'; import { connect } from 'react-redux'; -import moment from 'moment'; +import dayjs from '../../lib/dayjs'; import database from '../../lib/database'; import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription'; import I18n from '../../i18n'; @@ -154,11 +154,11 @@ const MessageActions = React.memo( if (blockEditInMinutes) { let msgTs; if (message.ts != null) { - msgTs = moment(message.ts); + msgTs = dayjs(message.ts); } let currentTsDiff = 0; if (msgTs != null) { - currentTsDiff = moment().diff(msgTs, 'minutes'); + currentTsDiff = dayjs().diff(msgTs, 'minutes'); } return currentTsDiff < blockEditInMinutes; } @@ -185,11 +185,11 @@ const MessageActions = React.memo( if (blockDeleteInMinutes != null && blockDeleteInMinutes !== 0) { let msgTs; if (message.ts != null) { - msgTs = moment(message.ts); + msgTs = dayjs(message.ts); } let currentTsDiff = 0; if (msgTs != null) { - currentTsDiff = moment().diff(msgTs, 'minutes'); + currentTsDiff = dayjs().diff(msgTs, 'minutes'); } return currentTsDiff < blockDeleteInMinutes; } diff --git a/app/containers/MessageComposer/components/Quotes/Quote.tsx b/app/containers/MessageComposer/components/Quotes/Quote.tsx index 80782dee217..c5436f19938 100644 --- a/app/containers/MessageComposer/components/Quotes/Quote.tsx +++ b/app/containers/MessageComposer/components/Quotes/Quote.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { View, Text } from 'react-native'; -import moment from 'moment'; +import dayjs from '../../../../lib/dayjs'; import { useTheme } from '../../../../theme'; import sharedStyles from '../../../../views/Styles'; import { useRoomContext } from '../../../../views/RoomView/context'; @@ -25,7 +25,7 @@ export const Quote = ({ messageId }: { messageId: string }) => { if (message) { username = useRealName ? message.u?.name || message.u?.username || '' : message.u?.username || ''; msg = message.msg || ''; - time = message.ts ? moment(message.ts).format('LT') : ''; + time = message.ts ? dayjs(message.ts).format('LT') : ''; } if (!message) { diff --git a/app/containers/MessageSeparator.tsx b/app/containers/MessageSeparator.tsx index ecc768f0357..6ba013755ae 100644 --- a/app/containers/MessageSeparator.tsx +++ b/app/containers/MessageSeparator.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; -import moment from 'moment'; +import dayjs from '../lib/dayjs'; import I18n from '../i18n'; import sharedStyles from '../views/Styles'; import { themes } from '../lib/constants/colors'; @@ -36,7 +36,7 @@ const MessageSeparator = ({ ts, unread }: { ts?: Date | string | null; unread?: return null; } - const date = ts ? moment(ts).format('LL') : null; + const date = ts ? dayjs(ts).format('LL') : null; const unreadLine = { backgroundColor: themes[theme].buttonBackgroundDangerDefault }; const unreadText = { color: themes[theme].fontDanger }; if (ts && unread) { diff --git a/app/containers/Passcode/utils.ts b/app/containers/Passcode/utils.ts index bec7bcf7519..8a07b6dbbb4 100644 --- a/app/containers/Passcode/utils.ts +++ b/app/containers/Passcode/utils.ts @@ -1,12 +1,12 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; -import moment from 'moment'; +import dayjs from '../../lib/dayjs'; import { LOCKED_OUT_TIMER_KEY, TIME_TO_LOCK } from '../../lib/constants/localAuthentication'; export const getLockedUntil = async () => { const t = await AsyncStorage.getItem(LOCKED_OUT_TIMER_KEY); if (t) { - return moment(t).add(TIME_TO_LOCK).toDate(); + return dayjs(t).add(TIME_TO_LOCK, 'millisecond').toDate(); } return null; }; diff --git a/app/containers/SupportedVersions/useSupportedVersionMessage.ts b/app/containers/SupportedVersions/useSupportedVersionMessage.ts index d4b31d10854..85f9965b2d7 100644 --- a/app/containers/SupportedVersions/useSupportedVersionMessage.ts +++ b/app/containers/SupportedVersions/useSupportedVersionMessage.ts @@ -1,5 +1,4 @@ -import moment from 'moment'; - +import dayjs from '../../lib/dayjs'; import { useAppSelector } from '../../lib/hooks/useAppSelector'; const applyParams = (message: string, params: Record) => { @@ -25,7 +24,7 @@ export const useSupportedVersionMessage = () => { instance_email: email, instance_ws_name: name, instance_domain: server, - remaining_days: moment(expiration).diff(new Date(), 'days'), + remaining_days: dayjs(expiration).diff(new Date(), 'days'), instance_version: version, ...message?.params }; diff --git a/app/containers/UIKit/DatePicker.tsx b/app/containers/UIKit/DatePicker.tsx index df7eef95b2b..bc1e05fbb60 100644 --- a/app/containers/UIKit/DatePicker.tsx +++ b/app/containers/UIKit/DatePicker.tsx @@ -3,8 +3,8 @@ import { StyleSheet, Text, unstable_batchedUpdates, View } from 'react-native'; import DateTimePicker, { type BaseProps } from '@react-native-community/datetimepicker'; import Touchable from 'react-native-platform-touchable'; import { BlockContext } from '@rocket.chat/ui-kit'; -import moment from 'moment'; +import dayjs from '../../lib/dayjs'; import Button from '../Button'; import { textParser } from './utils'; import { themes } from '../../lib/constants/colors'; @@ -54,7 +54,7 @@ export const DatePicker = ({ element, language, action, context, loading, value, onShow(false); } }); - action({ value: moment(newDate).format('YYYY-MM-DD') }); + action({ value: dayjs(newDate).format('YYYY-MM-DD') }); } }; diff --git a/app/containers/message/Components/Attachments/Reply.tsx b/app/containers/message/Components/Attachments/Reply.tsx index faa796f9634..eec13fe43c0 100644 --- a/app/containers/message/Components/Attachments/Reply.tsx +++ b/app/containers/message/Components/Attachments/Reply.tsx @@ -1,5 +1,4 @@ import { dequal } from 'dequal'; -import moment from 'moment'; import React, { useContext, useState } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { Image } from 'expo-image'; @@ -17,6 +16,7 @@ import { Attachments } from './components'; import MessageContext from '../../Context'; import Touchable from '../../Touchable'; import messageStyles from '../../styles'; +import dayjs from '../../../../lib/dayjs'; const styles = StyleSheet.create({ button: { @@ -103,7 +103,7 @@ const Title = React.memo( ({ attachment, timeFormat, theme }: { attachment: IAttachment; timeFormat?: string; theme: TSupportedThemes }) => { 'use memo'; - const time = attachment.message_link && attachment.ts ? moment(attachment.ts).format(timeFormat) : null; + const time = attachment.message_link && attachment.ts ? dayjs(attachment.ts).format(timeFormat) : null; return ( {attachment.author_name ? ( diff --git a/app/containers/message/Time.tsx b/app/containers/message/Time.tsx index efeb4ac5063..78ae7ab80f5 100644 --- a/app/containers/message/Time.tsx +++ b/app/containers/message/Time.tsx @@ -1,7 +1,7 @@ -import moment from 'moment'; import React from 'react'; import { Text } from 'react-native'; +import dayjs from '../../lib/dayjs'; import { useTheme } from '../../theme'; import messageStyles from './styles'; @@ -15,7 +15,7 @@ const MessageTime = ({ timeFormat, ts }: IMessageTime) => { const { colors } = useTheme(); - const time = moment(ts).format(timeFormat); + const time = dayjs(ts).format(timeFormat); return {time}; }; diff --git a/app/i18n/moment.ts b/app/i18n/dayjs.ts similarity index 69% rename from app/i18n/moment.ts rename to app/i18n/dayjs.ts index 88254b755df..32879525694 100644 --- a/app/i18n/moment.ts +++ b/app/i18n/dayjs.ts @@ -15,7 +15,8 @@ const localeKeys: { [key: string]: string } = { sv: 'sv', tr: 'tr', 'zh-CN': 'zh-cn', - 'zh-TW': 'zh-tw' + 'zh-TW': 'zh-tw', + no: 'nb' }; -export const toMomentLocale = (locale: string): string => localeKeys[locale]; +export const toDayJsLocale = (locale: string): string => localeKeys[locale] || locale; diff --git a/app/i18n/index.ts b/app/i18n/index.ts index 0124dffa5ce..91189b48d42 100644 --- a/app/i18n/index.ts +++ b/app/i18n/index.ts @@ -1,10 +1,9 @@ import i18n from 'i18n-js'; import { I18nManager } from 'react-native'; import * as RNLocalize from 'react-native-localize'; -import moment from 'moment'; -import 'moment/min/locales'; -import { toMomentLocale } from './moment'; +import dayjs from '../lib/dayjs/index'; +import { toDayJsLocale } from './dayjs'; import { isRTL } from './isRTL'; import englishJson from './locales/en.json'; @@ -177,7 +176,7 @@ export const setLanguage = (l: string) => { // TODO: Review this logic // @ts-ignore i18n.isRTL = I18nManager.isRTL; - moment.locale(toMomentLocale(locale)); + dayjs.locale(toDayJsLocale(locale)); }; i18n.translations = { en: translations.en?.() }; diff --git a/app/lib/dayjs/index.ts b/app/lib/dayjs/index.ts new file mode 100644 index 00000000000..f492c042909 --- /dev/null +++ b/app/lib/dayjs/index.ts @@ -0,0 +1,40 @@ +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import timezone from 'dayjs/plugin/timezone'; +import calendar from 'dayjs/plugin/calendar'; +import relativeTime from 'dayjs/plugin/relativeTime'; +import localizedFormat from 'dayjs/plugin/localizedFormat'; + +import 'dayjs/locale/en'; +import 'dayjs/locale/ar'; +import 'dayjs/locale/bn'; +import 'dayjs/locale/cs'; +import 'dayjs/locale/de'; +import 'dayjs/locale/es'; +import 'dayjs/locale/fi'; +import 'dayjs/locale/fr'; +import 'dayjs/locale/hi'; +import 'dayjs/locale/hu'; +import 'dayjs/locale/it'; +import 'dayjs/locale/ja'; +import 'dayjs/locale/nl'; +import 'dayjs/locale/nb'; +import 'dayjs/locale/nn'; +import 'dayjs/locale/pt-br'; +import 'dayjs/locale/pt'; +import 'dayjs/locale/ru'; +import 'dayjs/locale/sl'; +import 'dayjs/locale/sv'; +import 'dayjs/locale/ta'; +import 'dayjs/locale/te'; +import 'dayjs/locale/tr'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/zh-tw'; + +dayjs.extend(utc); +dayjs.extend(timezone); +dayjs.extend(calendar); +dayjs.extend(relativeTime); +dayjs.extend(localizedFormat); + +export default dayjs; diff --git a/app/lib/methods/AudioManager.ts b/app/lib/methods/AudioManager.ts index 9ee29e99889..ee4b9bec978 100644 --- a/app/lib/methods/AudioManager.ts +++ b/app/lib/methods/AudioManager.ts @@ -1,7 +1,7 @@ import { type AVPlaybackStatus, Audio } from 'expo-av'; import { Q } from '@nozbe/watermelondb'; -import moment from 'moment'; +import dayjs from '../dayjs'; import { getMessageById } from '../database/services/Message'; import database from '../database'; import { getFilePathAudio } from './getFilePathAudio'; @@ -120,7 +120,7 @@ class AudioManagerClass { const msg = await getMessageById(msgId); if (msg) { const db = database.active; - const whereClause: Q.Clause[] = [Q.sortBy('ts', Q.asc), Q.where('ts', Q.gt(moment(msg.ts).valueOf())), Q.take(1)]; + const whereClause: Q.Clause[] = [Q.sortBy('ts', Q.asc), Q.where('ts', Q.gt(dayjs(msg.ts).valueOf())), Q.take(1)]; if (msg.tmid) { whereClause.push(Q.where('tmid', msg.tmid || msg.id)); diff --git a/app/lib/methods/checkSupportedVersions.ts b/app/lib/methods/checkSupportedVersions.ts index 10e8ddf37af..8f98b1dc950 100644 --- a/app/lib/methods/checkSupportedVersions.ts +++ b/app/lib/methods/checkSupportedVersions.ts @@ -1,7 +1,7 @@ -import moment from 'moment'; import coerce from 'semver/functions/coerce'; import satisfies from 'semver/functions/satisfies'; +import dayjs from '../dayjs'; import { type ISupportedVersionsData, type TSVDictionary, type TSVMessage, type TSVStatus } from '../../definitions'; import builtInSupportedVersions from '../../../app-supportedversions.json'; @@ -12,11 +12,11 @@ export const getMessage = ({ messages?: TSVMessage[]; expiration?: string; }): TSVMessage | undefined => { - if (!messages?.length || !expiration || moment(expiration).diff(new Date(), 'days') < 0) { + if (!messages?.length || !expiration || dayjs(expiration).diff(new Date(), 'days') < 0) { return; } const sortedMessages = messages.sort((a, b) => a.remainingDays - b.remainingDays); - return sortedMessages.find(({ remainingDays }) => moment(expiration).diff(new Date(), 'hours') <= remainingDays * 24); + return sortedMessages.find(({ remainingDays }) => dayjs(expiration).diff(new Date(), 'hours') <= remainingDays * 24); }; const getStatus = ({ expiration, message }: { expiration?: string; message?: TSVMessage }): TSVStatus => { diff --git a/app/lib/methods/getServerInfo.ts b/app/lib/methods/getServerInfo.ts index b930e383d32..aaf347d0ef1 100644 --- a/app/lib/methods/getServerInfo.ts +++ b/app/lib/methods/getServerInfo.ts @@ -1,6 +1,6 @@ import { KJUR } from 'jsrsasign'; -import moment from 'moment'; +import dayjs from '../dayjs'; import { getSupportedVersionsCloud } from '../services/restApi'; import { type TCloudInfo, @@ -81,7 +81,7 @@ export async function getServerInfo(server: string): Promise const serverRecord = await getServerById(server); if ( serverRecord?.supportedVersionsUpdatedAt && - moment(new Date()).diff(serverRecord?.supportedVersionsUpdatedAt, 'hours') <= SV_CLOUD_UPDATE_INTERVAL + dayjs(new Date()).diff(serverRecord?.supportedVersionsUpdatedAt, 'hours') <= SV_CLOUD_UPDATE_INTERVAL ) { return { ...serverInfo, diff --git a/app/lib/methods/helpers/localAuthentication.ts b/app/lib/methods/helpers/localAuthentication.ts index 7059983cf02..8dd1b005f55 100644 --- a/app/lib/methods/helpers/localAuthentication.ts +++ b/app/lib/methods/helpers/localAuthentication.ts @@ -2,8 +2,8 @@ import * as LocalAuthentication from 'expo-local-authentication'; import RNBootSplash from 'react-native-bootsplash'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { sha256 } from 'js-sha256'; -import moment from 'moment'; +import dayjs from '../../dayjs'; import UserPreferences from '../userPreferences'; import { store } from '../../store/auxStore'; import database from '../../database'; @@ -146,7 +146,7 @@ export const localAuthenticate = async (server: string): Promise => { // `checkHasPasscode` results newPasscode = true if a passcode has been set if (!result?.newPasscode) { // diff to last authenticated session - const diffToLastSession = moment(timesync).diff(serverRecord?.lastLocalAuthenticatedSession, 'seconds'); + const diffToLastSession = dayjs(timesync).diff(serverRecord?.lastLocalAuthenticatedSession, 'seconds'); // if it was not possible to get `timesync` from server or the last authenticated session is older than the configured auto lock time, authentication is required if (!timesync || (serverRecord?.autoLockTime && diffToLastSession >= serverRecord.autoLockTime)) { diff --git a/app/lib/methods/helpers/normalizeMessage.ts b/app/lib/methods/helpers/normalizeMessage.ts index 186a7e188dd..e5bf66d0e10 100644 --- a/app/lib/methods/helpers/normalizeMessage.ts +++ b/app/lib/methods/helpers/normalizeMessage.ts @@ -1,5 +1,4 @@ -import moment from 'moment'; - +import dayjs from '../../dayjs'; import parseUrls from './parseUrls'; import type { IAttachment, IMessage, IThreadResult } from '../../../definitions'; @@ -15,7 +14,7 @@ function normalizeAttachments(msg: TMsg) { .map(att => { att.fields = att.fields || []; if (att.ts) { - att.ts = moment(att.ts).toDate(); + att.ts = dayjs(att.ts).toDate(); } att = normalizeAttachments(att as TMsg); return att; diff --git a/app/lib/methods/helpers/room.ts b/app/lib/methods/helpers/room.ts index c4d6d43896a..9f270c3c4e4 100644 --- a/app/lib/methods/helpers/room.ts +++ b/app/lib/methods/helpers/room.ts @@ -1,5 +1,4 @@ -import moment from 'moment'; - +import dayjs from '../../dayjs'; import { themes } from '../../constants/colors'; import I18n from '../../../i18n'; import { type IAttachment, SubscriptionType, type TSubscriptionModel } from '../../../definitions'; @@ -23,7 +22,7 @@ export const capitalize = (s: string): string => { }; export const formatDateAccessibility = (date: string | Date): string => - moment(date).calendar(null, { + dayjs(date).calendar(null, { lastDay: `[${I18n.t('Last_updated')}] [${I18n.t('Yesterday')}]`, sameDay: `[${I18n.t('Last_updated_at')}] LT`, lastWeek: `[${I18n.t('Last_updated_on')}] dddd`, @@ -31,7 +30,7 @@ export const formatDateAccessibility = (date: string | Date): string => }); export const formatDate = (date: string | Date): string => - moment(date).calendar(null, { + dayjs(date).calendar(null, { lastDay: `[${I18n.t('Yesterday')}]`, sameDay: 'LT', lastWeek: 'dddd', @@ -39,7 +38,7 @@ export const formatDate = (date: string | Date): string => }); export const formatDateThreads = (date: string | Date): string => - moment(date).calendar(null, { + dayjs(date).calendar(null, { sameDay: 'LT', lastDay: `[${I18n.t('Yesterday')}] LT`, lastWeek: 'dddd LT', diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index 501ed034f26..747b8b2aad2 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -1,5 +1,4 @@ -import moment from 'moment'; - +import dayjs from '../dayjs'; import { MessageTypeLoad } from '../constants/messageTypeLoad'; import { type IMessage, type TMessageModel } from '../../definitions'; import log from './helpers/log'; @@ -82,7 +81,7 @@ export function loadMessagesForRoom(args: { const loadMoreMessage = { _id: generateLoadMoreId(lastMessage._id as string), rid: lastMessage.rid, - ts: moment(lastMessage.ts).subtract(1, 'millisecond').toString(), + ts: dayjs(lastMessage.ts).subtract(1, 'millisecond').toString(), t: MessageTypeLoad.MORE, msg: lastMessage.msg } as IMessage; diff --git a/app/lib/methods/loadNextMessages.ts b/app/lib/methods/loadNextMessages.ts index 47c72c7b43b..3d410e2db1b 100644 --- a/app/lib/methods/loadNextMessages.ts +++ b/app/lib/methods/loadNextMessages.ts @@ -1,7 +1,7 @@ import EJSON from 'ejson'; -import moment from 'moment'; import orderBy from 'lodash/orderBy'; +import dayjs from '../dayjs'; import log from './helpers/log'; import { getMessageById } from '../database/services/Message'; import { MessageTypeLoad } from '../constants/messageTypeLoad'; @@ -31,7 +31,7 @@ export function loadNextMessages(args: ILoadNextMessages): Promise { const loadMoreItem = { _id: generateLoadMoreId(lastMessage._id), rid: lastMessage.rid, - ts: moment(lastMessage.ts).add(1, 'millisecond'), + ts: dayjs(lastMessage.ts).add(1, 'millisecond'), t: MessageTypeLoad.NEXT_CHUNK }; messages.push(loadMoreItem); diff --git a/app/lib/methods/loadSurroundingMessages.ts b/app/lib/methods/loadSurroundingMessages.ts index 7958f761ab1..ecb5b3c7e0f 100644 --- a/app/lib/methods/loadSurroundingMessages.ts +++ b/app/lib/methods/loadSurroundingMessages.ts @@ -1,7 +1,7 @@ import EJSON from 'ejson'; -import moment from 'moment'; import orderBy from 'lodash/orderBy'; +import dayjs from '../dayjs'; import log from './helpers/log'; import { getMessageById } from '../database/services/Message'; import { MessageTypeLoad } from '../constants/messageTypeLoad'; @@ -27,7 +27,7 @@ export function loadSurroundingMessages({ messageId, rid }: { messageId: string; const loadMoreItem = { _id: generateLoadMoreId(firstMessage._id), rid: firstMessage.rid, - ts: moment(firstMessage.ts).subtract(1, 'millisecond').toDate(), + ts: dayjs(firstMessage.ts).subtract(1, 'millisecond').toDate(), t: MessageTypeLoad.PREVIOUS_CHUNK, msg: firstMessage.msg } as IMessage; @@ -42,7 +42,7 @@ export function loadSurroundingMessages({ messageId, rid }: { messageId: string; const loadMoreItem = { _id: generateLoadMoreId(lastMessage._id), rid: lastMessage.rid, - ts: moment(lastMessage.ts).add(1, 'millisecond').toDate(), + ts: dayjs(lastMessage.ts).add(1, 'millisecond').toDate(), t: MessageTypeLoad.NEXT_CHUNK, msg: lastMessage.msg } as IMessage; diff --git a/app/sagas/login.js b/app/sagas/login.js index d3e37b0e2fa..aa81e5d964c 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -4,7 +4,7 @@ import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord'; import { Q } from '@nozbe/watermelondb'; import * as Keychain from 'react-native-keychain'; -import moment from 'moment'; +import dayjs from '../lib/dayjs'; import * as types from '../actions/actionsTypes'; import { appStart } from '../actions/app'; import { selectServerRequest, serverFinishAdd } from '../actions/server'; @@ -55,7 +55,7 @@ const showSupportedVersionsWarning = function* showSupportedVersionsWarning(serv } const serverRecord = yield getServerById(server); const isMasterDetail = yield select(state => state.app.isMasterDetail); - if (!serverRecord || moment(new Date()).diff(serverRecord?.supportedVersionsWarningAt, 'hours') <= 12) { + if (!serverRecord || dayjs(new Date()).diff(serverRecord?.supportedVersionsWarningAt, 'hours') <= 12) { return; } diff --git a/app/views/DiscussionsView/Item.tsx b/app/views/DiscussionsView/Item.tsx index 2a711096ea7..143b4da6841 100644 --- a/app/views/DiscussionsView/Item.tsx +++ b/app/views/DiscussionsView/Item.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; import Touchable from 'react-native-platform-touchable'; -import moment from 'moment'; +import dayjs from '../../lib/dayjs'; import { useTheme } from '../../theme'; import Avatar from '../../containers/Avatar'; import sharedStyles from '../Styles'; @@ -58,7 +58,7 @@ const Item = ({ item, onPress }: IItem): React.ReactElement => { let messageDate = ''; if (item?.ts) { - messageTime = moment(item.ts).format('LT'); + messageTime = dayjs(item.ts).format('LT'); messageDate = formatDateThreads(item.ts); } diff --git a/app/views/InviteUsersView/index.tsx b/app/views/InviteUsersView/index.tsx index c537fa5eae2..95aa027fb5b 100644 --- a/app/views/InviteUsersView/index.tsx +++ b/app/views/InviteUsersView/index.tsx @@ -1,8 +1,8 @@ import React, { useEffect } from 'react'; -import moment from 'moment'; import { ScrollView, Share, View } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; +import dayjs from '../../lib/dayjs'; import { inviteLinksClear, inviteLinksCreate } from '../../actions/inviteLinks'; import Button from '../../containers/Button'; import Markdown from '../../containers/markdown'; @@ -62,12 +62,12 @@ const InviteUsersView = ({ route, navigation }: IInviteUsersViewProps): React.Re if (invite.maxUses) { const usesLeft = invite.maxUses - invite.uses; return I18n.t('Your_invite_link_will_expire_on__date__or_after__usesLeft__uses', { - date: moment(expiration).format(timeDateFormat), + date: dayjs(expiration).format(timeDateFormat), usesLeft }); } - return I18n.t('Your_invite_link_will_expire_on__date__', { date: moment(expiration).format(timeDateFormat) }); + return I18n.t('Your_invite_link_will_expire_on__date__', { date: dayjs(expiration).format(timeDateFormat) }); } if (invite.maxUses) { diff --git a/app/views/ReadReceiptView/index.tsx b/app/views/ReadReceiptView/index.tsx index 9573eed00b7..6df57998f3c 100644 --- a/app/views/ReadReceiptView/index.tsx +++ b/app/views/ReadReceiptView/index.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { FlatList, Text, View, RefreshControl } from 'react-native'; import { dequal } from 'dequal'; -import moment from 'moment'; import { connect } from 'react-redux'; import { type NativeStackNavigationOptions, type NativeStackNavigationProp } from '@react-navigation/native-stack'; import { type RouteProp } from '@react-navigation/core'; +import dayjs from '../../lib/dayjs'; import * as List from '../../containers/List'; import Avatar from '../../containers/Avatar'; import * as HeaderButton from '../../containers/Header/components/HeaderButton'; @@ -112,7 +112,7 @@ class ReadReceiptView extends React.Component { const { theme, Message_TimeAndDateFormat } = this.props; - const time = moment(item.ts).format(Message_TimeAndDateFormat); + const time = dayjs(item.ts).format(Message_TimeAndDateFormat); if (!item?.user?.username) { return null; } diff --git a/app/views/RoomInfoView/Timezone.tsx b/app/views/RoomInfoView/Timezone.tsx index 73a9af64ad1..ea2d34996a0 100644 --- a/app/views/RoomInfoView/Timezone.tsx +++ b/app/views/RoomInfoView/Timezone.tsx @@ -1,6 +1,6 @@ -import moment from 'moment'; import React from 'react'; +import dayjs from '../../lib/dayjs'; import I18n from '../../i18n'; import { useAppSelector } from '../../lib/hooks/useAppSelector'; import Item from './Item'; @@ -11,7 +11,7 @@ const Timezone = ({ utcOffset }: { utcOffset?: number }): React.ReactElement | n if (!utcOffset) return null; return ( - + ); }; diff --git a/app/views/RoomView/index.tsx b/app/views/RoomView/index.tsx index eb152d970fe..041628ce5de 100644 --- a/app/views/RoomView/index.tsx +++ b/app/views/RoomView/index.tsx @@ -2,13 +2,13 @@ import React from 'react'; import { AccessibilityInfo, InteractionManager, PixelRatio, Text, View } from 'react-native'; import { connect } from 'react-redux'; import parse from 'url-parse'; -import moment from 'moment'; import { Q } from '@nozbe/watermelondb'; import { dequal } from 'dequal'; import { withSafeAreaInsets } from 'react-native-safe-area-context'; import { type Subscription } from 'rxjs'; import * as Haptics from 'expo-haptics'; +import dayjs from '../../lib/dayjs'; import { getRoutingConfig, getUserInfo, @@ -1353,11 +1353,14 @@ class RoomView extends React.Component { if (!previousItem) { dateSeparator = item.ts; - showUnreadSeparator = moment(item.ts).isAfter(lastOpen); + showUnreadSeparator = lastOpen ? dayjs(item.ts).isAfter(lastOpen) : false; } else { showUnreadSeparator = - (lastOpen && moment(item.ts).isSameOrAfter(lastOpen) && moment(previousItem.ts).isBefore(lastOpen)) ?? false; - if (!moment(item.ts).isSame(previousItem.ts, 'day')) { + (lastOpen && + (dayjs(item.ts).isSame(lastOpen) || dayjs(item.ts).isAfter(lastOpen)) && + dayjs(previousItem.ts).isBefore(lastOpen)) ?? + false; + if (!dayjs(item.ts).isSame(previousItem.ts, 'day')) { dateSeparator = item.ts; } } diff --git a/package.json b/package.json index 77b14a6eeed..801ec1bb024 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "@rocket.chat/ui-kit": "0.31.19", "bytebuffer": "5.0.1", "color2k": "1.2.4", + "dayjs": "^1.11.18", "dequal": "2.0.3", "ejson": "2.2.3", "eslint-import-resolver-typescript": "^4.4.4", @@ -81,7 +82,6 @@ "lint-staged": "11.1.0", "lodash": "4.17.21", "mitt": "3.0.1", - "moment": "2.29.4", "pretty-bytes": "5.6.0", "prop-types": "15.7.2", "react": "19.0.0", diff --git a/yarn.lock b/yarn.lock index 32ba7026430..de6b9c19a39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7256,6 +7256,11 @@ data-view-byte-offset@^1.0.0: es-errors "^1.3.0" is-data-view "^1.0.1" +dayjs@^1.11.18: + version "1.11.18" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.18.tgz#835fa712aac52ab9dec8b1494098774ed7070a11" + integrity sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA== + dayjs@^1.8.15: version "1.11.10" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" @@ -11455,11 +11460,6 @@ mkdirp@^3.0.1: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== -moment@2.29.4: - version "2.29.4" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" - integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== - moment@2.x.x: version "2.30.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"