Mixed-language UI was confusing — onboarding said "Why DChain / How it
works / Your keys" in English headings but feature descriptions and
CTAs were in Russian; compose's confirm dialog was Russian; feed tabs
were Russian; error messages in humanizeTxError were Russian.
Everything user-facing is now English.
Files touched (only string literals, not comments):
app/index.tsx onboarding slides + CTA buttons
app/(app)/compose.tsx composer alerts, header button, placeholder,
attachment-size hint
app/(app)/feed/index.tsx tab labels (Following/For you/Trending),
empty-state hints, retry button
app/(app)/feed/[id].tsx post detail header + stats rows (Views,
Likes, Size, Paid to publish, Hosted on,
Hashtags)
app/(app)/feed/tag/[tag].tsx empty-state copy
app/(app)/profile/[address].tsx Profile header, Follow/Following,
Edit, Open chat, Address, Copied, Encryption,
Added, Members, unknown-contact hint
app/(app)/new-contact.tsx Search title, placeholder, Search button,
empty-state hint, E2E-ready indicator,
Intro label + placeholder, fee-tier labels
(Min / Standard / Priority), Send request,
Insufficient-balance alert, Request-sent
alert
app/(app)/requests.tsx Notifications title, empty-state, Accept /
Decline buttons, decline-confirm alert,
"wants to add you" line
components/SearchBar.tsx default placeholder
components/feed/PostCard.tsx long-press menu (Delete post, confirm,
Actions / Cancel)
components/feed/ShareSheet.tsx sheet title, contact-search placeholder,
empty state, Select contacts / Send button,
plural helper rewritten for English
components/chat/PostRefCard.tsx "POST" ribbon, "photo" indicator
lib/api.ts humanizeTxError (rate-limit, clock skew,
bad signature, 400/5xx/network-error
messages)
lib/dates.ts dateBucket now returns Today/Yesterday/
"Jun 17, 2025"; month array switched to
English short forms
Code comments left in Russian intentionally — they're developer
context, not user-facing. This commit is purely display-string.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
2.4 KiB
TypeScript
68 lines
2.4 KiB
TypeScript
/**
|
||
* Date / time форматирование для UI мессенджера.
|
||
*
|
||
* Все функции принимают **unix-seconds** (совместимо с `Message.timestamp`,
|
||
* который тоже в секундах). Для ms-таймштампов делаем нормализацию внутри.
|
||
*/
|
||
|
||
// English short month names ("Jun 17, 2025").
|
||
const MONTHS_SHORT = [
|
||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
|
||
];
|
||
|
||
function sameDay(a: Date, b: Date): boolean {
|
||
return (
|
||
a.getFullYear() === b.getFullYear() &&
|
||
a.getMonth() === b.getMonth() &&
|
||
a.getDate() === b.getDate()
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Day-bucket label for chat separators.
|
||
* "Today" / "Yesterday" / "Jun 17, 2025"
|
||
*
|
||
* @param ts unix-seconds
|
||
*/
|
||
export function dateBucket(ts: number): string {
|
||
const d = new Date(ts * 1000);
|
||
const now = new Date();
|
||
const yday = new Date(); yday.setDate(now.getDate() - 1);
|
||
if (sameDay(d, now)) return 'Today';
|
||
if (sameDay(d, yday)) return 'Yesterday';
|
||
return `${MONTHS_SHORT[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`;
|
||
}
|
||
|
||
/**
|
||
* Короткое relative-time под углом bubble ("29m", "14m", "3h", "2d", "12:40").
|
||
*
|
||
* @param ts unix-seconds
|
||
*/
|
||
export function relTime(ts: number): string {
|
||
const now = Date.now();
|
||
const diff = now - ts * 1000;
|
||
if (diff < 60_000) return 'now';
|
||
if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m`;
|
||
if (diff < 24 * 3_600_000) return `${Math.floor(diff / 3_600_000)}h`;
|
||
if (diff < 7 * 24 * 3_600_000) return `${Math.floor(diff / (24 * 3_600_000))}d`;
|
||
const d = new Date(ts * 1000);
|
||
return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
|
||
}
|
||
|
||
/**
|
||
* Похоже на relTime, но принимает как unix-seconds, так и unix-ms.
|
||
* Используется в chat-list tiles (там timestamp бывает в ms от addedAt).
|
||
*/
|
||
export function formatWhen(ts: number): string {
|
||
// Heuristic: > 1e12 → уже в ms, иначе seconds.
|
||
const sec = ts > 1e12 ? Math.floor(ts / 1000) : ts;
|
||
return relTime(sec);
|
||
}
|
||
|
||
/** "HH:MM" — одна и та же локаль, без дня. */
|
||
export function formatHM(ts: number): string {
|
||
const d = new Date(ts * 1000);
|
||
return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
|
||
}
|