feat(status): improve last-seen labels in web private chats
Some checks are pending
CI / test (push) Has started running
Some checks are pending
CI / test (push) Has started running
This commit is contained in:
@@ -9,7 +9,7 @@ Legend:
|
|||||||
|
|
||||||
1. Account - `PARTIAL` (email auth, JWT, refresh, logout, reset; sessions exist, full UX still improving)
|
1. Account - `PARTIAL` (email auth, JWT, refresh, logout, reset; sessions exist, full UX still improving)
|
||||||
2. User Profile - `DONE` (username, name, avatar, bio, update)
|
2. User Profile - `DONE` (username, name, avatar, bio, update)
|
||||||
3. User Status - `PARTIAL` (online/last seen/offline; "recently" heuristic limited)
|
3. User Status - `PARTIAL` (online/last seen/offline; web now formats `just now/today/yesterday/recently`, backend-side presence heuristics still limited)
|
||||||
4. Contacts - `PARTIAL` (list/search/add/remove/block/unblock; `add by email` flow covered by integration tests including `success/not found/blocked conflict`; UX moved to menu)
|
4. Contacts - `PARTIAL` (list/search/add/remove/block/unblock; `add by email` flow covered by integration tests including `success/not found/blocked conflict`; UX moved to menu)
|
||||||
5. Chat List - `DONE` (all/pinned/archive/sort/unread; saved-messages delete behavior covered: clear history without deleting chat)
|
5. Chat List - `DONE` (all/pinned/archive/sort/unread; saved-messages delete behavior covered: clear history without deleting chat)
|
||||||
6. Chat Types - `DONE` (private/group/channel)
|
6. Chat Types - `DONE` (private/group/channel)
|
||||||
|
|||||||
@@ -878,6 +878,26 @@ function formatLastSeen(value: string): string {
|
|||||||
if (Number.isNaN(date.getTime())) {
|
if (Number.isNaN(date.getTime())) {
|
||||||
return "recently";
|
return "recently";
|
||||||
}
|
}
|
||||||
|
const now = new Date();
|
||||||
|
const diffMs = now.getTime() - date.getTime();
|
||||||
|
if (diffMs < 0) {
|
||||||
|
return "recently";
|
||||||
|
}
|
||||||
|
const minute = 60 * 1000;
|
||||||
|
const hour = 60 * minute;
|
||||||
|
const day = 24 * hour;
|
||||||
|
if (diffMs < 2 * minute) {
|
||||||
|
return "just now";
|
||||||
|
}
|
||||||
|
if (diffMs < day) {
|
||||||
|
return `today at ${date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}`;
|
||||||
|
}
|
||||||
|
if (diffMs < 2 * day) {
|
||||||
|
return `yesterday at ${date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}`;
|
||||||
|
}
|
||||||
|
if (diffMs < 7 * day) {
|
||||||
|
return "recently";
|
||||||
|
}
|
||||||
return date.toLocaleString(undefined, {
|
return date.toLocaleString(undefined, {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
month: "short",
|
month: "short",
|
||||||
|
|||||||
@@ -895,6 +895,26 @@ function formatLastSeen(value: string): string {
|
|||||||
if (Number.isNaN(date.getTime())) {
|
if (Number.isNaN(date.getTime())) {
|
||||||
return "recently";
|
return "recently";
|
||||||
}
|
}
|
||||||
|
const now = new Date();
|
||||||
|
const diffMs = now.getTime() - date.getTime();
|
||||||
|
if (diffMs < 0) {
|
||||||
|
return "recently";
|
||||||
|
}
|
||||||
|
const minute = 60 * 1000;
|
||||||
|
const hour = 60 * minute;
|
||||||
|
const day = 24 * hour;
|
||||||
|
if (diffMs < 2 * minute) {
|
||||||
|
return "just now";
|
||||||
|
}
|
||||||
|
if (diffMs < day) {
|
||||||
|
return `today at ${date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}`;
|
||||||
|
}
|
||||||
|
if (diffMs < 2 * day) {
|
||||||
|
return `yesterday at ${date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}`;
|
||||||
|
}
|
||||||
|
if (diffMs < 7 * day) {
|
||||||
|
return "recently";
|
||||||
|
}
|
||||||
return date.toLocaleString(undefined, {
|
return date.toLocaleString(undefined, {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
month: "short",
|
month: "short",
|
||||||
|
|||||||
@@ -317,6 +317,26 @@ function formatLastSeen(value: string): string {
|
|||||||
if (Number.isNaN(date.getTime())) {
|
if (Number.isNaN(date.getTime())) {
|
||||||
return "recently";
|
return "recently";
|
||||||
}
|
}
|
||||||
|
const now = new Date();
|
||||||
|
const diffMs = now.getTime() - date.getTime();
|
||||||
|
if (diffMs < 0) {
|
||||||
|
return "recently";
|
||||||
|
}
|
||||||
|
const minute = 60 * 1000;
|
||||||
|
const hour = 60 * minute;
|
||||||
|
const day = 24 * hour;
|
||||||
|
if (diffMs < 2 * minute) {
|
||||||
|
return "just now";
|
||||||
|
}
|
||||||
|
if (diffMs < day) {
|
||||||
|
return `today at ${date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}`;
|
||||||
|
}
|
||||||
|
if (diffMs < 2 * day) {
|
||||||
|
return `yesterday at ${date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}`;
|
||||||
|
}
|
||||||
|
if (diffMs < 7 * day) {
|
||||||
|
return "recently";
|
||||||
|
}
|
||||||
return date.toLocaleString(undefined, {
|
return date.toLocaleString(undefined, {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
month: "short",
|
month: "short",
|
||||||
|
|||||||
Reference in New Issue
Block a user