feat: 每日打卡
This commit is contained in:
@@ -56,6 +56,12 @@ const MODES = [
|
||||
label: '三字母精练',
|
||||
desc: '每页聚焦 3 个字母深度书写',
|
||||
},
|
||||
{
|
||||
id: 'letter-tracing-daily-checkin',
|
||||
icon: 'draw-o',
|
||||
label: '每日打卡',
|
||||
desc: '四宫格每日字母打卡练习',
|
||||
},
|
||||
] as const;
|
||||
|
||||
const MODE_MAP = Object.fromEntries(MODES.map((m) => [m.id, m])) as Record<
|
||||
@@ -72,6 +78,21 @@ for (let i = 0; i < LETTERS_UPPER.length; i += 3) {
|
||||
TRIPLE_GROUPS.push({ label, letters: [...group] });
|
||||
}
|
||||
|
||||
/** 每日打卡分组:4 个字母一组 */
|
||||
const DAILY_GROUPS: { label: string; letters: string[] }[] = [];
|
||||
for (let i = 0; i < LETTERS_UPPER.length; i += 4) {
|
||||
const group = LETTERS_UPPER.slice(i, i + 4);
|
||||
const label =
|
||||
group.length > 1 ? `${group[0]}–${group[group.length - 1]}` : group[0];
|
||||
DAILY_GROUPS.push({ label, letters: [...group] });
|
||||
}
|
||||
|
||||
function getDailyGroupIndex(letters?: string[]): number {
|
||||
const first = normalizeLetter(letters?.[0] ?? 'A');
|
||||
const idx = DAILY_GROUPS.findIndex((group) => group.letters[0] === first);
|
||||
return idx >= 0 ? idx : 0;
|
||||
}
|
||||
|
||||
/** 根据 worksheetId 查找页面元信息 */
|
||||
function pageInfoLookup(id: string) {
|
||||
const m = MODE_MAP[id];
|
||||
@@ -88,8 +109,11 @@ type PageData = CanvasDataState & {
|
||||
showCaseToggle: boolean;
|
||||
showNextLetter: boolean;
|
||||
showTripleGroupPicker: boolean;
|
||||
showDailyGroupPicker: boolean;
|
||||
tripleGroups: { label: string; letters: string[] }[];
|
||||
selectedTripleGroupIdx: number;
|
||||
dailyGroups: { label: string; letters: string[] }[];
|
||||
selectedDailyGroupIdx: number;
|
||||
letterGrid: string[];
|
||||
modeOptions: ReadonlyArray<{ id: string; label: string; desc: string }>;
|
||||
isPreviewFavorite: boolean;
|
||||
@@ -118,8 +142,11 @@ createPage(
|
||||
showCaseToggle: false,
|
||||
showNextLetter: true,
|
||||
showTripleGroupPicker: false,
|
||||
showDailyGroupPicker: false,
|
||||
tripleGroups: TRIPLE_GROUPS,
|
||||
selectedTripleGroupIdx: 0,
|
||||
dailyGroups: DAILY_GROUPS,
|
||||
selectedDailyGroupIdx: 0,
|
||||
letterGrid: LETTERS_PAIRS,
|
||||
modeOptions: [...MODES],
|
||||
isPreviewFavorite: false,
|
||||
@@ -204,6 +231,8 @@ createPage(
|
||||
this.data.traceMode === 'letter-tracing-case-pairing' ||
|
||||
this.data.traceMode === 'letter-tracing-half';
|
||||
const isTriple = this.data.traceMode === 'letter-tracing-three';
|
||||
const isDaily =
|
||||
this.data.traceMode === 'letter-tracing-daily-checkin';
|
||||
return mergeLetterTracingConfig(base, {
|
||||
selectedLetter: this.data.selectedLetter,
|
||||
letterCase,
|
||||
@@ -221,6 +250,13 @@ createPage(
|
||||
?.letters,
|
||||
}
|
||||
: {}),
|
||||
...(isDaily
|
||||
? {
|
||||
dailyLetters:
|
||||
DAILY_GROUPS[this.data.selectedDailyGroupIdx]
|
||||
?.letters,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
},
|
||||
|
||||
@@ -293,6 +329,14 @@ createPage(
|
||||
this.drawCanvas();
|
||||
},
|
||||
|
||||
/** 用户在每日打卡分组选择器中选择了一组 */
|
||||
onSelectDailyGroup(e: WechatMiniprogram.TouchEvent) {
|
||||
const idx = Number(e.currentTarget.dataset.idx);
|
||||
if (isNaN(idx) || idx === this.data.selectedDailyGroupIdx) return;
|
||||
this.setData({ selectedDailyGroupIdx: idx });
|
||||
this.drawCanvas();
|
||||
},
|
||||
|
||||
/**
|
||||
* 应用指定的 worksheet 配置到页面状态
|
||||
* 根据 worksheet 的 generatorConfig 决定 UI 控件的显隐(字母选择器、大小写切换等)
|
||||
@@ -320,9 +364,15 @@ createPage(
|
||||
traceMode === 'letter-tracing-half';
|
||||
const showNextLetter = traceMode === 'letter-tracing-single';
|
||||
const showTripleGroupPicker = traceMode === 'letter-tracing-three';
|
||||
const showDailyGroupPicker =
|
||||
traceMode === 'letter-tracing-daily-checkin';
|
||||
const selectedLetter = options?.preserveLetter
|
||||
? (this.data.selectedLetter ?? 'A')
|
||||
: normalizeLetter(merged.selectedLetter ?? '');
|
||||
const selectedDailyGroupIdx =
|
||||
options?.preserveLetter && showDailyGroupPicker
|
||||
? (this.data.selectedDailyGroupIdx ?? 0)
|
||||
: getDailyGroupIndex(merged.dailyLetters);
|
||||
const letterCaseLower =
|
||||
traceMode === 'letter-tracing-case-pairing' ||
|
||||
traceMode === 'letter-tracing-half'
|
||||
@@ -343,6 +393,8 @@ createPage(
|
||||
showCaseToggle,
|
||||
showNextLetter,
|
||||
showTripleGroupPicker,
|
||||
showDailyGroupPicker,
|
||||
selectedDailyGroupIdx,
|
||||
},
|
||||
() => {
|
||||
this.initPageInfo(
|
||||
|
||||
Reference in New Issue
Block a user