Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions prisma/migrations/20251109055509_add_board_name/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- CreateTable
CREATE TABLE "BoardState" (
"id" SERIAL NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"boardData" JSONB NOT NULL,
"boardName" TEXT NOT NULL,

CONSTRAINT "BoardState_pkey" PRIMARY KEY ("id")
);
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ model BoardState {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
boardData Json
boardName String
}
4 changes: 0 additions & 4 deletions src/iframe/life-game.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@
"
>
<table id="game-board" style="border-collapse: collapse"></table>

<button id="saveButton">SAVE</button>
<button id="loadButton">LOAD</button>

<script src="./life-game.js"></script>
</body>
</html>
15 changes: 5 additions & 10 deletions src/iframe/life-game.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,6 @@ on.pause = () => {
clearInterval(timerId);
};

on.load_board = (boardTemplate) => {
board = boardTemplate;
};

on.resize = (newBoardSize) => {
boardSize = newBoardSize;
};
Expand Down Expand Up @@ -191,18 +187,17 @@ on.stateupdate = () => {

on.sizechange(boardSize);

saveButton.onclick = async () => {
on.save_board = async () => {
window.parent.postMessage({ type: "save_board", data: board }, "*");
};

loadButton.onclick = async () => {
on.load_board = async () => {
window.parent.postMessage({ type: "request:load_board" }, "*");
};

on.load_board = (loadedBoard) => {
console.log("on.load_board");
board = loadedBoard;
on.apply_board = (newBoard) => {
board = newBoard;
renderBoard();
generationChange(0);
stop();
on.pause();
};
64 changes: 58 additions & 6 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
let generationFigure = $state(0);
let sizeInputValue = $state(20);

let saveModalOpen = $state(false);
let boardNameInput = $state("");
let boardToSave: boolean[][] | undefined = $state(undefined);

onMount(() => {
const handleMessage = (event: MessageEvent) => {
if (event.data.type === "patternError") {
Expand Down Expand Up @@ -60,22 +64,20 @@

onMount(() => {
const handler = async (event: MessageEvent<unknown>) => {
console.log("handler call");
const data = event.data as
| { type: "unknown event" }
| { type: "save_board"; data: boolean[][] }
| { type: "request:load_board" };
if (data.type === "save_board") {
console.log("board saved!");
await saveBoard(data.data);
boardToSave = data.data;
saveModalOpen = true;
return;
}

if (data.type === "request:load_board") {
console.log("loaded board");
const board = await loadBoard();
if (board) {
sendEvent("load_board", board);
sendEvent("apply_board", board);
}
return;
}
Expand All @@ -84,6 +86,18 @@
window.addEventListener("message", handler);
return () => window.removeEventListener("message", handler);
});

async function handleSave() {
if (!boardToSave) return;

const name = boardNameInput.trim() === "" ? "Unnamed Board" : boardNameInput.trim();

await saveBoard({ board: boardToSave, name: name });

saveModalOpen = false;
boardNameInput = "";
boardToSave = undefined;
}
</script>

<div class="navbar bg-[#E0E0E0] shadow-sm">
Expand Down Expand Up @@ -146,6 +160,24 @@
</div>
</div>

<input type="checkbox" class="modal-toggle" bind:checked={saveModalOpen} />
<div class="modal" class:modal-open={saveModalOpen}>
<div class="modal-box">
<h3 class="font-bold text-lg">盤面を保存</h3>
<p class="py-4">保存する盤面に名前を付けてください(任意)。</p>
<input
type="text"
placeholder="盤面名を入力"
class="input input-bordered w-full max-w-xs"
bind:value={boardNameInput}
/>
<div class="modal-action">
<button class="btn" onclick={() => (saveModalOpen = false)}>キャンセル</button>
<button class="btn btn-primary" onclick={handleSave} disabled={!boardToSave}> 保存 </button>
</div>
</div>
</div>

<input type="checkbox" class="modal-toggle" bind:checked={resetModalOpen} />
<div class="modal" class:modal-open={resetModalOpen}>
<div class="modal-box">
Expand Down Expand Up @@ -255,7 +287,7 @@
</div>

<button
class="btn btn-ghost hover:bg-[rgb(220,220,220)] ml-100 text-black"
class="btn btn-ghost hover:bg-[rgb(220,220,220)] ml-50 text-black"
onclick={() => {
isProgress = false;
sendEvent("boardreset");
Expand All @@ -274,6 +306,26 @@
Random
</button>

<button
class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black"
onclick={() => {
isProgress = false;
sendEvent("save_board");
}}
>
Save
</button>

<button
class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black"
onclick={() => {
isProgress = false;
sendEvent("load_board");
}}
>
Load
</button>

<button
class="btn btn-ghost hover:bg-[rgb(220,220,220)] ml-5 text-black"
onclick={() => {
Expand Down
5 changes: 2 additions & 3 deletions src/routes/api.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export async function saveBoard(board: boolean[][]) {
export async function saveBoard(data: { board: boolean[][]; name: string }) {
try {
const response = await fetch("/api/board", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(board),
body: JSON.stringify(data),
});

if (!response.ok) {
Expand Down Expand Up @@ -33,7 +33,6 @@ export async function loadBoard(): Promise<boolean[][] | undefined> {

const loadedBoard = await response.json();

console.log("fetched board:", loadedBoard);
return loadedBoard as boolean[][]; // TODO: add proper types
} catch (err) {
console.error("読込エラー:", err);
Expand Down
5 changes: 3 additions & 2 deletions src/routes/api/board/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { json } from "@sveltejs/kit";
import { prisma } from "@/lib/prisma.server.ts";

export async function POST({ request }) {
const boardData = await request.json();
const { board, name } = await request.json();

const newState = await prisma.boardState.create({
data: {
boardData: boardData,
boardData: board,
boardName: name,
},
});

Expand Down
Loading