mod.ts/** 一度取得したTaskを貯めておく場所
*
* reloadでresetされる
*/
const tasks: {
project: string;
title: string;
task: Task;
}[] = [];
async function load(projects: string[]) {
scrapbox.PageMenu(id).removeAllItems();
loading = true;
// 再読み込み用
scrapbox.PageMenu(id).addItem({
title: "Reload",
onClick: () => {
if (loading) return;
load(projects);
},
});
// コピペ用
scrapbox.PageMenu(id).addItem({
title: "Copy missed and today actions",
onClick: async () => {
const today = new Date();
const titles = tasks.map(({ task, title }) => {
const category = classify(task, today);
return { category, title };
});
const text = [
"今日やること",
...titles.flatMap(
({ category, title }) => category === "today" ? [` [${title}]`] : []
),
"",
"やり残していること",
...titles.flatMap(
({ category, title }) => category === "missed" ? [` [${title}]`] : []
),
"",
].join("\n");
try {
await navigator.clipboard.writeText(text);
} catch(e: unknown) {
if (!(e instanceof Error)) throw e;
console.error(e);
alert(`${e.name} ${e.message}`);
}
},
});
const buttons: [string, string, Category][] = [
["Copy tomorrow actions", "明日やること", "tomorrow"],
["Copy this week actions", "今週やること", "in week"],
["Copy next week actions", "来週やること", "in next week"],
["Copy this month actions", "今月やること", "in month"],
["Copy next month actions", "来月やること", "in next month"],
["Copy this year actions", "今年やること", "in year"],
["Copy next year actions", "来年やること", "in next year"],
["Copy someday actions", "いつかやること", "someday"],
["Copy no period actions", "時間情報なし", "no startAt"],
]
for (const [button, section, cat] of buttons) {
scrapbox.PageMenu(id).addItem({
title: button,
onClick: async () => {
const today = new Date();
const titles = tasks.map(({ task, title }) => {
const category = classify(task, today);
return { category, title };
});
const text = [
section,
...titles.flatMap(
({ category, title }) => category === cat ? [` [${title}]`] : []
),
"",
].join("\n");
try {
await navigator.clipboard.writeText(text);
} catch(e: unknown) {
if (!(e instanceof Error)) throw e;
console.error(e);
alert(`${e.name} ${e.message}`);
}
},
});
}
const { render, dispose } = useStatusBar();
try {
const titleLcs = new Set<string>(); // 重複除外用
const today = new Date();
for (const project of projects) {
render(
{ type: "spinner" },
{ type: "text", text: `Searching "/${project}" for next actions...`},
);
for await (const { task, title } of list(project)) {
const titleLc = toTitleLc(title);
if (titleLcs.has(titleLc)) continue;
titleLcs.add(titleLc);
if (task.status === "✅") continue;
if (task.status === "❌") continue;
tasks.push({ project, title, task });
const category = classify(task, today);
if (
category !== "missed" &&
category !== "today"
) continue;
scrapbox.PageMenu(id).addItem({
title,
onClick: () => {
if (project !== scrapbox.Project.name) {
const path = `https://scrapbox.io/${
project
}/${encodeTitleURI(title)}`;
window.open(path);
return;
}
openInTheSameTab(project, title);
},
});
}
if (project === projects[projects.length - 1]) continue;
scrapbox.PageMenu(id).addSeparator();
}
render(
{ type: "check-circle" },
{ type: "text", text: `Found actions.`},
);
} catch(e: unknown) {
render(
{ type: "exclamation-triangle" },
{ type: "text", text: e instanceof Error ?
`${e.name} ${e.message}` :
`Unknown error! (see developper console)`,
},
);
console.error(e);
} finally {
loading = false;
setTimeout(() => dispose(), 1000);
}
}