Files
Genarrative/src/components/rpg-entry/rpgEntryProfileTaskViewModel.ts

108 lines
2.7 KiB
TypeScript

import type {
ProfileTaskCenterResponse,
ProfileTaskItem,
} from '../../../packages/shared/src/contracts/runtime';
const PROFILE_TASK_STATUS_PRIORITY_RANK: Record<
ProfileTaskItem['status'],
number
> = {
claimable: 2,
incomplete: 1,
disabled: 0,
claimed: -1,
};
const PROFILE_TASK_CARD_FALLBACK_REWARD_POINTS = 10;
const PROFILE_TASK_STATUS_LABELS: Record<ProfileTaskItem['status'], string> = {
incomplete: '未完成',
claimable: '可领取',
claimed: '已领取',
disabled: '已停用',
};
export type ProfileTaskCardSummary = {
actionLabel: string;
progressCount: number;
progressPercent: number;
rewardPoints: number;
threshold: number;
};
export function selectProfileTaskCenterTasks(tasks: ProfileTaskItem[]) {
return tasks
.map((task, index) => ({ task, index }))
.filter(
({ task }) =>
task.status === 'claimable' || task.status === 'incomplete',
)
.sort(
(left, right) =>
PROFILE_TASK_STATUS_PRIORITY_RANK[right.task.status] -
PROFILE_TASK_STATUS_PRIORITY_RANK[left.task.status] ||
left.index - right.index,
)
.slice(0, 1)
.map(({ task }) => task);
}
export function selectProfileTaskCardTask(tasks: ProfileTaskItem[]) {
return (
selectProfileTaskCenterTasks(tasks)[0] ??
tasks.find((task) => task.status === 'claimed') ??
tasks.find((task) => task.status !== 'disabled') ??
null
);
}
export function getProfileTaskStatusLabel(status: ProfileTaskItem['status']) {
return PROFILE_TASK_STATUS_LABELS[status];
}
export function buildProfileTaskProgressLabel(task: ProfileTaskItem) {
const threshold = Math.max(1, task.threshold);
const progressCount = Math.min(Math.max(0, task.progressCount), threshold);
return `${progressCount}/${threshold}`;
}
export function getProfileTaskClaimButtonLabel(
task: ProfileTaskItem,
isClaiming: boolean,
) {
if (isClaiming) {
return '领取中';
}
if (task.status === 'claimed') {
return '已领取';
}
return task.status === 'claimable' ? '领取' : '未完成';
}
export function buildProfileTaskCardSummary(
center: ProfileTaskCenterResponse | null,
): ProfileTaskCardSummary {
const task = selectProfileTaskCardTask(center?.tasks ?? []);
const threshold = Math.max(1, task?.threshold ?? 1);
const progressCount = Math.min(
Math.max(0, task?.progressCount ?? 0),
threshold,
);
const rewardPoints =
task?.rewardPoints ?? PROFILE_TASK_CARD_FALLBACK_REWARD_POINTS;
const actionLabel =
task?.status === 'claimable'
? '领取'
: task?.status === 'claimed'
? '已完成'
: '去完成';
return {
actionLabel,
progressCount,
progressPercent: Math.round((progressCount / threshold) * 100),
rewardPoints,
threshold,
};
}