201 lines
5.6 KiB
TypeScript
201 lines
5.6 KiB
TypeScript
import { NAV_INNER_PX } from '../../utils/navMetrics';
|
|
import {
|
|
HOME_CURRENT_CAPABILITY_DATA,
|
|
type HomeDisplayItem,
|
|
type HomeDisplaySection,
|
|
} from './home.data';
|
|
|
|
type AgeBandKey = string;
|
|
|
|
type HomeTab = {
|
|
id: string;
|
|
name: string;
|
|
};
|
|
|
|
type HomeAgeBandView = {
|
|
key: string;
|
|
label: string;
|
|
desc: string;
|
|
path: string;
|
|
icon: string;
|
|
};
|
|
|
|
type HomeDisplayItemView = HomeDisplayItem & {
|
|
topBg: string;
|
|
};
|
|
|
|
type HomeDisplaySectionView = HomeDisplaySection & {
|
|
anchorId: string;
|
|
items: HomeDisplayItemView[];
|
|
};
|
|
|
|
const AGE_BAND_ICONS = ['🌱', '🚀', '🎓', '🧠', '🏆'] as const;
|
|
|
|
const CATEGORY_TOP_BG: Record<HomeDisplayItem['category'], string> = {
|
|
math: '#fff3c4',
|
|
chinese: '#d8f0d0',
|
|
english: '#e8f4ff',
|
|
puzzle: '#f5e6dc',
|
|
craft: '#fce4ec',
|
|
};
|
|
|
|
const SECTION_ANCHOR_PREFIX = 'section-';
|
|
const TAB_BAR_PATHS = new Set([
|
|
'/pages/home/home',
|
|
'/pages/age/age',
|
|
'/pages/favorites/favorites',
|
|
'/pages/profile/profile',
|
|
]);
|
|
|
|
function toItemView(item: HomeDisplayItem): HomeDisplayItemView {
|
|
return {
|
|
...item,
|
|
topBg: CATEGORY_TOP_BG[item.category],
|
|
};
|
|
}
|
|
|
|
function sortSectionsByTabs(
|
|
tabs: readonly { id: string }[],
|
|
sections: HomeDisplaySection[],
|
|
): HomeDisplaySectionView[] {
|
|
const orderMap = tabs.reduce<Record<string, number>>((acc, tab, index) => {
|
|
acc[tab.id] = index;
|
|
return acc;
|
|
}, {});
|
|
|
|
return [...sections]
|
|
.sort((a, b) => {
|
|
const aOrder = orderMap[a.id];
|
|
const bOrder = orderMap[b.id];
|
|
// 注意:0 需要保留(不能用 || 进行兜底)
|
|
return (aOrder ?? 999) - (bOrder ?? 999);
|
|
})
|
|
.map((section) => ({
|
|
...section,
|
|
anchorId: `${SECTION_ANCHOR_PREFIX}${section.id}`,
|
|
items: section.items.map(toItemView),
|
|
}));
|
|
}
|
|
|
|
function navigateByPath(path?: string, fallbackTitle?: string) {
|
|
if (!path) {
|
|
wx.showToast({
|
|
title: fallbackTitle ? `${fallbackTitle} 即将上线` : '即将上线',
|
|
icon: 'none',
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (TAB_BAR_PATHS.has(path)) {
|
|
wx.switchTab({ url: path });
|
|
return;
|
|
}
|
|
|
|
wx.navigateTo({ url: path });
|
|
}
|
|
|
|
const win = wx.getWindowInfo();
|
|
const HOME_DATA = HOME_CURRENT_CAPABILITY_DATA;
|
|
const HOME_TABS: HomeTab[] = HOME_DATA.categoryTabs.map((item) => ({
|
|
id: item.id,
|
|
name: item.name,
|
|
}));
|
|
const HOME_SECTIONS = sortSectionsByTabs(HOME_TABS, HOME_DATA.sections);
|
|
console.log('HOME_DATA', HOME_DATA);
|
|
console.log('HOME_SECTIONS', HOME_SECTIONS);
|
|
|
|
Page({
|
|
data: {
|
|
statusBarHeight: win.statusBarHeight,
|
|
navBlockHeight: win.statusBarHeight + NAV_INNER_PX,
|
|
searchPlaceholder: HOME_DATA.searchPlaceholder,
|
|
tabs: HOME_TABS,
|
|
activeTab: 'all',
|
|
ageBands: HOME_DATA.ageBands.map((item, idx) => ({
|
|
...item,
|
|
icon: AGE_BAND_ICONS[idx] || '🌟',
|
|
})) as HomeAgeBandView[],
|
|
activeAgeBand: HOME_DATA.ageBands[0]?.key || ('3-4' as AgeBandKey),
|
|
featuredItems: HOME_DATA.featured.map(toItemView),
|
|
hotRecommends: HOME_DATA.hot.map(toItemView),
|
|
sections: HOME_SECTIONS,
|
|
},
|
|
|
|
onTabChange(e: WechatMiniprogram.CustomEvent) {
|
|
const id = e.detail.id as string | undefined;
|
|
if (!id) return;
|
|
|
|
this.setData({ activeTab: id });
|
|
|
|
if (id === 'all') {
|
|
wx.pageScrollTo({
|
|
scrollTop: 0,
|
|
duration: 400,
|
|
});
|
|
return;
|
|
}
|
|
|
|
wx.pageScrollTo({
|
|
selector: `#${SECTION_ANCHOR_PREFIX}${id}`,
|
|
duration: 400,
|
|
offsetTop: -(win.statusBarHeight + NAV_INNER_PX + 24),
|
|
});
|
|
},
|
|
|
|
onTapAgeBand(e: WechatMiniprogram.TouchEvent) {
|
|
const key = e.currentTarget.dataset.key as AgeBandKey | undefined;
|
|
const path = e.currentTarget.dataset.path as string | undefined;
|
|
if (!key) return;
|
|
this.setData({ activeAgeBand: key });
|
|
navigateByPath(path, '分龄内容');
|
|
},
|
|
|
|
onTapFeatured(e: WechatMiniprogram.TouchEvent) {
|
|
const path = e.currentTarget.dataset.path as string | undefined;
|
|
const title = e.currentTarget.dataset.title as string | undefined;
|
|
navigateByPath(path, title);
|
|
},
|
|
|
|
onTapHotRecommend(e: WechatMiniprogram.TouchEvent) {
|
|
const path = e.currentTarget.dataset.path as string | undefined;
|
|
const title = e.currentTarget.dataset.title as string | undefined;
|
|
navigateByPath(path, title);
|
|
},
|
|
|
|
onTapAgeMore() {
|
|
wx.switchTab({ url: '/pages/age/age' });
|
|
},
|
|
|
|
onTapHotMore() {
|
|
wx.showToast({ title: '热门内容整理中', icon: 'none' });
|
|
},
|
|
|
|
onTapTrackMore(e: WechatMiniprogram.TouchEvent) {
|
|
const path = e.currentTarget.dataset.path as string | undefined;
|
|
const title = e.currentTarget.dataset.title as string | undefined;
|
|
navigateByPath(path, title);
|
|
},
|
|
|
|
onTapTrackCard(e: WechatMiniprogram.TouchEvent) {
|
|
const path = e.currentTarget.dataset.path as string | undefined;
|
|
const title = e.currentTarget.dataset.title as string | undefined;
|
|
navigateByPath(path, title);
|
|
},
|
|
|
|
onShareAppMessage() {
|
|
return {
|
|
title: '涂鸦丫 - 快来生成宝宝的专属学习卡',
|
|
path: '/pages/home/home',
|
|
imageUrl:
|
|
'https://cdn.joeyone.cn/doodle/share-img/index-share-v2.png',
|
|
};
|
|
},
|
|
|
|
onShareTimeline() {
|
|
return {
|
|
title: '涂鸦丫 - 快来生成宝宝的专属学习卡',
|
|
query: '',
|
|
};
|
|
},
|
|
});
|