From 04ccf8aca93b589c1046662ae153700536570e69 Mon Sep 17 00:00:00 2001
From: Lim Chee Aun
Date: Thu, 5 Jan 2023 10:50:27 +0800
Subject: [PATCH] Replace @github/relative-time-element with dayjs
---
package-lock.json | 49 +++++++++++++++++++++------
package.json | 3 +-
src/components/relative-time.jsx | 57 ++++++++++++++++++++++++++++++++
src/components/status.jsx | 23 +++----------
src/compose.jsx | 1 -
src/main.jsx | 1 -
src/pages/notifications.jsx | 5 ++-
src/pages/settings.jsx | 4 +--
src/pages/status.jsx | 5 ++-
9 files changed, 107 insertions(+), 41 deletions(-)
create mode 100644 src/components/relative-time.jsx
diff --git a/package-lock.json b/package-lock.json
index dd11a14a..39e32772 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,8 +8,9 @@
"name": "phanpy",
"version": "0.1.0",
"dependencies": {
- "@github/relative-time-element": "~4.1.5",
"@github/text-expander-element": "~2.3.0",
+ "dayjs": "~1.11.7",
+ "dayjs-twitter": "~0.5.0",
"fast-blurhash": "~1.1.2",
"history": "~5.3.0",
"iconify-icon": "~1.0.2",
@@ -2062,11 +2063,6 @@
"resolved": "https://registry.npmjs.org/@github/combobox-nav/-/combobox-nav-2.1.5.tgz",
"integrity": "sha512-dmG1PuppNKHnBBEcfylWDwj9SSxd/E/qd8mC1G/klQC3s7ps5q6JZ034mwkkG0LKfI+Y+UgEua/ROD776N400w=="
},
- "node_modules/@github/relative-time-element": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.1.5.tgz",
- "integrity": "sha512-WAf1EQV5Sn6jGuAIQur/ztKlEV9R+VHDNwqEbeaOb6s9fiwM5z7+ujlWNZtgFkDp3lF0H8D/f0vdiPlfHz0ZTQ=="
- },
"node_modules/@github/text-expander-element": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.3.0.tgz",
@@ -3001,6 +2997,19 @@
"node": ">=8"
}
},
+ "node_modules/dayjs": {
+ "version": "1.11.7",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
+ "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
+ },
+ "node_modules/dayjs-twitter": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/dayjs-twitter/-/dayjs-twitter-0.5.0.tgz",
+ "integrity": "sha512-SZ7qEUISstBLUXdlGAbLrwr6zfRM9kaCfbq4uVTerM/HXzuHiiGzzUqAJVhxt+3tf69E+ocmQdP6YYpOINv05w==",
+ "dependencies": {
+ "duration-js": "^4.0.0"
+ }
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -3060,6 +3069,11 @@
"tslib": "^2.0.3"
}
},
+ "node_modules/duration-js": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/duration-js/-/duration-js-4.0.0.tgz",
+ "integrity": "sha512-qoXjOsH97r+NrOa6sK5V2cwBOouVG/LI9jwgwKvjVkyqGpZ72yilWjjzFJYPqqbvNZDwpRMaLEUFE+PTefvOEA=="
+ },
"node_modules/ejs": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
@@ -7183,11 +7197,6 @@
"resolved": "https://registry.npmjs.org/@github/combobox-nav/-/combobox-nav-2.1.5.tgz",
"integrity": "sha512-dmG1PuppNKHnBBEcfylWDwj9SSxd/E/qd8mC1G/klQC3s7ps5q6JZ034mwkkG0LKfI+Y+UgEua/ROD776N400w=="
},
- "@github/relative-time-element": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.1.5.tgz",
- "integrity": "sha512-WAf1EQV5Sn6jGuAIQur/ztKlEV9R+VHDNwqEbeaOb6s9fiwM5z7+ujlWNZtgFkDp3lF0H8D/f0vdiPlfHz0ZTQ=="
- },
"@github/text-expander-element": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.3.0.tgz",
@@ -7925,6 +7934,19 @@
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"dev": true
},
+ "dayjs": {
+ "version": "1.11.7",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
+ "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
+ },
+ "dayjs-twitter": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/dayjs-twitter/-/dayjs-twitter-0.5.0.tgz",
+ "integrity": "sha512-SZ7qEUISstBLUXdlGAbLrwr6zfRM9kaCfbq4uVTerM/HXzuHiiGzzUqAJVhxt+3tf69E+ocmQdP6YYpOINv05w==",
+ "requires": {
+ "duration-js": "^4.0.0"
+ }
+ },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -7964,6 +7986,11 @@
"tslib": "^2.0.3"
}
},
+ "duration-js": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/duration-js/-/duration-js-4.0.0.tgz",
+ "integrity": "sha512-qoXjOsH97r+NrOa6sK5V2cwBOouVG/LI9jwgwKvjVkyqGpZ72yilWjjzFJYPqqbvNZDwpRMaLEUFE+PTefvOEA=="
+ },
"ejs": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
diff --git a/package.json b/package.json
index ec25be14..0451e333 100644
--- a/package.json
+++ b/package.json
@@ -10,8 +10,9 @@
"source-map-explorer": "npx source-map-explorer dist/assets/*.js"
},
"dependencies": {
- "@github/relative-time-element": "~4.1.5",
"@github/text-expander-element": "~2.3.0",
+ "dayjs": "~1.11.7",
+ "dayjs-twitter": "~0.5.0",
"fast-blurhash": "~1.1.2",
"history": "~5.3.0",
"iconify-icon": "~1.0.2",
diff --git a/src/components/relative-time.jsx b/src/components/relative-time.jsx
new file mode 100644
index 00000000..7d8c7a14
--- /dev/null
+++ b/src/components/relative-time.jsx
@@ -0,0 +1,57 @@
+// Twitter-style relative time component
+// Seconds = 1s
+// Minutes = 1m
+// Hours = 1h
+// Days = 1d
+// After 7 days, use DD/MM/YYYY or MM/DD/YYYY
+import dayjs from 'dayjs';
+import dayjsTwitter from 'dayjs-twitter';
+import localizedFormat from 'dayjs/plugin/localizedFormat';
+import relativeTime from 'dayjs/plugin/relativeTime';
+import { useEffect, useState } from 'preact/hooks';
+
+dayjs.extend(dayjsTwitter);
+dayjs.extend(localizedFormat);
+dayjs.extend(relativeTime);
+
+const dtf = new Intl.DateTimeFormat();
+
+export default function RelativeTime({ datetime, format }) {
+ if (!datetime) return null;
+ const date = dayjs(datetime);
+ const [dateStr, setDateStr] = useState('');
+
+ useEffect(() => {
+ let timer, raf;
+ const update = () => {
+ raf = requestAnimationFrame(() => {
+ let str;
+ if (format === 'micro') {
+ // If date <= 7 days
+ if (date.diff(dayjs(), 'day') >= -7) {
+ str = date.twitter();
+ } else {
+ // If date > 7 days
+ str = dtf.format(date.toDate());
+ }
+ } else {
+ str = date.fromNow();
+ }
+ setDateStr(str);
+
+ timer = setTimeout(update, 30_000);
+ });
+ };
+ raf = requestAnimationFrame(update);
+ return () => {
+ clearTimeout(timer);
+ cancelAnimationFrame(raf);
+ };
+ }, [date]);
+
+ return (
+
+ );
+}
diff --git a/src/components/status.jsx b/src/components/status.jsx
index ce555c45..a23e0860 100644
--- a/src/components/status.jsx
+++ b/src/components/status.jsx
@@ -28,6 +28,7 @@ import visibilityIconsMap from '../utils/visibility-icons-map';
import Avatar from './avatar';
import Icon from './icon';
+import RelativeTime from './relative-time';
function fetchAccount(id) {
return masto.v1.accounts.fetch(id);
@@ -253,14 +254,7 @@ function Status({
alt={visibility}
size="s"
/>{' '}
-
- {createdAtDate.toLocaleString()}
-
+
) : (
@@ -269,14 +263,7 @@ function Status({
alt={visibility}
size="s"
/>{' '}
-
- {createdAtDate.toLocaleString()}
-
+
))}
@@ -1136,9 +1123,7 @@ function Poll({ poll, lang, readOnly, onUpdate = () => {} }) {
>
)}{' '}
• {expired ? 'Ended' : 'Ending'}{' '}
- {!!expiresAtDate && (
-
- )}
+ {!!expiresAtDate && }
)}
diff --git a/src/compose.jsx b/src/compose.jsx
index c9dbe4ca..757502eb 100644
--- a/src/compose.jsx
+++ b/src/compose.jsx
@@ -2,7 +2,6 @@ import './index.css';
import './app.css';
-import '@github/relative-time-element';
import { login } from 'masto';
import { render } from 'preact';
import { useEffect, useState } from 'preact/hooks';
diff --git a/src/main.jsx b/src/main.jsx
index 74bdd119..ad1d5cb9 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -1,6 +1,5 @@
import './index.css';
-import '@github/relative-time-element';
import { render } from 'preact';
import { App } from './app';
diff --git a/src/pages/notifications.jsx b/src/pages/notifications.jsx
index 8ea2acdf..378aca72 100644
--- a/src/pages/notifications.jsx
+++ b/src/pages/notifications.jsx
@@ -8,6 +8,7 @@ import Avatar from '../components/avatar';
import Icon from '../components/icon';
import Loader from '../components/loader';
import NameText from '../components/name-text';
+import RelativeTime from '../components/relative-time';
import Status from '../components/status';
import states from '../utils/states';
import store from '../utils/store';
@@ -102,11 +103,9 @@ function Notification({ notification }) {
{' '}
•{' '}
-
)}
diff --git a/src/pages/settings.jsx b/src/pages/settings.jsx
index 48c6e492..fbc6ef37 100644
--- a/src/pages/settings.jsx
+++ b/src/pages/settings.jsx
@@ -5,6 +5,7 @@ import { useRef, useState } from 'preact/hooks';
import Avatar from '../components/avatar';
import Icon from '../components/icon';
import NameText from '../components/name-text';
+import RelativeTime from '../components/relative-time';
import states from '../utils/states';
import store from '../utils/store';
@@ -196,8 +197,7 @@ function Settings({ onClose }) {
{__BUILD_TIME__ && (
- Last build:{' '}
- {' '}
+ Last build: {' '}
{__COMMIT_HASH__ && (
<>
(
diff --git a/src/pages/status.jsx b/src/pages/status.jsx
index 63aa3dd9..ef0b868b 100644
--- a/src/pages/status.jsx
+++ b/src/pages/status.jsx
@@ -17,6 +17,7 @@ import { useSnapshot } from 'valtio';
import Icon from '../components/icon';
import Loader from '../components/loader';
import NameText from '../components/name-text';
+import RelativeTime from '../components/relative-time';
import Status from '../components/status';
import htmlContentLength from '../utils/html-content-length';
import shortenNumber from '../utils/shorten-number';
@@ -325,11 +326,9 @@ function StatusPage({ id }) {
{' '}
•{' '}
-