import type { BlockClientInstance, BlockImplInstance, } from '@toeverything/datasource/jwt'; import { getDateIsoStringWithTimezone } from '@toeverything/utils'; import getDaysInMonth from 'date-fns/getDaysInMonth'; import color, { ColorInput } from 'tinycolor2'; import type { Theme, CalendarDay } from './types'; // export const DEFAULT_THEME = createCalendarTheme('#3E6FDB'); export const DEFAULT_THEME: Theme = { level4: '#3E6FDB', level3: 'rgba(62, 111, 219)', level2: 'rgba(62, 111, 219, 0.5)', level1: 'rgba(62, 111, 219, 0.2)', }; export function createCalendarTheme( baseColor: ColorInput, emptyColor = color('white').darken(8).toHslString() ): Theme { const base = color(baseColor); if (!base.isValid()) { return DEFAULT_THEME; } return { level4: base.setAlpha(0.92).toHslString(), level3: base.setAlpha(0.76).toHslString(), level2: base.setAlpha(0.6).toHslString(), level1: base.setAlpha(0.44).toHslString(), // level0: emptyColor }; } function getRandomNumber(min: number, max: number) { return Math.round(Math.random() * (max - min) + min); } export async function fetchActivitiesHeatmap( db: BlockClientInstance, date: Date, flattenedItems: any[] ): Promise<{ daysToHighlight: CalendarDay[] }> { // const pages = await db.getByType('page'); const pages_with_ids = (await Promise.all( flattenedItems.map(async (page_item: any) => { const page_id = page_item.id; return [page_id, await db.get(page_id as 'page')]; }) )) as [string, BlockImplInstance][]; const pages = new Map(pages_with_ids); const blocks = pages.values(); const pages_by_month = {} as Record; for (const page of blocks) { const page_created_month = getDateIsoStringWithTimezone( page.created ).slice(0, 7); if (!pages_by_month[page_created_month]) { pages_by_month[page_created_month] = [page]; } else { pages_by_month[page_created_month].push(page); } } const result_date_key = getDateIsoStringWithTimezone(date.getTime()).slice( 0, 7 ); if (!pages_by_month[result_date_key]) { return { daysToHighlight: [] }; } const pages_by_day = {} as Record; const daysToHighlight = [] as CalendarDay[]; pages_by_month[result_date_key].forEach(page => { const page_created_date = new Date(page.created).getDate(); if (!pages_by_day[page_created_date]) { pages_by_day[page_created_date] = [page]; } else { pages_by_day[page_created_date].push(page); } }); Object.keys(pages_by_day).forEach(day => { daysToHighlight.push({ dayInMonth: Number(day), activitiesOfDay: pages_by_day[day].length, }); }); return { daysToHighlight }; } export async function fakeFetch( date: Date, { signal }: { signal?: AbortSignal } = {} ): Promise<{ daysToHighlight: CalendarDay[] }> { return new Promise((resolve, reject) => { // const timeout = setTimeout(() => { const daysInMonth = getDaysInMonth(date); const daysToHighlight = Array(7) .fill(1) .map(() => { const countOfDay = getRandomNumber(1, daysInMonth); return { dayInMonth: countOfDay, activitiesOfDay: countOfDay, }; }); resolve({ daysToHighlight }); // }, 0); if (signal) { signal.onabort = () => { // clearTimeout(timeout); reject(new DOMException('aborted', 'AbortError')); }; } }); }