From 1d1780081ee85ecc040e05a4ba18a4aa368c1490 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 7 Jan 2024 14:21:19 +0900
Subject: [PATCH] =?UTF-8?q?enhance(frontend):=20=E3=82=B2=E3=83=BC?=
 =?UTF-8?q?=E3=83=A0=E3=81=AE=E3=82=B7=E3=82=A7=E3=82=A2=E6=A9=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../frontend/src/pages/drop-and-fusion.vue    | 44 +++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/packages/frontend/src/pages/drop-and-fusion.vue b/packages/frontend/src/pages/drop-and-fusion.vue
index 7f41be4c58..71d3f06192 100644
--- a/packages/frontend/src/pages/drop-and-fusion.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.vue
@@ -74,6 +74,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<div v-if="gameOver" :class="$style.gameOverLabel">
 						<div>GAME OVER!</div>
 						<div>SCORE: <MkNumber :value="score"/></div>
+						<MkButton primary rounded inline @click="share">Share</MkButton>
 					</div>
 				</div>
 			</div>
@@ -103,6 +104,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 import * as Matter from 'matter-js';
 import { Ref, onMounted, ref, shallowRef } from 'vue';
 import { EventEmitter } from 'eventemitter3';
+import * as Misskey from 'misskey-js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import * as sound from '@/scripts/sound.js';
 import MkRippleEffect from '@/components/MkRippleEffect.vue';
@@ -115,6 +117,8 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
 import { i18n } from '@/i18n.js';
 import { useInterval } from '@/scripts/use-interval.js';
 import MkSelect from '@/components/MkSelect.vue';
+import { apiUrl } from '@/config.js';
+import { $i } from '@/account.js';
 
 type Mono = {
 	id: string;
@@ -788,6 +792,46 @@ async function start() {
 	game.start();
 }
 
+function getGameImageDriveFile() {
+	return new Promise<Misskey.entities.DriveFile | null>(res => {
+		canvasEl.value?.toBlob(blob => {
+			if (!blob) return res(null);
+			if ($i == null) return res(null);
+			const formData = new FormData();
+			formData.append('file', blob);
+			formData.append('name', `bubble-game-${Date.now()}.png`);
+			formData.append('isSensitive', 'false');
+			formData.append('comment', 'null');
+			formData.append('i', $i.token);
+			if (defaultStore.state.uploadFolder) {
+				formData.append('folderId', defaultStore.state.uploadFolder);
+			}
+
+			window.fetch(apiUrl + '/drive/files/create', {
+				method: 'POST',
+				body: formData,
+			})
+				.then(response => response.json())
+				.then(f => {
+					res(f);
+				});
+		}, 'image/png');
+	});
+}
+
+async function share() {
+	const uploading = getGameImageDriveFile();
+	os.promiseDialog(uploading);
+	const file = await uploading;
+	if (!file) return;
+	os.post({
+		initialText: `#BubbleGame
+MODE: ${gameMode.value}
+SCORE: ${score.value}`,
+		initialFiles: [file],
+	});
+}
+
 useInterval(() => {
 	if (!canvasEl.value) return;
 	const actualCanvasWidth = canvasEl.value.getBoundingClientRect().width;