mirror of
https://github.com/flarum/framework.git
synced 2024-11-28 03:32:49 +08:00
feat: date time formats from locales (#4029)
Co-authored-by: Sami Mazouz <sychocouldy@gmail.com>
This commit is contained in:
parent
983d42160d
commit
d041515e19
|
@ -273,7 +273,7 @@ export default class UserListPage extends AdminPage {
|
||||||
name: app.translator.trans('core.admin.users.grid.columns.join_time.title'),
|
name: app.translator.trans('core.admin.users.grid.columns.join_time.title'),
|
||||||
content: (user: User) => (
|
content: (user: User) => (
|
||||||
<span className="UserList-joinDate" title={user.joinTime()}>
|
<span className="UserList-joinDate" title={user.joinTime()}>
|
||||||
{dayjs(user.joinTime()).format('LLL')}
|
{app.translator.formatDateTime(dayjs(user.joinTime()), 'core.lib.datetime_formats.userListJoinDate')}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
|
import type { Dayjs } from 'dayjs';
|
||||||
import { RichMessageFormatter, mithrilRichHandler, NestedStringArray } from '@askvortsov/rich-icu-message-formatter';
|
import { RichMessageFormatter, mithrilRichHandler, NestedStringArray } from '@askvortsov/rich-icu-message-formatter';
|
||||||
import { pluralTypeHandler, selectTypeHandler } from '@ultraq/icu-message-formatter';
|
import { pluralTypeHandler, selectTypeHandler } from '@ultraq/icu-message-formatter';
|
||||||
import username from './helpers/username';
|
import username from './helpers/username';
|
||||||
import User from './models/User';
|
import User from './models/User';
|
||||||
import extract from './utils/extract';
|
import extract from './utils/extract';
|
||||||
import extractText from './utils/extractText';
|
import extractText from './utils/extractText';
|
||||||
|
import ItemList from './utils/ItemList';
|
||||||
|
|
||||||
type Translations = Record<string, string>;
|
type Translations = Record<string, string>;
|
||||||
type TranslatorParameters = Record<string, unknown>;
|
type TranslatorParameters = Record<string, unknown>;
|
||||||
|
type DateTimeFormatCallback = (id?: string) => string | void;
|
||||||
|
|
||||||
export default class Translator {
|
export default class Translator {
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +17,11 @@ export default class Translator {
|
||||||
*/
|
*/
|
||||||
translations: Translations = {};
|
translations: Translations = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A item list of date time format callbacks.
|
||||||
|
*/
|
||||||
|
dateTimeFormats: ItemList<DateTimeFormatCallback> = new ItemList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The underlying ICU MessageFormatter util.
|
* The underlying ICU MessageFormatter util.
|
||||||
*/
|
*/
|
||||||
|
@ -88,4 +96,23 @@ export default class Translator {
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the time.
|
||||||
|
*
|
||||||
|
* The format of the time will be chosen by the following order:
|
||||||
|
* - Custom format defined in the item list.
|
||||||
|
* - The format defined in current locale.
|
||||||
|
* - DayJS default format.
|
||||||
|
*/
|
||||||
|
formatDateTime(time: Dayjs, id: string): string {
|
||||||
|
const formatCallback = this.dateTimeFormats.has(id) && this.dateTimeFormats.get(id);
|
||||||
|
|
||||||
|
if (formatCallback) {
|
||||||
|
const result = formatCallback.apply(this, [id]);
|
||||||
|
if (result) return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.format(this.translations[id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import type Mithril from 'mithril';
|
import type Mithril from 'mithril';
|
||||||
|
import app from '../app';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `fullTime` helper displays a formatted time string wrapped in a <time>
|
* The `fullTime` helper displays a formatted time string wrapped in a <time>
|
||||||
|
@ -9,7 +10,7 @@ export default function fullTime(time: Date): Mithril.Vnode {
|
||||||
const d = dayjs(time);
|
const d = dayjs(time);
|
||||||
|
|
||||||
const datetime = d.format();
|
const datetime = d.format();
|
||||||
const full = d.format('LLLL');
|
const full = app.translator.formatDateTime(d, 'core.lib.datetime_formats.fullTime');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<time pubdate datetime={datetime}>
|
<time pubdate datetime={datetime}>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import type Mithril from 'mithril';
|
import type Mithril from 'mithril';
|
||||||
|
import app from '../app';
|
||||||
import humanTimeUtil from '../utils/humanTime';
|
import humanTimeUtil from '../utils/humanTime';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,7 +12,7 @@ export default function humanTime(time: Date): Mithril.Vnode {
|
||||||
const d = dayjs(time);
|
const d = dayjs(time);
|
||||||
|
|
||||||
const datetime = d.format();
|
const datetime = d.format();
|
||||||
const full = d.format('LLLL');
|
const full = app.translator.formatDateTime(d, 'core.lib.datetime_formats.fullTime');
|
||||||
const ago = humanTimeUtil(time);
|
const ago = humanTimeUtil(time);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import app from '../app';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,17 +16,15 @@ export default function humanTime(time: dayjs.ConfigType): string {
|
||||||
d = now;
|
d = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
const day = 864e5;
|
|
||||||
const diff = d.diff(dayjs());
|
|
||||||
let ago: string;
|
let ago: string;
|
||||||
|
|
||||||
// If this date was more than a month ago, we'll show the name of the month
|
// If this date was more than a month ago, we'll show the name of the month
|
||||||
// in the string. If it wasn't this year, we'll show the year as well.
|
// in the string. If it wasn't this year, we'll show the year as well.
|
||||||
if (diff < -30 * day) {
|
if (d.diff(now, 'day') < -30) {
|
||||||
if (d.year() === dayjs().year()) {
|
if (d.isSame(now, 'year')) {
|
||||||
ago = d.format('D MMM');
|
ago = app.translator.formatDateTime(d, 'core.lib.datetime_formats.humanTimeShort');
|
||||||
} else {
|
} else {
|
||||||
ago = d.format('ll');
|
ago = app.translator.formatDateTime(d, 'core.lib.datetime_formats.humanTimeFull');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ago = d.fromNow();
|
ago = d.fromNow();
|
||||||
|
|
|
@ -10,7 +10,7 @@ function updateHumanTimes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `liveHumanTimes` initializer sets up a loop every 1 second to update
|
* The `liveHumanTimes` initializer sets up a loop every 10 seconds to update
|
||||||
* timestamps rendered with the `humanTime` helper.
|
* timestamps rendered with the `humanTime` helper.
|
||||||
*/
|
*/
|
||||||
export default function liveHumanTimes() {
|
export default function liveHumanTimes() {
|
||||||
|
|
|
@ -270,7 +270,7 @@ export default class PostStream extends Component {
|
||||||
// set the index to the last post.
|
// set the index to the last post.
|
||||||
this.stream.index = indexFromViewPort !== null ? indexFromViewPort + 1 : this.stream.count();
|
this.stream.index = indexFromViewPort !== null ? indexFromViewPort + 1 : this.stream.count();
|
||||||
this.stream.visible = visible;
|
this.stream.visible = visible;
|
||||||
if (period) this.stream.description = dayjs(period).format('MMMM YYYY');
|
if (period) this.stream.description = app.translator.formatDateTime(dayjs(period), 'core.lib.datetime_formats.scrubber');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -843,6 +843,14 @@ core:
|
||||||
username:
|
username:
|
||||||
deleted_text: "[deleted]"
|
deleted_text: "[deleted]"
|
||||||
|
|
||||||
|
# These are DayJS formats used in core.
|
||||||
|
datetime_formats:
|
||||||
|
fullTime: LLLL
|
||||||
|
humanTimeShort: D MMM
|
||||||
|
humanTimeLong: ll
|
||||||
|
scrubber: MMMM YYYY
|
||||||
|
userListJoinDate: LLL
|
||||||
|
|
||||||
# Translations in this namespace are used in views other than Flarum's normal JS client.
|
# Translations in this namespace are used in views other than Flarum's normal JS client.
|
||||||
views:
|
views:
|
||||||
# Translations in this namespace are displayed by the basic HTML admin index.
|
# Translations in this namespace are displayed by the basic HTML admin index.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user