forked from rDrama/rDrama
Add human readable timestamp
parent
4c5a46f80a
commit
a08eb64469
|
@ -11,7 +11,6 @@ declare interface ChatSpeakResponse {
|
||||||
text_censored: string;
|
text_censored: string;
|
||||||
text_html: string;
|
text_html: string;
|
||||||
time: number;
|
time: number;
|
||||||
timestamp: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface EmojiModSelection {
|
declare interface EmojiModSelection {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/humanize-duration": "^3.27.1",
|
||||||
"@types/lodash.debounce": "^4.0.7",
|
"@types/lodash.debounce": "^4.0.7",
|
||||||
"@types/lozad": "^1.16.1",
|
"@types/lozad": "^1.16.1",
|
||||||
"@types/react": "^18.0.20",
|
"@types/react": "^18.0.20",
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
"dotenv": "^16.0.2",
|
"dotenv": "^16.0.2",
|
||||||
"esbuild": "^0.15.7",
|
"esbuild": "^0.15.7",
|
||||||
|
"humanize-duration": "^3.27.3",
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
"lozad": "^1.16.0",
|
"lozad": "^1.16.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
|
|
@ -35,8 +35,6 @@ function AppInner() {
|
||||||
const initiallyScrolledDown = useRef(false);
|
const initiallyScrolledDown = useRef(false);
|
||||||
const { messages, quote } = useChat();
|
const { messages, quote } = useChat();
|
||||||
|
|
||||||
console.log({ quote });
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (messages.length > 0) {
|
if (messages.length > 0) {
|
||||||
if (initiallyScrolledDown.current) {
|
if (initiallyScrolledDown.current) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { useCallback, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import cx from "classnames";
|
import cx from "classnames";
|
||||||
import key from "weak-key";
|
import key from "weak-key";
|
||||||
|
import humanizeDuration from "humanize-duration";
|
||||||
import { Username } from "./Username";
|
import { Username } from "./Username";
|
||||||
import { useChat, useRootContext } from "../../hooks";
|
import { useChat, useRootContext } from "../../hooks";
|
||||||
import "./ChatMessage.css";
|
import "./ChatMessage.css";
|
||||||
|
@ -9,6 +10,8 @@ interface ChatMessageProps extends ChatSpeakResponse {
|
||||||
showUser?: boolean;
|
showUser?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TIMESTAMP_UPDATE_INTERVAL = 20000;
|
||||||
|
|
||||||
export function ChatMessage({
|
export function ChatMessage({
|
||||||
avatar,
|
avatar,
|
||||||
showUser = true,
|
showUser = true,
|
||||||
|
@ -19,7 +22,6 @@ export function ChatMessage({
|
||||||
text_html,
|
text_html,
|
||||||
text_censored,
|
text_censored,
|
||||||
time,
|
time,
|
||||||
timestamp,
|
|
||||||
}: ChatMessageProps) {
|
}: ChatMessageProps) {
|
||||||
const message = {
|
const message = {
|
||||||
avatar,
|
avatar,
|
||||||
|
@ -30,7 +32,6 @@ export function ChatMessage({
|
||||||
text_html,
|
text_html,
|
||||||
text_censored,
|
text_censored,
|
||||||
time,
|
time,
|
||||||
timestamp,
|
|
||||||
};
|
};
|
||||||
const {
|
const {
|
||||||
username: loggedInUsername,
|
username: loggedInUsername,
|
||||||
|
@ -57,6 +58,18 @@ export function ChatMessage({
|
||||||
setConfirmedDelete(true);
|
setConfirmedDelete(true);
|
||||||
}
|
}
|
||||||
}, [text, confirmedDelete]);
|
}, [text, confirmedDelete]);
|
||||||
|
const [timestamp, setTimestamp] = useState(formatTimeAgo(time));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const updatingTimestamp = setInterval(
|
||||||
|
() => setTimestamp(formatTimeAgo(time)),
|
||||||
|
TIMESTAMP_UPDATE_INTERVAL
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(updatingTimestamp);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"ChatMessage"} style={style}>
|
<div className={"ChatMessage"} style={style}>
|
||||||
|
@ -117,3 +130,13 @@ export function ChatMessageList() {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatTimeAgo(time: number) {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
|
||||||
|
return `${humanizeDuration(time * 1000 - now, {
|
||||||
|
round: true,
|
||||||
|
units: ["h", "m", "s"],
|
||||||
|
largest: 2,
|
||||||
|
})} ago`;
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
|
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
|
||||||
integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==
|
integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==
|
||||||
|
|
||||||
|
"@types/humanize-duration@^3.27.1":
|
||||||
|
version "3.27.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/humanize-duration/-/humanize-duration-3.27.1.tgz#f14740d1f585a0a8e3f46359b62fda8b0eaa31e7"
|
||||||
|
integrity sha512-K3e+NZlpCKd6Bd/EIdqjFJRFHbrq5TzPPLwREk5Iv/YoIjQrs6ljdAUCo+Lb2xFlGNOjGSE0dqsVD19cZL137w==
|
||||||
|
|
||||||
"@types/lodash.debounce@^4.0.7":
|
"@types/lodash.debounce@^4.0.7":
|
||||||
version "4.0.7"
|
version "4.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.7.tgz#0285879defb7cdb156ae633cecd62d5680eded9f"
|
resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.7.tgz#0285879defb7cdb156ae633cecd62d5680eded9f"
|
||||||
|
@ -362,6 +367,11 @@ hoist-non-react-statics@^3.3.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
react-is "^16.7.0"
|
react-is "^16.7.0"
|
||||||
|
|
||||||
|
humanize-duration@^3.27.3:
|
||||||
|
version "3.27.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/humanize-duration/-/humanize-duration-3.27.3.tgz#db654e72ebf5ccfe232c7f56bc58aa3a6fe4df88"
|
||||||
|
integrity sha512-iimHkHPfIAQ8zCDQLgn08pRqSVioyWvnGfaQ8gond2wf7Jq2jJ+24ykmnRyiz3fIldcn4oUuQXpjqKLhSVR7lw==
|
||||||
|
|
||||||
inflight@^1.0.4:
|
inflight@^1.0.4:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||||
|
|
Loading…
Reference in New Issue