mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2025-02-02 07:31:38 +01:00
add timeformatter, shared between all view models
This commit is contained in:
parent
9c2c5af291
commit
c4e239a401
@ -29,6 +29,7 @@ import type {ILogger} from "../logging/types";
|
|||||||
import type {Navigation} from "./navigation/Navigation";
|
import type {Navigation} from "./navigation/Navigation";
|
||||||
import type {SegmentType} from "./navigation/index";
|
import type {SegmentType} from "./navigation/index";
|
||||||
import type {IURLRouter} from "./navigation/URLRouter";
|
import type {IURLRouter} from "./navigation/URLRouter";
|
||||||
|
import type { ITimeFormatter } from "../platform/types/types";
|
||||||
|
|
||||||
export type Options<T extends object = SegmentType> = {
|
export type Options<T extends object = SegmentType> = {
|
||||||
platform: Platform;
|
platform: Platform;
|
||||||
@ -145,4 +146,8 @@ export class ViewModel<N extends object = SegmentType, O extends Options<N> = Op
|
|||||||
// typescript needs a little help here
|
// typescript needs a little help here
|
||||||
return this._options.navigation as unknown as Navigation<N>;
|
return this._options.navigation as unknown as Navigation<N>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get timeFormatter(): ITimeFormatter {
|
||||||
|
return this._options.platform.timeFormatter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,13 +48,7 @@ export class DateTile extends ViewModel implements ITile<BaseEventEntry> {
|
|||||||
|
|
||||||
get date(): string {
|
get date(): string {
|
||||||
if (!this._dateString) {
|
if (!this._dateString) {
|
||||||
const date = new Date(this.refEntry.timestamp);
|
this._dateString = this.timeFormatter.formatRelativeDate(new Date(this.refEntry.timestamp));
|
||||||
this._dateString = date.toLocaleDateString({}, {
|
|
||||||
weekday: 'long',
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'long',
|
|
||||||
day: 'numeric'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return this._dateString;
|
return this._dateString;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
import type {RequestResult} from "../web/dom/request/fetch.js";
|
import type {RequestResult} from "../web/dom/request/fetch.js";
|
||||||
import type {RequestBody} from "../../matrix/net/common";
|
import type {RequestBody} from "../../matrix/net/common";
|
||||||
import type {ILogItem} from "../../logging/types";
|
import type { BaseObservableValue } from "../../observable/ObservableValue";
|
||||||
|
|
||||||
export interface IRequestOptions {
|
export interface IRequestOptions {
|
||||||
uploadProgress?: (loadedBytes: number) => void;
|
uploadProgress?: (loadedBytes: number) => void;
|
||||||
@ -43,3 +43,7 @@ export type File = {
|
|||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly blob: IBlobHandle;
|
readonly blob: IBlobHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ITimeFormatter {
|
||||||
|
formatRelativeDate(date: Date): string;
|
||||||
|
}
|
@ -39,6 +39,7 @@ import {Disposables} from "../../utils/Disposables";
|
|||||||
import {parseHTML} from "./parsehtml.js";
|
import {parseHTML} from "./parsehtml.js";
|
||||||
import {handleAvatarError} from "./ui/avatar";
|
import {handleAvatarError} from "./ui/avatar";
|
||||||
import {ThemeLoader} from "./theming/ThemeLoader";
|
import {ThemeLoader} from "./theming/ThemeLoader";
|
||||||
|
import {TimeFormatter} from "./dom/TimeFormatter";
|
||||||
|
|
||||||
function addScript(src) {
|
function addScript(src) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
@ -139,6 +140,7 @@ export class Platform {
|
|||||||
this._createLogger(options?.development);
|
this._createLogger(options?.development);
|
||||||
this.history = new History();
|
this.history = new History();
|
||||||
this.onlineStatus = new OnlineStatus();
|
this.onlineStatus = new OnlineStatus();
|
||||||
|
this.timeFormatter = new TimeFormatter();
|
||||||
this._serviceWorkerHandler = null;
|
this._serviceWorkerHandler = null;
|
||||||
if (assetPaths.serviceWorker && "serviceWorker" in navigator) {
|
if (assetPaths.serviceWorker && "serviceWorker" in navigator) {
|
||||||
this._serviceWorkerHandler = new ServiceWorkerHandler();
|
this._serviceWorkerHandler = new ServiceWorkerHandler();
|
||||||
|
73
src/platform/web/dom/TimeFormatter.ts
Normal file
73
src/platform/web/dom/TimeFormatter.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ITimeFormatter } from "../../types/types";
|
||||||
|
import {Clock} from "./Clock";
|
||||||
|
|
||||||
|
enum TimeScope {
|
||||||
|
Minute = 60 * 1000,
|
||||||
|
Day = 24 * 60 * 60 * 1000,
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TimeFormatter implements ITimeFormatter {
|
||||||
|
|
||||||
|
private todayMidnight: Date;
|
||||||
|
private relativeDayFormatter: Intl.RelativeTimeFormat;
|
||||||
|
private weekdayFormatter: Intl.DateTimeFormat;
|
||||||
|
private currentYearFormatter: Intl.DateTimeFormat;
|
||||||
|
private otherYearFormatter: Intl.DateTimeFormat;
|
||||||
|
|
||||||
|
constructor(private clock: Clock) {
|
||||||
|
// don't use the clock time here as the DOM relative formatters don't support setting the reference date anyway
|
||||||
|
this.todayMidnight = new Date();
|
||||||
|
this.todayMidnight.setHours(0, 0, 0, 0);
|
||||||
|
this.relativeDayFormatter = new Intl.RelativeTimeFormat(undefined, {numeric: "auto"});
|
||||||
|
this.weekdayFormatter = new Intl.DateTimeFormat(undefined, {weekday: 'long'});
|
||||||
|
this.currentYearFormatter = new Intl.DateTimeFormat(undefined, {
|
||||||
|
weekday: 'long',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric'
|
||||||
|
});
|
||||||
|
this.otherYearFormatter = new Intl.DateTimeFormat(undefined, {
|
||||||
|
weekday: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
formatRelativeDate(date: Date): string {
|
||||||
|
let daysDiff = Math.floor((date.getTime() - this.todayMidnight.getTime()) / TimeScope.Day);
|
||||||
|
console.log("formatRelativeDate daysDiff", daysDiff, date);
|
||||||
|
if (daysDiff >= -1 && daysDiff <= 1) {
|
||||||
|
// Tomorrow, Today, Yesterday
|
||||||
|
return capitalizeFirstLetter(this.relativeDayFormatter.format(daysDiff, "day"));
|
||||||
|
} else if (daysDiff > -7 && daysDiff < 0) {
|
||||||
|
// Wednesday
|
||||||
|
return this.weekdayFormatter.format(date);
|
||||||
|
} else if (this.todayMidnight.getFullYear() === date.getFullYear()) {
|
||||||
|
// Friday, November 6
|
||||||
|
return this.currentYearFormatter.format(date);
|
||||||
|
} else {
|
||||||
|
// Friday, November 5, 2021
|
||||||
|
return this.otherYearFormatter.format(date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function capitalizeFirstLetter(str: string) {
|
||||||
|
return str.slice(0, 1).toLocaleUpperCase() + str.slice(1);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user