diff --git a/apps/web/public/locales/en.json b/apps/web/public/locales/en.json index 7b77c42d5..e32c7e479 100644 --- a/apps/web/public/locales/en.json +++ b/apps/web/public/locales/en.json @@ -292,6 +292,7 @@ "Edit Menu": "Edit Menu", "Edit Profile": "Edit Profile", "Edit welcome message": "Edit welcome message", + "Edited": "Edited", "Editing Group Menu": "Editing Group Menu", "Email": "Email", "Email address is not in a valid format": "Email address is not in a valid format", @@ -655,6 +656,7 @@ "Post from": "Post from", "Post from child group": "Post from child group", "Post in": "Post in", + "Posted": "Posted", "Posted In:": "Posted In:", "Posting...": "Posting...", "Posts": "Posts", @@ -1116,6 +1118,7 @@ "new comments on posts you're following?": "new comments on posts you're following?", "new markets": "new markets", "no more than {{maxTags}} allowed": "no more than {{maxTags}} allowed", + "now": "now", "nutrient density": "nutrient density", "of": "of", "offer": "Offer", diff --git a/apps/web/public/locales/es.json b/apps/web/public/locales/es.json index 64aa4f4c7..872e1a262 100644 --- a/apps/web/public/locales/es.json +++ b/apps/web/public/locales/es.json @@ -291,6 +291,7 @@ "Edit Menu": "Editar menú", "Edit Profile": "Editar perfil", "Edit welcome message": "Editar mensaje de bienvenida", + "Edited": "Editado", "Editing Group Menu": "Menú del grupo de edición", "Email": "Correo electrónico", "Email address is not in a valid format": "La dirección de correo electrónico no tiene un formato válido", @@ -661,6 +662,7 @@ "Post from": "Publicacion de", "Post from child group": "Publicacion de subgrupo", "Post in": "Publica en", + "Posted": "Publicado", "Posted In:": "Publicado en:", "Posting...": "Publicando...", "Posts": "Publicaciones", @@ -822,7 +824,7 @@ "Start typing to add a topic": "Comienza a escribir para agregar un tema", "Start typing to find/create a topic to add": "Comience a escribir para encontrar/crear un tema para agregar", "Started: {{from}}": "Empezó desde: {{from}}", - "Starts: {{from}}": "Comienza: {{desde}}", + "Starts: {{from}}": "Comienza desde: {{from}}", "Stay connected, organized, and engaged with your group.": "Manténte conectado, organizado y comprometido con tu grupo.", "Stream": "Flujo", "Subgroups": "Subgrupos", @@ -1116,6 +1118,7 @@ "new comments on posts you're following?": "¿nuevos comentarios en las publicaciones que estás siguiendo?", "new markets": "nuevos mercados", "no more than {{maxTags}} allowed": "no más de {{maxTags}} permitido", + "now": "ahora", "nutrient density": "densidad de nutrientes", "of": "de", "offer": "Oferta", diff --git a/apps/web/src/components/PostBigGridItem/PostBigGridItem.js b/apps/web/src/components/PostBigGridItem/PostBigGridItem.js index 6311fa542..42aaf5974 100644 --- a/apps/web/src/components/PostBigGridItem/PostBigGridItem.js +++ b/apps/web/src/components/PostBigGridItem/PostBigGridItem.js @@ -24,10 +24,12 @@ export default function PostBigGridItem ({ expanded }) { const { + id, title, details, creator, - createdTimestamp, + createdTimestampForBigGrd, + exactCreatedTimestamp, attachments } = post const { t } = useTranslation() @@ -156,8 +158,8 @@ export default function PostBigGridItem ({ {creator.name} -
- {createdTimestamp} +
+ {createdTimestampForBigGrd}
@@ -171,6 +173,11 @@ export default function PostBigGridItem ({ + ) } diff --git a/apps/web/src/components/PostCard/ChatCard/ChatCard.js b/apps/web/src/components/PostCard/ChatCard/ChatCard.js index cd9bcef2f..c1a10b347 100644 --- a/apps/web/src/components/PostCard/ChatCard/ChatCard.js +++ b/apps/web/src/components/PostCard/ChatCard/ChatCard.js @@ -9,6 +9,7 @@ import HyloHTML from 'components/HyloHTML' import RoundImage from 'components/RoundImage' import classes from './ChatCard.module.scss' +import { getLocaleAsString } from 'components/Calendar/calendar-util' export default function ChatCard ({ expanded, @@ -32,7 +33,7 @@ export default function ChatCard ({ {!slug && in  {firstGroup}} - {DateTime.fromISO(post.createdAt).toFormat('yyyy t')} + {DateTime.fromISO(post.createdAt).setLocale(getLocaleAsString()).toFormat('yyyy t')} diff --git a/apps/web/src/components/PostCard/EventDate/EventDate.js b/apps/web/src/components/PostCard/EventDate/EventDate.js index 115d44606..48872282c 100644 --- a/apps/web/src/components/PostCard/EventDate/EventDate.js +++ b/apps/web/src/components/PostCard/EventDate/EventDate.js @@ -1,10 +1,11 @@ import React from 'react' import { DateTime } from 'luxon' import classes from './EventDate.module.scss' +import { getLocaleAsString } from 'components/Calendar/calendar-util' export default function EventDate ({ startTime }) { if (!startTime) return null - const start = DateTime.fromISO(startTime) + const start = DateTime.fromISO(startTime).setLocale(getLocaleAsString()) return (
{start.toFormat('MMM')} diff --git a/apps/web/src/components/PostGridItem/PostGridItem.js b/apps/web/src/components/PostGridItem/PostGridItem.js index 1aadc9f4e..8df3ccccc 100644 --- a/apps/web/src/components/PostGridItem/PostGridItem.js +++ b/apps/web/src/components/PostGridItem/PostGridItem.js @@ -18,10 +18,12 @@ export default function PostGridItem ({ expanded }) { const { + id, title, details, creator, createdTimestampForGrid, + exactCreatedTimestamp, attachments } = post @@ -83,13 +85,18 @@ export default function PostGridItem ({ {creator.name}
- + {createdTimestampForGrid}
+ ) } diff --git a/apps/web/src/components/PostListRow/PostListRow.js b/apps/web/src/components/PostListRow/PostListRow.js index ac999e722..079da90a6 100644 --- a/apps/web/src/components/PostListRow/PostListRow.js +++ b/apps/web/src/components/PostListRow/PostListRow.js @@ -15,7 +15,7 @@ import { cn } from 'util/index' import { personUrl, topicUrl } from 'util/navigation' import classes from './PostListRow.module.scss' -import { sameDay } from 'components/Calendar/calendar-util' +import { getLocaleAsString } from 'components/Calendar/calendar-util' // :SHONK: no idea why React propagates events from child elements but NOT IN OTHER COMPONENTS const stopEvent = (e) => e.stopPropagation() @@ -30,10 +30,12 @@ const PostListRow = (props) => { } = props const { + id, title, details, creator, createdTimestamp, + exactCreatedTimestamp, commentersTotal, topics } = post @@ -53,13 +55,13 @@ const PostListRow = (props) => { const creatorUrl = personUrl(creator.id, routeParams.slug) const numOtherCommentors = commentersTotal - 1 const unread = false - const start = typeof post.startTime === 'string' + const start = (typeof post.startTime === 'string' ? DateTime.fromISO(post.startTime) - : DateTime.fromJSDate(post.startTime) - const end = typeof post.endTime === 'string' + : DateTime.fromJSDate(post.startTime)).setLocale(getLocaleAsString()) + const end = (typeof post.endTime === 'string' ? DateTime.fromISO(post.endTime) - : DateTime.fromJSDate(post.endTime) - const isSameDay = sameDay(start.toJSDate(), end.toJSDate()) + : DateTime.fromJSDate(post.endTime)).setLocale(getLocaleAsString()) + const isSameDay = start.hasSame(end, 'day') const isFlagged = post.flaggedGroups && post.flaggedGroups.includes(currentGroupId) return ( @@ -104,7 +106,7 @@ const PostListRow = (props) => { /> )} -
+
{createdTimestamp}
@@ -129,6 +131,11 @@ const PostListRow = (props) => { delay={550} id={`post-tt-${post.id}`} /> + ) } diff --git a/apps/web/src/components/Widget/AnnouncementWidget/AnnouncementWidget.js b/apps/web/src/components/Widget/AnnouncementWidget/AnnouncementWidget.js index 74f0f29b6..23e5b89cf 100644 --- a/apps/web/src/components/Widget/AnnouncementWidget/AnnouncementWidget.js +++ b/apps/web/src/components/Widget/AnnouncementWidget/AnnouncementWidget.js @@ -7,6 +7,7 @@ import { postUrl } from 'util/navigation' import 'slick-carousel/slick/slick.css' import 'slick-carousel/slick/slick-theme.css' import classes from './AnnouncementWidget.module.scss' +import { getLocaleAsString } from 'components/Calendar/calendar-util' const settings = { dots: true, @@ -45,7 +46,7 @@ export default ({ items = [], group, routeParams }) => {
{a.author} - {DateTime.fromJSDate(a.createdAt).toRelative()} + {DateTime.fromJSDate(a.createdAt).setLocale(getLocaleAsString()).toRelative()}
{a.title}
diff --git a/apps/web/src/components/Widget/EventsWidget/EventsWidget.js b/apps/web/src/components/Widget/EventsWidget/EventsWidget.js index 6fc1f3fdb..2581e46ea 100644 --- a/apps/web/src/components/Widget/EventsWidget/EventsWidget.js +++ b/apps/web/src/components/Widget/EventsWidget/EventsWidget.js @@ -10,6 +10,7 @@ import { postUrl, createPostUrl } from 'util/navigation' import 'slick-carousel/slick/slick.css' import 'slick-carousel/slick/slick-theme.css' import classes from './EventsWidget.module.scss' +import { getLocaleAsString } from 'components/Calendar/calendar-util' const settings = { dots: true, @@ -46,7 +47,7 @@ export default ({ items, group, routeParams, isMember }) => {
1 })} key={e.id}>
-
{DateTime.fromJSDate(e.startTime).toFormat('MMM d yyyy')}
+
{DateTime.fromJSDate(e.startTime).setLocale(getLocaleAsString()).toLocaleString(DateTime.DATE_MED)}
{e.title}
{e.location}
diff --git a/apps/web/src/components/Widget/ProjectsWidget/ProjectsWidget.js b/apps/web/src/components/Widget/ProjectsWidget/ProjectsWidget.js index 0d00503f7..6750b416a 100644 --- a/apps/web/src/components/Widget/ProjectsWidget/ProjectsWidget.js +++ b/apps/web/src/components/Widget/ProjectsWidget/ProjectsWidget.js @@ -7,6 +7,7 @@ import { postUrl, createPostUrl } from 'util/navigation' import RoundImage from '../../RoundImage' import classes from './ProjectsWidget.module.scss' +import { getLocaleAsString } from 'components/Calendar/calendar-util' const { array, bool, object } = PropTypes @@ -27,7 +28,7 @@ class ProjectsWidget extends Component {
{p.title}
-
{DateTime.fromJSDate(p.updatedAt).toRelative()}
+
{DateTime.fromJSDate(p.updatedAt).setLocale(getLocaleAsString()).toRelative()}
diff --git a/apps/web/src/components/ui/datetimepicker.jsx b/apps/web/src/components/ui/datetimepicker.jsx index 2dfe48533..ece003f2c 100644 --- a/apps/web/src/components/ui/datetimepicker.jsx +++ b/apps/web/src/components/ui/datetimepicker.jsx @@ -192,10 +192,10 @@ function display12HourValue (hours) { } return `0${hours % 12}` } -function genMonths (locale) { +function genMonths () { return Array.from({ length: 12 }, (_, i) => ({ value: i, - label: DateTime.fromObject({ year: 2021, month: i + 1 }).toFormat('MMMM', { locale }) + label: DateTime.fromObject({ year: 2021, month: i + 1 }).setLocale(getLocaleAsString()).toFormat('MMMM') })) } function genYears (yearRange = 50) { @@ -208,7 +208,7 @@ function genYears (yearRange = 50) { // ---------- utils end ---------- function Calendar ({ className, classNames, showOutsideDays = true, yearRange = 50, ...props }) { const MONTHS = React.useMemo(() => { - return genMonths(getLocaleAsString()) + return genMonths() }, []) const YEARS = React.useMemo(() => genYears(yearRange), []) const disableLeftNavigation = () => { @@ -511,16 +511,13 @@ const DateTimePicker = React.forwardRef(({ locale = getLocaleAsString(), default hour12: displayFormat?.hour12 ?? `D hh:mm${!granularity || granularity === 'second' ? ':ss' : ''} a` } + const dateFormatted = DateTime.fromJSDate(displayDate).setLocale(getLocaleAsString()).toFormat(hourCycle === 24 ? initHourFormat.hour24 : initHourFormat.hour12) return ( diff --git a/apps/web/src/i18n.mjs b/apps/web/src/i18n.mjs index 27a5c8143..4a9b95cf7 100644 --- a/apps/web/src/i18n.mjs +++ b/apps/web/src/i18n.mjs @@ -34,7 +34,8 @@ i18n interpolation: { escapeValue: false // not needed for react as it escapes by default }, - defaultNS: false, + ns: ['en.json', 'es.json'], + defaultNS: 'en.json', preload: ['en', 'es'] }) diff --git a/apps/web/src/routes/ChatRoom/ChatPost/ChatPost.js b/apps/web/src/routes/ChatRoom/ChatPost/ChatPost.js index 007010ae0..4d999b5a0 100644 --- a/apps/web/src/routes/ChatRoom/ChatPost/ChatPost.js +++ b/apps/web/src/routes/ChatRoom/ChatPost/ChatPost.js @@ -35,6 +35,7 @@ import { groupUrl, personUrl } from 'util/navigation' import { cn } from 'util/index' import styles from './ChatPost.module.scss' +import { getLocaleAsString } from 'components/Calendar/calendar-util' export default function ChatPost ({ className, @@ -269,8 +270,8 @@ export default function ChatPost ({
{creator.name}
- {DateTime.fromISO(createdAt).toFormat('t')} - {editedAt &&  ({t('edited')} {DateTime.fromISO(editedAt).toFormat('t')})} + {DateTime.fromISO(createdAt).setLocale(getLocaleAsString()).toFormat('t')} + {editedAt &&  ({t('edited')} {DateTime.fromISO(editedAt).setLocale(getLocaleAsString()).toFormat('t')})}
)} diff --git a/apps/web/src/routes/ChatRoom/ChatRoom.js b/apps/web/src/routes/ChatRoom/ChatRoom.js index 7f827645f..9149f1c76 100644 --- a/apps/web/src/routes/ChatRoom/ChatRoom.js +++ b/apps/web/src/routes/ChatRoom/ChatRoom.js @@ -46,6 +46,7 @@ import { groupInviteUrl, groupUrl } from 'util/navigation' import isWebView from 'util/webView' import styles from './ChatRoom.module.scss' +import { getLocaleAsString } from 'components/Calendar/calendar-util' // the maximum amount of time in minutes that can pass between messages to still // include them under the same avatar and timestamp @@ -463,7 +464,7 @@ const Footer = ({ context }) => { const StickyHeader = ({ data, prevData }) => { const firstItem = useCurrentlyRenderedData()[0] - const createdAt = firstItem?.createdAt ? DateTime.fromISO(firstItem.createdAt) : null + const createdAt = firstItem?.createdAt ? DateTime.fromISO(firstItem.createdAt).setLocale(getLocaleAsString()) : null const displayDay = createdAt && getDisplayDay(createdAt) return ( @@ -517,7 +518,7 @@ const ItemContent = ({ data: post, context, prevData, nextData }) => { const expanded = context.selectedPostId === post.id const firstUnread = context.latestOldPostId === prevData?.id && post.creator.id !== context.currentUser.id const previousDay = prevData?.createdAt ? DateTime.fromISO(prevData.createdAt) : DateTime.now() - const currentDay = DateTime.fromISO(post.createdAt) + const currentDay = DateTime.fromISO(post.createdAt).setLocale(getLocaleAsString()) const displayDay = prevData?.createdAt && previousDay.hasSame(currentDay, 'day') ? null : getDisplayDay(currentDay) const createdTimeDiff = currentDay.diff(previousDay, 'minutes')?.toObject().minutes || 1000 diff --git a/apps/web/src/routes/MemberProfile/MemberProfile.js b/apps/web/src/routes/MemberProfile/MemberProfile.js index 51fe8a8fe..3b76261b8 100644 --- a/apps/web/src/routes/MemberProfile/MemberProfile.js +++ b/apps/web/src/routes/MemberProfile/MemberProfile.js @@ -54,6 +54,7 @@ import { } from 'util/navigation' import styles from './MemberProfile.module.scss' +import { getLocaleAsString } from 'components/Calendar/calendar-util' const GROUPS_DIV_HEIGHT = 200 @@ -347,7 +348,7 @@ function Project ({ memberCap, project }) {
viewPostDetails(project)}>
{title}
-
{creator.name} - {DateTime.fromJSDate(createdAt).toRelative()}
+
{creator.name} - {DateTime.fromJSDate(createdAt).setLocale(getLocaleAsString()).toRelative()}
memberCap })} inline imageUrls={members.items.map(m => m.avatarUrl)} cap={memberCap} />
@@ -356,12 +357,13 @@ function Project ({ memberCap, project }) { function Event ({ memberCap, event }) { const { location, eventInvitations, startTime, title } = event + const start = DateTime.fromJSDate(startTime).setLocale(getLocaleAsString()) const viewPostDetails = useViewPostDetails() return (
viewPostDetails(event)}>
-
{DateTime.fromJSDate(startTime).toFormat('MMM')}
-
{DateTime.fromJSDate(startTime).toFormat('dd')}
+
{start.toFormat('MMM')}
+
{start.toFormat('dd')}
{title}
diff --git a/apps/web/src/routes/PostDetail/Comments/Comment/Comment.jsx b/apps/web/src/routes/PostDetail/Comments/Comment/Comment.jsx index b938b8b19..3c4538db0 100644 --- a/apps/web/src/routes/PostDetail/Comments/Comment/Comment.jsx +++ b/apps/web/src/routes/PostDetail/Comments/Comment/Comment.jsx @@ -30,6 +30,7 @@ import getMe from 'store/selectors/getMe' import getResponsibilitiesForGroup from 'store/selectors/getResponsibilitiesForGroup' import { RESP_MANAGE_CONTENT } from 'store/constants' import { INITIAL_SUBCOMMENTS_DISPLAYED } from 'util/constants' +import { getLocaleAsString } from 'components/Calendar/calendar-util' function Comment ({ comment, @@ -123,11 +124,11 @@ function Comment ({
{creator.name} - + {timestamp} {(editedTimestamp) && ( - + ({editedTimestamp}) )} diff --git a/apps/web/src/routes/UserSettings/ManageInvitesTab/ManageInvitesTab.js b/apps/web/src/routes/UserSettings/ManageInvitesTab/ManageInvitesTab.js index ce97b9d35..9c696bbae 100644 --- a/apps/web/src/routes/UserSettings/ManageInvitesTab/ManageInvitesTab.js +++ b/apps/web/src/routes/UserSettings/ManageInvitesTab/ManageInvitesTab.js @@ -9,6 +9,7 @@ import { JOIN_REQUEST_STATUS } from 'store/models/JoinRequest' import { currentUserSettingsUrl, personUrl } from 'util/navigation' import classes from './ManageInvitesTab.module.scss' +import { getLocaleAsString } from 'components/Calendar/calendar-util' const { array, bool, func } = PropTypes @@ -118,7 +119,7 @@ function GroupInvite ({ acceptInvite, declineInvite, invite }) {
- {t('Sent')} {DateTime.fromISO(createdAt).toFormat('MM-dd-yyyy')} + {t('Sent')} {DateTime.fromISO(createdAt).setLocale(getLocaleAsString()).toLocaleString(DateTime.DATE_SHORT)} {t('Decline')} acceptInvite(token, group.slug)} className={classes.joinButton}>{t('Join')}
@@ -143,7 +144,7 @@ function JoinRequest ({ joinRequest, cancelJoinRequest }) {
- {t('Requested')} {DateTime.fromISO(createdAt).toFormat('yyyy-MM-dd')} + {t('Requested')} {DateTime.fromISO(createdAt).setLocale(getLocaleAsString()).toLocaleString(DateTime.DATE_SHORT)} {joinRequest.status === JOIN_REQUEST_STATUS.Pending && ( {t('Cancel')} )} diff --git a/apps/web/src/store/presenters/presentPost.js b/apps/web/src/store/presenters/presentPost.js index 90b1d35b3..65b3041e3 100644 --- a/apps/web/src/store/presenters/presentPost.js +++ b/apps/web/src/store/presenters/presentPost.js @@ -1,6 +1,8 @@ +import i18n from '../../i18n.mjs' import { DateTime } from 'luxon' import presentTopic from 'store/presenters/presentTopic' import { TextHelpers } from '@hylo/shared' +import { getLocaleAsString } from 'components/Calendar/calendar-util' export default function presentPost (post, groupId) { if (!post) return null @@ -9,6 +11,7 @@ export default function presentPost (post, groupId) { Number(p.group) === Number(groupId)) const pinned = postMembership && postMembership.pinned const createdAtHumanDate = TextHelpers.humanDate(post.createdAt) + const createdAtHumanDateShort = TextHelpers.humanDate(post.createdAt, true) const editedAtHumanDate = TextHelpers.humanDate(post.editedAt) return { @@ -41,10 +44,11 @@ export default function presentPost (post, groupId) { } }), proposalOptions: post.proposalOptions?.toModelArray() || [], - createdTimestampForGrid: createdAtHumanDate, - createdTimestamp: `Posted ${createdAtHumanDate}`, - editedTimestamp: post.editedAt ? `Edited ${editedAtHumanDate}` : null, - exactCreatedTimestamp: DateTime.fromISO(post.createdAt).toFormat('D t ZZZZ'), - exactEditedTimestamp: DateTime.fromISO(post.editedAt).toFormat('D t ZZZZ') + createdTimestampForGrid: createdAtHumanDateShort, + createdTimestamp: `${i18n.t('Posted')} ${createdAtHumanDate}`, + createdTimestampForBigGrd: `${i18n.t('Posted')} ${createdAtHumanDateShort}`, + editedTimestamp: post.editedAt ? `${i18n.t('Edited')} ${editedAtHumanDate}` : null, + exactCreatedTimestamp: DateTime.fromISO(post.createdAt).setLocale(getLocaleAsString()).toFormat('D t ZZZZ'), + exactEditedTimestamp: DateTime.fromISO(post.editedAt).setLocale(getLocaleAsString()).toFormat('D t ZZZZ') } } diff --git a/apps/web/src/util/savedSearch.js b/apps/web/src/util/savedSearch.js index d699c85e1..5e75fc659 100644 --- a/apps/web/src/util/savedSearch.js +++ b/apps/web/src/util/savedSearch.js @@ -1,3 +1,4 @@ +import { getLocaleAsString } from 'components/Calendar/calendar-util' import { DateTime } from 'luxon' import { groupUrl } from 'util/navigation' @@ -26,7 +27,7 @@ export function currentFilters (filters) { export function formatParams (search) { const { group, context, createdAt, postTypes, searchText, topics } = search return [ - `Created on ${DateTime.fromISO(createdAt).toFormat('MMMM d yyyy')}`, // this was 'do' as in ordinal, but not supported in luxon + `Created on ${DateTime.fromISO(createdAt).setLocale(getLocaleAsString()).toLocaleString(DateTime.DATE_FULL)}`, ['all', 'public'].includes(context) ? `Context: ${context}` : '', group ? parsegroup(group) : '', searchText ? parseSearch(searchText) : '', diff --git a/packages/shared/src/TextHelpers.js b/packages/shared/src/TextHelpers.js index 2cb658a2e..29d019c8d 100644 --- a/packages/shared/src/TextHelpers.js +++ b/packages/shared/src/TextHelpers.js @@ -1,3 +1,5 @@ +import i18n from '../../../apps/web/src/i18n.mjs' +import { getLocaleAsString } from '../../../apps/web/src/components/Calendar/calendar-util' import { convert as convertHtmlToText } from 'html-to-text' import { isURL } from 'validator' import { marked } from 'marked' @@ -126,65 +128,50 @@ export const sanitizeURL = url => { // Date string related export function humanDate (date, short) { - const isString = typeof date === 'string' - const isValidDate = !isNaN(Number(date)) && Number(date) !== 0 - let ret = date && (isString || isValidDate) - ? prettyDate.format(isString ? new Date(date) : date) - : '' + const dt = typeof date === 'string' ? DateTime.fromISO(date) : DateTime.fromJSDate(date) + if (dt.invalid) return '' + let ret = new String(dt.toRelative()) // Always return 'now' for very recent timestamps - if (ret === 'just now') { - return 'now' + if (ret.includes('second')) { + return i18n.t('now') } - if (short) { - ret = ret.replace(' ago', '') - } else { - if (ret.match(/(\d+) seconds? ago/)) { - return 'now' - } - } + ret = dt.setLocale(getLocaleAsString()).toRelative({ style: (short ? 'short' : 'long') }) - return ret.replace(/ seconds?/, 's') - .replace(/ minutes?/, 'm') - .replace(/ hours?/, 'h') - .replace(/ days?/, 'd') - .replace(/ weeks?/, 'w') - .replace(/ years?/, 'y') - .replace(/ month(s?)/, ' mo$1') + return short + // TODO solve this problem in the future when we translate loads of languages + ? ret.replace(' ago', '').replace('hace ', '') + : ret } export const formatDatePair = (startTime, endTime, returnAsObj, timezone) => { - const start = DateTime.fromISO(startTime, {zone: timezone || DateTime.now().zoneName || 'UTC'}) - const end = DateTime.fromISO(endTime, {zone: timezone || DateTime.now().zoneName || 'UTC'}) - const now = DateTime.now() + if (!startTime || !endTime) return '(invalid start or end)' - const isThisYear = start.get('year') === now.get('year') && end.get('year') === now.get('year') + const locale = getLocaleAsString() + const now = DateTime.now().setLocale(locale) + timezone ||= now.zoneName - let to = '' - let from = '' + const start = DateTime.fromISO(startTime, {zone: timezone || 'UTC'}).setLocale(locale) + const end = DateTime.fromISO(endTime, {zone: timezone || 'UTC'}).setLocale(locale) - // TODO post-redesign: This was previously trying to add YYYY if it wasn't this year but that was just adding YYYY to the string - if (isThisYear) { - from = endTime ? start.toFormat("EEE, DD 'at' t") : start.toFormat("EEE, DD 'at' t ZZZZ") - } else { - from = endTime ? start.toFormat("EEE, DD 'at' t") : start.toFormat("EEE, DD 'at' t ZZZZ") - } + const isStartThisYear = start.hasSame(now, 'year') + const isEndThisYear = end.hasSame(now, 'year') + const isSameYear = isStartThisYear && isEndThisYear - if (endTime) { - if (end.get('year') !== start.get('year')) { - to = end.toFormat("EEE, DD, yyyy 'at' t ZZZZ") - } else if (end.get('month') !== start.get('month') || - end.get('day') !== start.get('day') || - end <= now) { - to = end.toFormat("EEE, DD 'at' t ZZZZ") - } else { - to = end.toFormat('t ZZZZ') - } - to = returnAsObj ? to : ' - ' + to - } + const from = !isSameYear || !isStartThisYear ? start.toFormat('EEE, DD, yyyy, t') : start.toFormat('EEE, DD, t') + let to = !isSameYear || !isEndThisYear ? end.toFormat('EEE, DD, yyyy, t ZZZZ') : end.toFormat('EEE, DD, t ZZZZ') - return returnAsObj ? { from, to } : from + to + if (!isSameYear) { + to = end.toFormat('EEE, DD, yyyy, t ZZZZ') + } else if (!end.hasSame(start, 'month')) { + to = end.toFormat('EEE, DD, t ZZZZ') + } else if (!end.hasSame(start, 'day')) { + to = end.toFormat('EEE, DD, t ZZZZ') + } else { + to = end.toFormat('t ZZZZ') + } + return returnAsObj ? { from, to } : `${from} \u2013 ${to}` } export function isDateInTheFuture (date) {