From 60d9bb02182376a41a751fc8bf09547e30fc3470 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Mon, 16 Jan 2023 10:31:30 +0900
Subject: [PATCH] enhance(client): add timeline flash preset

---
 packages/frontend/src/components/MkAsUi.vue   |   2 +-
 .../frontend/src/pages/flash/flash-edit.vue   | 112 ++++++++++++++----
 packages/frontend/src/scripts/aiscript/ui.ts  |   4 +
 3 files changed, 93 insertions(+), 25 deletions(-)

diff --git a/packages/frontend/src/components/MkAsUi.vue b/packages/frontend/src/components/MkAsUi.vue
index 6aaf2f956..cbdf92453 100644
--- a/packages/frontend/src/components/MkAsUi.vue
+++ b/packages/frontend/src/components/MkAsUi.vue
@@ -6,7 +6,7 @@
 		</template>
 	</div>
 	<span v-else-if="c.type === 'text'" :class="{ [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace' }" :style="{ fontSize: c.size ? `${c.size * 100}%` : null, fontWeight: c.bold ? 'bold' : null, color: c.color ?? null }">{{ c.text }}</span>
-	<Mfm v-else-if="c.type === 'mfm'" :class="{ [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace' }" :style="{ fontSize: c.size ? `${c.size * 100}%` : null, color: c.color ?? null }" :text="c.text"/>
+	<Mfm v-else-if="c.type === 'mfm'" :class="{ [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace' }" :style="{ fontSize: c.size ? `${c.size * 100}%` : null, fontWeight: c.bold ? 'bold' : null, color: c.color ?? null }" :text="c.text"/>
 	<MkButton v-else-if="c.type === 'button'" :primary="c.primary" :rounded="c.rounded" :small="size === 'small'" @click="c.onClick">{{ c.text }}</MkButton>
 	<div v-else-if="c.type === 'buttons'" class="_buttons">
 		<MkButton v-for="button in c.buttons" :primary="button.primary" :rounded="button.rounded" :small="size === 'small'" @click="button.onClick">{{ button.text }}</MkButton>
diff --git a/packages/frontend/src/pages/flash/flash-edit.vue b/packages/frontend/src/pages/flash/flash-edit.vue
index 48cb0f5cf..5ba226c10 100644
--- a/packages/frontend/src/pages/flash/flash-edit.vue
+++ b/packages/frontend/src/pages/flash/flash-edit.vue
@@ -33,24 +33,7 @@ import MkTextarea from '@/components/MkTextarea.vue';
 import MkInput from '@/components/MkInput.vue';
 import { useRouter } from '@/router';
 
-const router = useRouter();
-
-const props = defineProps<{
-	id?: string;
-}>();
-
-let flash = $ref(null);
-
-if (props.id) {
-	flash = await os.api('flash/show', {
-		flashId: props.id,
-	});
-}
-
-let title = $ref(flash?.title ?? 'New Play');
-let summary = $ref(flash?.summary ?? '');
-let permissions = $ref(flash?.permissions ?? []);
-let script = $ref(flash?.script ?? `/// @ 0.12.2
+const PRESET_DEFAULT = `/// @ 0.12.2
 
 var name = ""
 
@@ -66,13 +49,9 @@ Ui:render([
 		}
 	})
 ])
-`);
+`;
 
-function selectPreset(ev: MouseEvent) {
-	os.popupMenu([{
-		text: 'Omikuji',
-		action: () => {
-			script = `/// @ 0.12.2
+const PRESET_OMIKUJI = `/// @ 0.12.2
 // ユーザーごとに日替わりのおみくじのプリセット
 
 // 選択肢
@@ -114,6 +93,91 @@ Ui:render([
 	})
 ])
 `;
+
+const PRESET_TIMELINE = `/// @ 0.12.2
+// APIリクエストを行いローカルタイムラインを表示するプリセット
+
+@fetch() {
+	Ui:render([
+		Ui:C:container({
+			align: 'center'
+			children: [
+				Ui:C:text({ text: "読み込み中..." })
+			]
+		})
+	])
+
+	// タイムライン取得
+	let notes = Mk:api("notes/local-timeline" {})
+
+	// それぞれのノートごとにUI要素作成
+	let noteEls = []
+	each (let note, notes) {
+		let el = Ui:C:container({
+			bgColor: "#444"
+			fgColor: "#fff"
+			padding: 10
+			rounded: true
+			children: [
+				Ui:C:mfm({
+					text: note.user.name
+					bold: true
+				})
+				Ui:C:mfm({
+					text: note.text
+				})
+			]
+		})
+		noteEls.push(el)
+	}
+
+	// UIを表示
+	Ui:render([
+		Ui:C:text({ text: "ローカル タイムライン" })
+		Ui:C:button({
+			text: "更新"
+			onClick: @() {
+				fetch()
+			}
+		})
+		Ui:C:container({
+			children: noteEls
+		})
+	])
+}
+
+fetch()
+`;
+
+const router = useRouter();
+
+const props = defineProps<{
+	id?: string;
+}>();
+
+let flash = $ref(null);
+
+if (props.id) {
+	flash = await os.api('flash/show', {
+		flashId: props.id,
+	});
+}
+
+let title = $ref(flash?.title ?? 'New Play');
+let summary = $ref(flash?.summary ?? '');
+let permissions = $ref(flash?.permissions ?? []);
+let script = $ref(flash?.script ?? PRESET_DEFAULT);
+
+function selectPreset(ev: MouseEvent) {
+	os.popupMenu([{
+		text: 'Omikuji',
+		action: () => {
+			script = PRESET_OMIKUJI;
+		},
+	}, {
+		text: 'Timeline viewer',
+		action: () => {
+			script = PRESET_TIMELINE;
 		},
 	}], ev.currentTarget ?? ev.target);
 }
diff --git a/packages/frontend/src/scripts/aiscript/ui.ts b/packages/frontend/src/scripts/aiscript/ui.ts
index 6e0e31211..2555cd391 100644
--- a/packages/frontend/src/scripts/aiscript/ui.ts
+++ b/packages/frontend/src/scripts/aiscript/ui.ts
@@ -39,6 +39,7 @@ export type AsUiMfm = AsUiComponentBase & {
 	type: 'mfm';
 	text?: string;
 	size?: number;
+	bold?: boolean;
 	color?: string;
 	font?: 'serif' | 'sans-serif' | 'monospace';
 };
@@ -208,6 +209,8 @@ function getMfmOptions(def: values.Value | undefined): Omit<AsUiMfm, 'id' | 'typ
 	if (text) utils.assertString(text);
 	const size = def.value.get('size');
 	if (size) utils.assertNumber(size);
+	const bold = def.value.get('bold');
+	if (bold) utils.assertBoolean(bold);
 	const color = def.value.get('color');
 	if (color) utils.assertString(color);
 	const font = def.value.get('font');
@@ -216,6 +219,7 @@ function getMfmOptions(def: values.Value | undefined): Omit<AsUiMfm, 'id' | 'typ
 	return {
 		text: text?.value,
 		size: size?.value,
+		bold: bold?.value,
 		color: color?.value,
 		font: font?.value,
 	};