Skip to content
Merged
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: 6 additions & 3 deletions src/app/api/index/plot/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NextResponse } from "next/server";
import { type Hex, decodeEventLog, encodeEventTopics } from "viem";
import { publicClient, getReceiptWithRetry } from "../../../../../lib/rpc";

Check warning on line 3 in src/app/api/index/plot/route.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

'getReceiptWithRetry' is defined but never used
import { createServerClient } from "../../../../../lib/supabase";
import { validateRecentTx } from "../../../../../lib/index-auth";
import {
Expand Down Expand Up @@ -117,17 +117,20 @@
const DEADLINE_MS = 168 * 60 * 60 * 1000; // 7 days — matches DEADLINE_HOURS in DeadlineCountdown
const { data: storylineRow } = await supabase
.from("storylines")
.select("last_plot_time, sunset")
.select("last_plot_time, sunset, has_deadline")
.eq("storyline_id", Number(storylineId))
.single();

if (storylineRow) {
if (storylineRow.sunset) {
return error("Storyline has sunset — no new plots allowed", 400);
}
if (storylineRow.last_plot_time) {
if (storylineRow.has_deadline && storylineRow.last_plot_time) {
const deadline = new Date(storylineRow.last_plot_time).getTime() + DEADLINE_MS;
if (Date.now() > deadline) {
// Use block timestamp (when tx was mined) instead of Date.now() to avoid
// rejecting plots that the contract already accepted near the deadline edge
const blockTimeMs = Number(blockTimestamp) * 1000;
if (blockTimeMs > deadline) {
return error("Storyline deadline expired — no new plots allowed", 400);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/app/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ async function fetchWriterStorylines(address: string): Promise<Storyline[]> {

function isStorylineExpired(s: Storyline): boolean {
if (s.sunset) return true;
if (!s.has_deadline) return false;
if (!s.last_plot_time) return false;
return Date.now() > new Date(s.last_plot_time).getTime() + DEADLINE_MS;
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/story/[storylineId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ function StoryHeader({
)}
</div>
</div>
<AddPlotButton storylineId={storyline.storyline_id} writerAddress={storyline.writer_address} lastPlotTime={storyline.last_plot_time} sunset={storyline.sunset} />
<AddPlotButton storylineId={storyline.storyline_id} writerAddress={storyline.writer_address} lastPlotTime={storyline.last_plot_time} sunset={storyline.sunset} hasDeadline={storyline.has_deadline} />
</header>
);
}
Expand Down
8 changes: 5 additions & 3 deletions src/components/AddPlotButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,27 @@ export function AddPlotButton({
writerAddress,
lastPlotTime,
sunset,
hasDeadline,
}: {
storylineId: number;
writerAddress: string;
lastPlotTime?: string | null;
sunset?: boolean;
hasDeadline?: boolean;
}) {
const { address } = useAccount();
if (!address || address.toLowerCase() !== writerAddress.toLowerCase())
return null;

const expired = sunset || (lastPlotTime ? isDeadlineExpired(lastPlotTime) : false);
const expired = sunset || (hasDeadline !== false && lastPlotTime ? isDeadlineExpired(lastPlotTime) : false);

if (expired) {
return (
<div
className="border-border text-muted mt-3 block w-full rounded border py-2 text-center text-xs font-medium opacity-50"
title="The 7-day deadline has expired"
title={sunset ? "This story has sunset" : "The 7-day deadline has expired"}
>
Deadline expired
{sunset ? "Story complete" : "Deadline expired"}
</div>
);
}
Expand Down
Loading