feat: add WatchMedium field, general review editing, configurable deploy
Some checks failed
CI / Check / Test (push) Failing after 27m0s
Some checks failed
CI / Check / Test (push) Failing after 27m0s
- WatchMedium enum (cinema/streaming/tv/physical_media/download/media_server/other) - PATCH /api/v1/reviews/:id partial update (rating, comment, watched_at, watch_medium) - edit_review use case w/ ownership + remote review guard, best-effort AP Update broadcast - SPA: icon picker, edit sheet (long-press mobile / pencil desktop), watch medium badge - shared ReviewFormFields, EditableContextMenu, parse_watched_at/format_watched_at - deploy.sh parameterized (--features, --tag), CORS allows PATCH - CONTEXT.md glossary, ADR-0001 general review editing
This commit is contained in:
@@ -157,6 +157,17 @@ export async function putForm<T = void>(
|
||||
})
|
||||
}
|
||||
|
||||
export async function patch<T = void>(
|
||||
path: string,
|
||||
body?: unknown,
|
||||
): Promise<T> {
|
||||
return request<T>(buildUrl(path), {
|
||||
method: "PATCH",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
})
|
||||
}
|
||||
|
||||
export async function del<T = void>(path: string): Promise<T> {
|
||||
return request<T>(buildUrl(path), { method: "DELETE" })
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ export const reviewDtoSchema = z.object({
|
||||
rating: z.number(),
|
||||
comment: z.string().optional(),
|
||||
watched_at: z.string(),
|
||||
watch_medium: z.string().optional(),
|
||||
})
|
||||
export type ReviewDto = z.infer<typeof reviewDtoSchema>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { z } from "zod"
|
||||
import type { DiaryEntryDto, Paginated } from "./common"
|
||||
import { diaryEntryDtoSchema, movieDtoSchema, paginatedSchema, reviewDtoSchema } from "./common"
|
||||
import { del, get, post } from "./client"
|
||||
import { del, get, patch, post } from "./client"
|
||||
|
||||
export const diaryQueryParamsSchema = z.object({
|
||||
limit: z.number().optional(),
|
||||
@@ -22,9 +22,18 @@ export const logReviewRequestSchema = z.object({
|
||||
rating: z.number(),
|
||||
comment: z.string().optional(),
|
||||
watched_at: z.string(),
|
||||
watch_medium: z.string().optional(),
|
||||
})
|
||||
export type LogReviewRequest = z.infer<typeof logReviewRequestSchema>
|
||||
|
||||
export const editReviewRequestSchema = z.object({
|
||||
rating: z.number().optional(),
|
||||
comment: z.string().nullable().optional(),
|
||||
watched_at: z.string().optional(),
|
||||
watch_medium: z.string().nullable().optional(),
|
||||
})
|
||||
export type EditReviewRequest = z.infer<typeof editReviewRequestSchema>
|
||||
|
||||
export const feedEntryDtoSchema = z.object({
|
||||
movie: movieDtoSchema,
|
||||
review: reviewDtoSchema,
|
||||
@@ -58,6 +67,10 @@ export function logReview(data: LogReviewRequest) {
|
||||
return post("/reviews", data)
|
||||
}
|
||||
|
||||
export function editReview(id: string, data: EditReviewRequest) {
|
||||
return patch(`/reviews/${id}`, data)
|
||||
}
|
||||
|
||||
export function deleteReview(id: string) {
|
||||
return del(`/reviews/${id}`)
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ export const socialReviewDtoSchema = z.object({
|
||||
comment: z.string().optional(),
|
||||
watched_at: z.string(),
|
||||
is_federated: z.boolean(),
|
||||
watch_medium: z.string().optional(),
|
||||
})
|
||||
export type SocialReviewDto = z.infer<typeof socialReviewDtoSchema>
|
||||
|
||||
|
||||
26
spa/src/lib/watch-mediums.ts
Normal file
26
spa/src/lib/watch-mediums.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { LucideIcon } from "lucide-react"
|
||||
import {
|
||||
Clapperboard,
|
||||
Tv,
|
||||
Radio,
|
||||
Disc3,
|
||||
Download,
|
||||
Server,
|
||||
Ellipsis,
|
||||
} from "lucide-react"
|
||||
|
||||
export type WatchMediumDef = {
|
||||
value: string
|
||||
icon: LucideIcon
|
||||
labelKey: string
|
||||
}
|
||||
|
||||
export const WATCH_MEDIUMS: WatchMediumDef[] = [
|
||||
{ value: "cinema", icon: Clapperboard, labelKey: "watchMedium.cinema" },
|
||||
{ value: "streaming", icon: Tv, labelKey: "watchMedium.streaming" },
|
||||
{ value: "tv", icon: Radio, labelKey: "watchMedium.tv" },
|
||||
{ value: "physical_media", icon: Disc3, labelKey: "watchMedium.physicalMedia" },
|
||||
{ value: "download", icon: Download, labelKey: "watchMedium.download" },
|
||||
{ value: "media_server", icon: Server, labelKey: "watchMedium.mediaServer" },
|
||||
{ value: "other", icon: Ellipsis, labelKey: "watchMedium.other" },
|
||||
]
|
||||
Reference in New Issue
Block a user