74 lines
1.9 KiB
TypeScript
74 lines
1.9 KiB
TypeScript
import type { ImageSourcePropType } from 'react-native';
|
|
|
|
export type IdentityStat = {
|
|
key: string;
|
|
label: string;
|
|
value: number;
|
|
};
|
|
|
|
const STAT_BLUEPRINT: IdentityStat[] = [
|
|
{ key: 'likes', label: 'likes', value: 0 },
|
|
{ key: 'posts', label: 'posts', value: 0 },
|
|
{ key: 'views', label: 'views', value: 0 },
|
|
];
|
|
|
|
export function createStats(user: unknown): IdentityStat[] {
|
|
const source = (user as Record<string, unknown>) ?? {};
|
|
return STAT_BLUEPRINT.map(stat => ({
|
|
...stat,
|
|
value: deriveNumericValue(source[stat.key]),
|
|
}));
|
|
}
|
|
|
|
export function deriveDisplayName(user: unknown): string | null {
|
|
if (!user || typeof user !== 'object') {
|
|
return null;
|
|
}
|
|
const data = user as Record<string, unknown>;
|
|
return ensureString(data.username) ?? ensureString(data.name) ?? null;
|
|
}
|
|
|
|
export function deriveAvatarSource(user: unknown): ImageSourcePropType | undefined {
|
|
if (!user || typeof user !== 'object') {
|
|
return undefined;
|
|
}
|
|
const image = ensureString((user as Record<string, unknown>).image);
|
|
if (!image) {
|
|
return undefined;
|
|
}
|
|
return { uri: image };
|
|
}
|
|
|
|
export function deriveNumericValue(value: unknown): number {
|
|
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
return value;
|
|
}
|
|
if (typeof value === 'string') {
|
|
const parsed = Number(value);
|
|
if (Number.isFinite(parsed)) {
|
|
return parsed;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
export function deriveInitials(name: string): string {
|
|
const tokens = name
|
|
.replace(/[_-]+/g, ' ')
|
|
.split(/\s+/)
|
|
.filter(Boolean);
|
|
if (tokens.length === 0) {
|
|
return 'AI';
|
|
}
|
|
const initials = tokens.slice(0, 2).map(part => part[0]?.toUpperCase() ?? '');
|
|
return initials.join('') || tokens[0][0]?.toUpperCase() || 'AI';
|
|
}
|
|
|
|
function ensureString(value: unknown): string | null {
|
|
if (typeof value !== 'string') {
|
|
return null;
|
|
}
|
|
const trimmed = value.trim();
|
|
return trimmed.length > 0 ? trimmed : null;
|
|
}
|