import { ApiChat, ApiUser } from '../../api/types'; import { SERVICE_NOTIFICATIONS_USER_ID } from '../../config'; import { formatFullDate, formatTime } from '../../util/dateFormat'; import { orderBy } from '../../util/iteratees'; import { LangFn } from '../../hooks/useLang'; const USER_COLOR_KEYS = [1, 8, 5, 2, 7, 4, 6]; export function getUserFirstOrLastName(user?: ApiUser) { if (!user) { return undefined; } switch (user.type) { case 'userTypeBot': case 'userTypeRegular': { return user.firstName || user.lastName; } case 'userTypeDeleted': case 'userTypeUnknown': { return 'Deleted'; } default: return undefined; } } export function getUserFullName(user?: ApiUser) { if (!user) { return undefined; } if (isDeletedUser(user)) { return 'Deleted account'; } switch (user.type) { case 'userTypeBot': case 'userTypeRegular': { if (user.firstName && user.lastName) { return `${user.firstName} ${user.lastName}`; } if (user.firstName) { return user.firstName; } if (user.lastName) { return user.lastName; } break; } case 'userTypeDeleted': case 'userTypeUnknown': { return 'Deleted account'; } } return undefined; } export function getUserStatus(user: ApiUser, lang: LangFn) { if (user.id === SERVICE_NOTIFICATIONS_USER_ID) { return lang('ServiceNotifications').toLowerCase(); } if (user.type && user.type === 'userTypeBot') { return lang('Bot'); } if (!user.status) { return ''; } switch (user.status.type) { case 'userStatusEmpty': { return lang('ALongTimeAgo'); } case 'userStatusLastMonth': { return lang('WithinAMonth'); } case 'userStatusLastWeek': { return lang('WithinAWeek'); } case 'userStatusOffline': { const { wasOnline } = user.status; if (!wasOnline) return lang('LastSeen.Offline'); const now = new Date(); const wasOnlineDate = new Date(wasOnline * 1000); if (wasOnlineDate >= now) { return lang('LastSeen.JustNow'); } const diff = new Date(now.getTime() - wasOnlineDate.getTime()); // within a minute if (diff.getTime() / 1000 < 60) { return lang('LastSeen.JustNow'); } // within an hour if (diff.getTime() / 1000 < 60 * 60) { const minutes = Math.floor(diff.getTime() / 1000 / 60); return lang('LastSeen.MinutesAgo', minutes); } // today const today = new Date(); today.setHours(0, 0, 0, 0); if (wasOnlineDate > today) { // up to 6 hours ago if (diff.getTime() / 1000 < 6 * 60 * 60) { const hours = Math.floor(diff.getTime() / 1000 / 60 / 60); return lang('LastSeen.HoursAgo', hours); } // other return lang('LastSeen.TodayAt', formatTime(wasOnlineDate)); } // yesterday const yesterday = new Date(); yesterday.setDate(now.getDate() - 1); today.setHours(0, 0, 0, 0); if (wasOnlineDate > yesterday) { return lang('LastSeen.YesterdayAt', formatTime(wasOnlineDate)); } return lang('LastSeen.AtDate', formatFullDate(wasOnlineDate)); } case 'userStatusOnline': { return lang('Online'); } case 'userStatusRecently': { return lang('Lately'); } default: return undefined; } } export function isUserOnline(user: ApiUser) { const { id, status, type } = user; if (!status) { return false; } if (id === SERVICE_NOTIFICATIONS_USER_ID) { return false; } return status.type === 'userStatusOnline' && type !== 'userTypeBot'; } export function isDeletedUser(user: ApiUser) { if (!user.status || user.type === 'userTypeBot' || user.id === SERVICE_NOTIFICATIONS_USER_ID) { return false; } return user.type === 'userTypeDeleted' || user.type === 'userTypeUnknown'; } export function isUserBot(user: ApiUser) { return user.type === 'userTypeBot'; } export function sortUserIds( userIds: number[], usersById: Record, priorityIds?: number[], ) { return orderBy(userIds, (id) => { const now = Date.now() / 1000; if (priorityIds && priorityIds.includes(id)) { // Assuming that online status expiration date can't be as far as two days from now, // this should place prioritized on top of the list. // Then we subtract index of `id` in `priorityIds` to preserve selected order return now + (48 * 60 * 60) - (priorityIds.length - priorityIds.indexOf(id)); } const user = usersById[id]; if (!user || !user.status) { return 0; } if (user.status.type === 'userStatusOnline') { return user.status.expires; } else if (user.status.type === 'userStatusOffline' && user.status.wasOnline) { return user.status.wasOnline; } switch (user.status.type) { case 'userStatusRecently': return now - 60 * 60 * 24; case 'userStatusLastWeek': return now - 60 * 60 * 24 * 7; case 'userStatusLastMonth': return now - 60 * 60 * 24 * 7 * 30; default: return 0; } }, 'desc'); } // eslint-disable-next-line max-len // https://github.com/telegramdesktop/tdesktop/blob/371510cfe23b0bd226de8c076bc49248fbe40c26/Telegram/SourceFiles/data/data_peer.cpp#L53 export function getUserColorKey(peer: ApiUser | ApiChat | undefined) { const index = peer ? Math.abs(peer.id) % 7 : 0; return USER_COLOR_KEYS[index]; }