Files
doodle-mini/miniprogram/pinyinPages/pinyinDictation/pinyinDictation.ts
T
2026-05-19 18:24:43 +08:00

169 lines
5.6 KiB
TypeScript

import PinyinDictationDraw from './draw/pinyinDictationDraw';
import type { PinyinDictationData } from './draw/pinyinDictationDraw';
import { createPage, type CanvasDataState } from '../../base/pageMixin';
import { defaultShareConfig } from '../../config/config';
import {
getModeInfo,
getPublishMetaByMode,
isValidMode,
PINYIN_DICTATION_MODE_OPTIONS,
type PinyinDictationMode,
} from './pinyinDictation.config';
import type { DebugPublishMeta } from '../../utils/debugPublish';
import {
addFavorite,
removeFavorite,
batchCheckFavorited,
} from '../../utils/favorites';
import { loadFontFace } from '../../core/font/fontLoader';
import { TONEOZ_PINYIN } from '../../core/font/fontProfiles';
const pageInfoLookup = getModeInfo;
type PageData = CanvasDataState & {
worksheetId: string;
currentMode: PinyinDictationMode;
modeOptions: typeof PINYIN_DICTATION_MODE_OPTIONS;
isPreviewFavorite: boolean;
isDevEnv: boolean;
debugPublishVisible: boolean;
debugPublishLoading: boolean;
debugPublishMeta: DebugPublishMeta | null;
};
createPage(
{
canvas: null as Canvas | null,
ctx: null as RenderingContext | null,
boxHeight: 0,
boxWidth: 0,
drawService: null as PinyinDictationDraw | null,
_favoritedMap: {} as Record<string, boolean>,
data: {
pageTitle: '拼音字母默写',
functionId: '',
hasContent: false,
showShareDialog: false,
worksheetId: 'pinyin-tracing',
currentMode: 'pinyin-tracing' as PinyinDictationMode,
modeOptions: PINYIN_DICTATION_MODE_OPTIONS,
isPreviewFavorite: false,
isDevEnv: false,
debugPublishVisible: false,
debugPublishLoading: false,
debugPublishMeta: null,
} as unknown as PageData,
onLoad(options: { id?: string }) {
const worksheetId =
options.id && isValidMode(options.id)
? options.id
: 'pinyin-tracing';
this.syncDebugPublishEnv();
this.applyWorksheet(worksheetId);
this.loadFavoritedMap();
},
onSelectMode(e: WechatMiniprogram.TouchEvent) {
const id = e.currentTarget.dataset.id as string | undefined;
if (!id || id === this.data.worksheetId) return;
this.applyWorksheet(id, { redraw: true });
},
onCanvasReady(e: WechatMiniprogram.CustomEvent) {
this.initCanvasFromComponent(e.detail, {
createDrawService: (
canvas: Canvas,
ctx: RenderingContext,
options?: Record<string, unknown>,
) => new PinyinDictationDraw(canvas, ctx, options),
drawServiceOptions: {
title: this.data.pageTitle,
},
onCanvasReady: () => {
this.drawCanvas();
},
});
},
async drawCanvas() {
if (!this.ctx || !this.drawService) return;
try {
await loadFontFace(TONEOZ_PINYIN);
const data: PinyinDictationData = {
mode: this.data.currentMode,
};
await (this.drawService as PinyinDictationDraw).draw(data);
this.setData({ hasContent: true });
} catch (e) {
console.error('pinyinDictation draw failed', e);
this.setData({ hasContent: false });
}
},
async onPreviewFavorite() {
const next = !this.data.isPreviewFavorite;
this.setData({ isPreviewFavorite: next });
const id = this.data.worksheetId;
if (id) {
this._favoritedMap[id] = next;
if (next) {
addFavorite(id);
} else {
removeFavorite(id);
}
}
wx.showToast({
title: next ? '收藏成功' : '已取消收藏',
icon: 'none',
});
},
async loadFavoritedMap() {
const ids = PINYIN_DICTATION_MODE_OPTIONS.map((d) => d.id);
this._favoritedMap = await batchCheckFavorited(ids);
const currentId = this.data.worksheetId;
if (this._favoritedMap[currentId]) {
this.setData({ isPreviewFavorite: true });
}
},
getPublishMeta(): DebugPublishMeta {
const meta = getPublishMetaByMode(this.data.worksheetId);
if (!meta) {
throw new Error('当前题型配置不存在');
}
return meta;
},
applyWorksheet(worksheetId: string, options?: { redraw?: boolean }) {
if (!isValidMode(worksheetId)) return;
this.setData(
{
worksheetId,
functionId: worksheetId,
currentMode: worksheetId as PinyinDictationMode,
isPreviewFavorite: !!this._favoritedMap[worksheetId],
},
() => {
this.initPageInfo(worksheetId, '拼音字母默写');
if (this.drawService) {
this.drawService.options.title = this.data.pageTitle;
}
if (options?.redraw) {
this.drawCanvas();
}
},
);
},
},
{
shareConfig: defaultShareConfig,
pageInfoLookup,
},
);