From b9b9f6a8d74d1ba24ef8b84fc502d04985e64ed7 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sun, 29 Jan 2023 14:14:42 +0000 Subject: [PATCH] Add relative time strings --- src/app/browser/friend/index.tsx | 13 ++++++--- src/app/browser/main/friends.tsx | 2 +- src/app/browser/main/index.tsx | 2 +- src/app/browser/util.tsx | 39 +++++++++++++++------------ src/app/i18n/locale/en-gb.ts | 45 ++++++++++++++++++++++++++++++-- src/app/main/ipc.ts | 9 ++++--- 6 files changed, 83 insertions(+), 27 deletions(-) diff --git a/src/app/browser/friend/index.tsx b/src/app/browser/friend/index.tsx index 6b9f928..00b8262 100644 --- a/src/app/browser/friend/index.tsx +++ b/src/app/browser/friend/index.tsx @@ -48,7 +48,7 @@ export default function FriendWindow(props: FriendProps) { if (!user || !friend || discord_presence_source_state !== RequestState.LOADED) { return @@ -62,7 +62,7 @@ export default function FriendWindow(props: FriendProps) { const can_see_user_presence = user.nsoAccount.user.permissions.presence === PresencePermissions.FRIENDS || (user.nsoAccount.user.permissions.presence === PresencePermissions.FAVORITE_FRIENDS && friend.isFavoriteFriend); - return + return {props.game.name} {props.game.sysDescription ? {props.game.sysDescription} : null} - {t('game_played_for', {duration: hrduration(props.game.totalPlayTime)})} + {props.game.totalPlayTime >= 60 ? + props.game.totalPlayTime % 60 ? + t('game_played_for_hm', {hours: Math.floor(props.game.totalPlayTime / 60), + minutes: props.game.totalPlayTime % 60}) : + t('game_played_for_h', {hours: props.game.totalPlayTime / 60}) : + t('game_played_for_m', {minutes: props.game.totalPlayTime})} {first_played ? t('game_first_played', { diff --git a/src/app/browser/main/friends.tsx b/src/app/browser/main/friends.tsx index 2409926..9d84d20 100644 --- a/src/app/browser/main/friends.tsx +++ b/src/app/browser/main/friends.tsx @@ -98,7 +98,7 @@ function FriendPresence(props: { const { t, i18n } = useTranslation('main_window', { keyPrefix: 'friends_section' }); const logout = props.presence.logoutAt ? new Date(props.presence.logoutAt * 1000) : null; - const since_logout = useTimeSince(logout ?? new Date(0), true); + const since_logout = useTimeSince(logout ?? new Date(0), true, i18n.getFixedT(null, 'time_since')); if (props.presence.state === PresenceState.ONLINE || props.presence.state === PresenceState.PLAYING) { return {t('presence_playing')}; diff --git a/src/app/browser/main/index.tsx b/src/app/browser/main/index.tsx index 7ddd8c4..097ba70 100644 --- a/src/app/browser/main/index.tsx +++ b/src/app/browser/main/index.tsx @@ -36,7 +36,7 @@ export default function App(props: AppProps) { titleUser={selectedUser} vibrancy={props.vibrancy} style={[styles.app, !props.vibrancy ? theme.appNoVibrancy : null]} - i18nNamespace="main_window" + i18nNamespace={['main_window', 'time_since']} > { @@ -323,24 +323,28 @@ interface TimeSinceInterval { interval: number; max: number; string: (count: number) => string; + key?: string; } const time_since_intervals: TimeSinceInterval[] = [ - {interval: 1000, max: 10, string: () => 'just now'}, - {interval: 1000, max: 60, string: c => c + ' second' + (c === 1 ? '' : 's') + ' ago'}, - {interval: 60 * 1000, max: 60, string: c => c + ' minute' + (c === 1 ? '' : 's') + ' ago'}, - {interval: 60 * 60 * 1000, max: 24, string: c => c + ' hour' + (c === 1 ? '' : 's') + ' ago'}, - {interval: 24 * 60 * 60 * 1000, max: Infinity, string: c => c + ' day' + (c === 1 ? '' : 's') + ' ago'}, + {interval: 1000, max: 10, string: () => 'just now', key: 'default.now'}, + {interval: 1000, max: 60, string: c => c + ' second' + (c === 1 ? '' : 's') + ' ago', key: 'default.seconds'}, + {interval: 60 * 1000, max: 60, string: c => c + ' minute' + (c === 1 ? '' : 's') + ' ago', key: 'default.minutes'}, + {interval: 60 * 60 * 1000, max: 24, string: c => c + ' hour' + (c === 1 ? '' : 's') + ' ago', key: 'default.hours'}, + {interval: 24 * 60 * 60 * 1000, max: Infinity, string: c => c + ' day' + (c === 1 ? '' : 's') + ' ago', key: 'default.days'}, ]; const short_time_since_intervals: TimeSinceInterval[] = [ - {interval: 1000, max: 10, string: () => 'Just now'}, - {interval: 1000, max: 60, string: c => c + ' sec' + (c === 1 ? '' : 's')}, - {interval: 60 * 1000, max: 60, string: c => c + ' min' + (c === 1 ? '' : 's')}, - {interval: 60 * 60 * 1000, max: 24, string: c => c + ' hr' + (c === 1 ? '' : 's')}, - {interval: 24 * 60 * 60 * 1000, max: Infinity, string: c => c + ' day' + (c === 1 ? '' : 's')}, + {interval: 1000, max: 10, string: () => 'Just now', key: 'default.now'}, + {interval: 1000, max: 60, string: c => c + ' sec' + (c === 1 ? '' : 's'), key: 'short.seconds'}, + {interval: 60 * 1000, max: 60, string: c => c + ' min' + (c === 1 ? '' : 's'), key: 'short.minutes'}, + {interval: 60 * 60 * 1000, max: 24, string: c => c + ' hr' + (c === 1 ? '' : 's'), key: 'short.hours'}, + {interval: 24 * 60 * 60 * 1000, max: Infinity, string: c => c + ' day' + (c === 1 ? '' : 's'), key: 'short.days'}, ]; -function getTimeSince(time: Date | number, now = Date.now(), intervals = time_since_intervals): [string, number] { +function getTimeSince( + time: Date | number, now = Date.now(), + intervals = time_since_intervals, t?: TFunction, +): [string, number] { if (time instanceof Date) time = time.getTime(); const elapsed = Math.max(0, now - time); @@ -349,7 +353,10 @@ function getTimeSince(time: Date | number, now = Date.now(), intervals = time_si for (const i of intervals) { if (elapsed < i.max * i.interval || last === i) { const count = Math.floor(elapsed / i.interval); - return [i.string.call(null, count), i.interval - (elapsed - (count * i.interval))]; + return [ + (t && i.key ? t(i.key, {count, defaultValue: ''}) : '') || i.string.call(null, count), + i.interval - (elapsed - (count * i.interval)), + ]; } } diff --git a/src/app/i18n/locale/en-gb.ts b/src/app/i18n/locale/en-gb.ts index 6d1c687..869ad3c 100644 --- a/src/app/i18n/locale/en-gb.ts +++ b/src/app/i18n/locale/en-gb.ts @@ -69,7 +69,15 @@ export const menus = { friend: { presence_online: 'Online', game_first_played: 'First played: {{date, datetime}}', - game_play_time: 'Play time: {{time, datetime}}', + + game_play_time_h: 'Play time: $t(friend.hours, {"count": {{hours}}})', + game_play_time_hm: 'Play time: $t(friend.hours, {"count": {{hours}}}), $t(friend.minutes, {"count": {{minutes}}})', + game_play_time_m: 'Play time: $t(friend.minutes, {"count": {{minutes}}})', + hours_one: '{{count}} hour', + hours_other: '{{count}} hours', + minutes_one: '{{count}} minute', + minutes_other: '{{count}} minutes', + presence_inactive: 'Offline (console online)', presence_offline: 'Offline', presence_updated: 'Updated: {{date, datetime}}', @@ -91,6 +99,32 @@ export const handle_uri = { cancel: 'Cancel', }; +export const time_since = { + default: { + now: 'just now', + seconds_one: '{{count}} second ago', + seconds_other: '{{count}} seconds ago', + minutes_one: '{{count}} minute ago', + minutes_other: '{{count}} minutes ago', + hours_one: '{{count}} hour ago', + hours_other: '{{count}} hours ago', + days_one: '{{count}} day ago', + days_other: '{{count}} days ago', + }, + + short: { + now: 'Just now', + seconds_one: '{{count}} sec', + seconds_other: '{{count}} secs', + minutes_one: '{{count}} min', + minutes_other: '{{count}} mins', + hours_one: '{{count}} hr', + hours_other: '{{count}} hrs', + days_one: '{{count}} day', + days_other: '{{count}} days', + }, +}; + export const main_window = { sidebar: { discord_active: 'Discord Rich Presence active', @@ -244,7 +278,14 @@ export const friend_window = { presence_offline: 'Offline', presence_last_seen: 'Last seen {{since_logout}}', - game_played_for: 'Played for {{duration}}', + game_played_for_h: 'Played for $t(hours, {"count": {{hours}}})', + game_played_for_hm: 'Played for $t(hours, {"count": {{hours}}}), $t(minutes, {"count": {{minutes}}})', + game_played_for_m: 'Played for $t(minutes, {"count": {{minutes}}})', + hours_one: '{{count}} hour', + hours_other: '{{count}} hours', + minutes_one: '{{count}} minute', + minutes_other: '{{count}} minutes', + game_first_played: 'First played {{date, datetime}}', game_first_played_now: 'First played now', game_title_id: 'Title ID', diff --git a/src/app/main/ipc.ts b/src/app/main/ipc.ts index 8fbfcf6..bb9e594 100644 --- a/src/app/main/ipc.ts +++ b/src/app/main/ipc.ts @@ -316,9 +316,12 @@ function buildFriendMenu(app: App, user: NintendoAccountUser, nso: CurrentUser, date: new Date(friend.presence.game.firstPlayedAt * 1000), formatParams: { date: { dateStyle: 'short', timeStyle: 'medium' } }, })!, enabled: false}), - new MenuItem({label: t('game_play_time', { - time: hrduration(friend.presence.game.totalPlayTime), - })!, enabled: false}), + new MenuItem({label: friend.presence.game.totalPlayTime >= 60 ? + friend.presence.game.totalPlayTime % 60 ? + t('game_play_time_hm', {hours: Math.floor(friend.presence.game.totalPlayTime / 60), + minutes: friend.presence.game.totalPlayTime % 60})! : + t('game_play_time_h', {hours: friend.presence.game.totalPlayTime / 60})! : + t('game_play_time_m', {minutes: friend.presence.game.totalPlayTime})!, enabled: false}), ] : []), new MenuItem({label: t('presence_updated', { date: new Date(friend.presence.updatedAt * 1000),