diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 1b9c7ec..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,29 +0,0 @@
-FROM oven/bun:1 AS base
-WORKDIR /usr/src/app
-
-# Installe les dépendances de développement.
-FROM base AS install
-RUN mkdir -p /temp/dev
-COPY package.json bun.lock /temp/dev/
-RUN cd /temp/dev && bun install --frozen-lockfile
-# Installe les dépendances de production.
-RUN mkdir -p /temp/prod
-COPY package.json bun.lock /temp/prod/
-RUN cd /temp/prod && bun install --frozen-lockfile --production
-
-# Récupère node_modules et les fichiers du projet.
-FROM base AS prerelease
-COPY --from=install /temp/dev/node_modules/ node_modules
-COPY . .
-# Compile le projet.
-ENV NODE_ENV=production
-RUN bun --bun vite build
-
-# Créé le nécessaire pour Angie, le proxy inversé servant l'application.
-FROM docker.angie.software/angie:minimal AS release
-COPY --from=prerelease /usr/src/app/dist/ /usr/share/angie/html/
-COPY ./docker/default.conf /etc/angie/http.d/default.conf
-
-# Démarre Angie.
-EXPOSE 80
-CMD ["angie", "-g", "daemon off;"]
diff --git a/bun.lock b/bun.lock
index 6f92dbf..a448063 100644
--- a/bun.lock
+++ b/bun.lock
@@ -213,11 +213,11 @@
"@effect/experimental": ["@effect/experimental@0.41.4", "", { "dependencies": { "msgpackr": "^1.10.2", "uuid": "^11.0.3" }, "peerDependencies": { "@effect/platform": "^0.77.4", "@effect/platform-node": "^0.73.4", "effect": "^3.13.4", "ioredis": "^5", "lmdb": "^3", "ws": "^8" }, "optionalPeers": ["@effect/platform-node", "ioredis", "lmdb", "ws"] }, "sha512-celrEhl/K2Eis906d3/oOv/3/w+M1jcONvrChG5qQgWYo6CJjSJm4xXopcTbiBhxAhvkd06zABkB3tr/lptUCA=="],
- "@effect/platform": ["@effect/platform@0.77.4", "", { "dependencies": { "find-my-way-ts": "^0.1.5", "multipasta": "^0.2.5" }, "peerDependencies": { "effect": "^3.13.4" } }, "sha512-3jBDn4bAWqRSKARmoMY2NmMxIMM5Py5BqJdUuYJqPyI6jbz7qkOMwgeaF62rWqiqhQLHLTgU4QL/cPwyZl7mVg=="],
+ "@effect/platform": ["@effect/platform@0.77.6", "", { "dependencies": { "find-my-way-ts": "^0.1.5", "multipasta": "^0.2.5" }, "peerDependencies": { "effect": "^3.13.6" } }, "sha512-ghhLNyj/UoQvmp2I29nqngMlAzQB72BhjUKcOA58cUPaUUwNy3K2jmUAzdU6SB3RHIObsX44CM/jXZiYfTv59A=="],
"@effect/sql": ["@effect/sql@0.30.4", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.25.1", "uuid": "^11.0.3" }, "peerDependencies": { "@effect/experimental": "^0.41.4", "@effect/platform": "^0.77.4", "effect": "^3.13.4" } }, "sha512-hyGOZsNRlw09yqBcXCTr1o2+vVIVxEnBMNZzi0ZX5JbS8JBT05O7xAu3OYEzSU6bC5i+uVpJJUgdx2zDlOLkeA=="],
- "@effect/sql-drizzle": ["@effect/sql-drizzle@0.29.4", "", { "peerDependencies": { "@effect/sql": "^0.30.4", "drizzle-orm": "^0.31", "effect": "^3.13.4" } }, "sha512-Hz8RypUu5g/V3DVmD0WLK+Nqy9H/V/GA2ew41sSZhJ0fTmxaCoQ08it23qypeNN66CCJNF5uE9OWnHl10cfKGA=="],
+ "@effect/sql-drizzle": ["@effect/sql-drizzle@0.29.6", "", { "peerDependencies": { "@effect/sql": "^0.30.6", "drizzle-orm": "^0.31", "effect": "^3.13.6" } }, "sha512-ST3HEXQZfp9tUXKOKxpfh9bbTukJsomyXXzZLvPo/KvF8nPpRltovYNT55Dsk+0vN8JyOHri+mX8hKBG5JzXcA=="],
"@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "~0.18.20", "source-map-support": "^0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="],
@@ -623,7 +623,7 @@
"easy-table": ["easy-table@1.2.0", "", { "dependencies": { "ansi-regex": "^5.0.1" }, "optionalDependencies": { "wcwidth": "^1.0.1" } }, "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww=="],
- "effect": ["effect@3.13.4", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-XZgCImyBpONuKdsBRk37JfV7242yxTu8r/TcL5ZELIyqRbMYa+Prr86cz1INxXi7iFXfU0havZkCJGyYp1BsiA=="],
+ "effect": ["effect@3.13.6", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-NKmzyIuOb2UuHFPRz9EYScbhMBxXkzjPRuu+4axE+hMk1f0U7TZxzi2CP3TVVxA2kzvh00aBQEbyH7Opq4PnWg=="],
"electron-to-chromium": ["electron-to-chromium@1.5.109", "", {}, "sha512-AidaH9JETVRr9DIPGfp1kAarm/W6hRJTPuCnkF+2MqhF4KaAgRIcBc8nvjk+YMXZhwfISof/7WG29eS4iGxQLQ=="],
@@ -649,7 +649,7 @@
"eslint-plugin-perfectionist": ["eslint-plugin-perfectionist@4.9.0", "", { "dependencies": { "@typescript-eslint/types": "^8.24.0", "@typescript-eslint/utils": "^8.24.0", "natural-orderby": "^5.0.0" }, "peerDependencies": { "eslint": ">=8.0.0" } }, "sha512-76lDfJnonOcXGW3bEXuqhEGId0LrOlvIE1yLHvK/eKMMPOc0b43KchAIR2Bdbqlg+LPXU5/Q+UzuzkO+cWHT6w=="],
- "eslint-plugin-vue": ["eslint-plugin-vue@9.32.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "globals": "^13.24.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.15", "semver": "^7.6.3", "vue-eslint-parser": "^9.4.3", "xml-name-validator": "^4.0.0" }, "peerDependencies": { "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, "sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug=="],
+ "eslint-plugin-vue": ["eslint-plugin-vue@10.0.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.15", "semver": "^7.6.3", "xml-name-validator": "^4.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "vue-eslint-parser": "^10.0.0" } }, "sha512-XKckedtajqwmaX6u1VnECmZ6xJt+YvlmMzBPZd+/sI3ub2lpYZyFnsyWo7c3nMOQKJQudeyk1lw/JxdgeKT64w=="],
"eslint-scope": ["eslint-scope@8.2.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A=="],
@@ -1037,8 +1037,6 @@
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
- "type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="],
-
"typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="],
"typescript-eslint": ["typescript-eslint@8.25.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.25.0", "@typescript-eslint/parser": "8.25.0", "@typescript-eslint/utils": "8.25.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-TxRdQQLH4g7JkoFlYG3caW5v1S6kEkz8rqt80iQJZUYPq1zD1Ra7HfQBJJ88ABRaMvHAXnwRvRB4V+6sQ9xN5Q=="],
@@ -1129,8 +1127,6 @@
"eslint/file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
- "eslint-plugin-vue/globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="],
-
"fast-glob/@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
diff --git a/containers/Dockerfile b/containers/Dockerfile
new file mode 100644
index 0000000..073334f
--- /dev/null
+++ b/containers/Dockerfile
@@ -0,0 +1,53 @@
+FROM oven/bun:1 AS base
+WORKDIR /usr/src/app
+
+# Définis les variables d'environnement.
+ARG VERSION="0.1"
+
+# Installe les dépendances de développement.
+FROM base AS install
+RUN mkdir -p /temp/dev
+COPY package.json bun.lock /temp/dev/
+RUN cd /temp/dev && bun install --frozen-lockfile
+# Installe les dépendances de production.
+RUN mkdir -p /temp/prod
+COPY package.json bun.lock /temp/prod/
+RUN cd /temp/prod && bun install --frozen-lockfile --production
+
+# Récupère node_modules et les fichiers du projet.
+FROM base AS prerelease
+COPY --from=install /temp/dev/node_modules/ node_modules
+COPY . .
+# Compile le projet.
+ENV NODE_ENV=production
+RUN bun --bun vite build
+
+# Créé le nécessaire pour Angie, le proxy inversé servant l'application.
+FROM docker.angie.software/angie:minimal AS release
+COPY --from=prerelease /usr/src/app/dist/ /usr/share/angie/html/
+COPY containers/angie/default.conf /etc/angie/http.d/default.conf
+
+# Met en place les métadonnées OCI.
+LABEL org.opencontainers.image.title=journal-media-vue \
+ org.opencontainers.image.description="A modern client-server application for the Soulseek file sharing network" \
+ org.opencontainers.image.authors="gcch" \
+ org.opencontainers.image.vendor="gcch" \
+ org.opencontainers.image.licenses=AGPL-3.0
+# org.opencontainers.image.url=https://slskd.org \
+# org.opencontainers.image.source=https://github.com/slskd/slskd \
+# org.opencontainers.image.documentation=https://github.com/slskd/slskd \
+# org.opencontainers.image.version=$VERSION \
+# org.opencontainers.image.revision=$REVISION \
+# org.opencontainers.image.created=$BUILD_DATE
+
+# Démarre Angie.
+EXPOSE 80
+CMD ["angie", "-g", "daemon off;"]
+
+# Met en place une vérification périodique de la bonne santé du conteneur.
+HEALTHCHECK \
+ --interval=60s \
+ --timeout=3s \
+ --start-period=5s \
+ --retries=3 \
+ CMD wget -q -O - http://localhost:80/
diff --git a/docker/default.conf b/containers/angie/default.conf
similarity index 100%
rename from docker/default.conf
rename to containers/angie/default.conf
diff --git a/cspell.json b/cspell.json
index f8a4ff1..5d546ed 100644
--- a/cspell.json
+++ b/cspell.json
@@ -14,6 +14,7 @@
"quartary",
"fieldset",
"tabindex",
- "currentcolor"
+ "currentcolor",
+ "labelledby"
]
}
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 3987542..91eb7f2 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -2,7 +2,7 @@ services:
app:
build:
context: .
- dockerfile: Dockerfile
+ dockerfile: containers/Dockerfile
container_name: journal-media-vue
ports:
- 127.0.0.1:8080:8
diff --git a/package.json b/package.json
index 0beb834..5cdc9fd 100644
--- a/package.json
+++ b/package.json
@@ -4,14 +4,14 @@
"type": "module",
"private": true,
"dependencies": {
- "@effect/platform": "^0.77.4",
- "@effect/sql-drizzle": "^0.29.4",
+ "@effect/platform": "^0.77.6",
+ "@effect/sql-drizzle": "^0.29.6",
"@thi.ng/color-palettes": "^1.4.36",
"@thi.ng/pixel": "^7.3.19",
"@thi.ng/pixel-dither": "^1.1.159",
"a11y-dialog": "^8.1.1",
"drizzle-orm": "^0.40.0",
- "effect": "^3.13.4",
+ "effect": "^3.13.6",
"pinia": "^3.0.1",
"sqlocal": "^0.14.0",
"vue": "^3.5.13",
@@ -29,7 +29,7 @@
"drizzle-kit": "^0.30.5",
"eslint": "^9.21.0",
"eslint-plugin-perfectionist": "^4.9.0",
- "eslint-plugin-vue": "^9.32.0",
+ "eslint-plugin-vue": "^10.0.0",
"globals": "^16.0.0",
"jiti": "^2.4.2",
"knip": "^5.45.0",
diff --git a/src/components/TmdbSearchResults.vue b/src/components/TmdbSearchResults.vue
index 7cac717..fa7d84a 100644
--- a/src/components/TmdbSearchResults.vue
+++ b/src/components/TmdbSearchResults.vue
@@ -90,12 +90,12 @@
tabindex="0" @click="onRowClicked(result[0])" @keypress="onRowClicked(result[0])"
>
- {{ result[1].original_result_index }}
+ {{ result[1].originalResultIndex }}
|
- {{ result[1].original_title }}
+ {{ result[1].originalTitle }}
|
- {{ result[1].release_date }} |
+ {{ result[1].releaseDate }} |
{{ result[1].popularity }} |
diff --git a/src/components/dialogs/EditEntryDialog.vue b/src/components/dialogs/EditEntryDialog.vue
index e99dde0..6c9d12f 100644
--- a/src/components/dialogs/EditEntryDialog.vue
+++ b/src/components/dialogs/EditEntryDialog.vue
@@ -1,37 +1,62 @@
+
+
diff --git a/src/db/drizzle/0000_unusual_karen_page.sql b/src/db/drizzle/0000_goofy_vanisher.sql
similarity index 88%
rename from src/db/drizzle/0000_unusual_karen_page.sql
rename to src/db/drizzle/0000_goofy_vanisher.sql
index 6f5591f..8cc4796 100644
--- a/src/db/drizzle/0000_unusual_karen_page.sql
+++ b/src/db/drizzle/0000_goofy_vanisher.sql
@@ -1,7 +1,10 @@
CREATE TABLE `diary_entries` (
+ `appreciation` text NOT NULL,
`art_work_id` integer NOT NULL,
+ `commentary` text,
`date_created` integer NOT NULL,
`date_modified` integer NOT NULL,
+ `date_obtained` integer NOT NULL,
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`state_id` integer NOT NULL,
FOREIGN KEY (`art_work_id`) REFERENCES `art_works`(`id`) ON UPDATE no action ON DELETE no action,
@@ -59,4 +62,10 @@ CREATE TABLE `media_types` (
);
--> statement-breakpoint
CREATE UNIQUE INDEX `media_types_name_unique` ON `media_types` (`name`);--> statement-breakpoint
-CREATE UNIQUE INDEX `media_types_slug_unique` ON `media_types` (`slug`);
\ No newline at end of file
+CREATE UNIQUE INDEX `media_types_slug_unique` ON `media_types` (`slug`);--> statement-breakpoint
+CREATE TABLE `posters` (
+ `art_work_id` integer NOT NULL,
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `image` blob NOT NULL,
+ FOREIGN KEY (`art_work_id`) REFERENCES `art_works`(`id`) ON UPDATE no action ON DELETE no action
+);
diff --git a/src/db/drizzle/meta/0000_snapshot.json b/src/db/drizzle/meta/0000_snapshot.json
index 0923fb6..d8392a3 100644
--- a/src/db/drizzle/meta/0000_snapshot.json
+++ b/src/db/drizzle/meta/0000_snapshot.json
@@ -1,12 +1,19 @@
{
"version": "6",
"dialect": "sqlite",
- "id": "8b217318-7662-4f81-bc55-92d5c6ddf2b2",
+ "id": "01d72a44-6bdd-4f2a-b1dd-34546aa1b734",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"diary_entries": {
"name": "diary_entries",
"columns": {
+ "appreciation": {
+ "name": "appreciation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
"art_work_id": {
"name": "art_work_id",
"type": "integer",
@@ -14,6 +21,13 @@
"notNull": true,
"autoincrement": false
},
+ "commentary": {
+ "name": "commentary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
"date_created": {
"name": "date_created",
"type": "integer",
@@ -28,6 +42,13 @@
"notNull": true,
"autoincrement": false
},
+ "date_obtained": {
+ "name": "date_obtained",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
"id": {
"name": "id",
"type": "integer",
@@ -404,6 +425,51 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
+ },
+ "posters": {
+ "name": "posters",
+ "columns": {
+ "art_work_id": {
+ "name": "art_work_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "image": {
+ "name": "image",
+ "type": "blob",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "posters_art_work_id_art_works_id_fk": {
+ "name": "posters_art_work_id_art_works_id_fk",
+ "tableFrom": "posters",
+ "tableTo": "art_works",
+ "columnsFrom": [
+ "art_work_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
}
},
"views": {},
diff --git a/src/db/drizzle/meta/_journal.json b/src/db/drizzle/meta/_journal.json
index de36f89..207d6cd 100644
--- a/src/db/drizzle/meta/_journal.json
+++ b/src/db/drizzle/meta/_journal.json
@@ -5,8 +5,8 @@
{
"idx": 0,
"version": "6",
- "when": 1740814587298,
- "tag": "0000_unusual_karen_page",
+ "when": 1741093519331,
+ "tag": "0000_goofy_vanisher",
"breakpoints": true
}
]
diff --git a/src/db/schemas/constants.ts b/src/db/schemas/constants.ts
index a616ed8..40fe09c 100644
--- a/src/db/schemas/constants.ts
+++ b/src/db/schemas/constants.ts
@@ -20,3 +20,14 @@ export const DIARY_ENTRY_STATES = {
/** Un média ayant été regardé au mois une fois. */
WATCHED: "watched",
} as const;
+
+export const APPRECIATION_STATES = {
+ /** Oeuvre appréciée. */
+ APPRECIATED: "appreciated",
+ /** Oeuvre non appréciée (détestée). */
+ DISLIKED: "disliked",
+ /** Oeuvre laissant de marbre. */
+ NEUTRAL: "neutral",
+ /** Appréciation inconnue. */
+ UNKNOWN: "unknown",
+} as const;
diff --git a/src/db/schemas/entries.ts b/src/db/schemas/entries.ts
index 3ae3683..f99fbd0 100644
--- a/src/db/schemas/entries.ts
+++ b/src/db/schemas/entries.ts
@@ -5,15 +5,18 @@ import * as t from "drizzle-orm/sqlite-core";
import { sqliteTable as table } from "drizzle-orm/sqlite-core";
import { Schema } from "effect";
-import { DIARY_ENTRY_STATES } from "./constants";
+import { APPRECIATION_STATES, DIARY_ENTRY_STATES } from "./constants";
import { ArtWorks, Genres } from "./works";
// Tables
export const DiaryEntries = table("diary_entries", {
+ appreciation: t.text("appreciation").$type>().notNull(),
artWorkId: t.integer("art_work_id").references((): AnySQLiteColumn => ArtWorks.id).notNull(),
+ commentary: t.text("commentary").notNull(),
dateCreated: t.integer("date_created", { mode: "timestamp" }).notNull(),
dateModified: t.integer("date_modified", { mode: "timestamp" }).notNull(),
+ dateObtained: t.integer("date_obtained", { mode: "timestamp" }).notNull(),
id: t.integer("id").primaryKey({ autoIncrement: true }),
stateId: t.integer("state_id").references((): AnySQLiteColumn => DiaryEntriesStates.id).notNull(),
});
@@ -38,9 +41,12 @@ export const Viewings = table("viewings", {
// Schémas
export const DiaryEntrySchema = Schema.Struct({
+ appreciation: Schema.Enums(APPRECIATION_STATES),
artWorkId: Schema.NonNegativeInt,
+ commentary: Schema.String.pipe(Schema.optional),
dateCreated: Schema.Number,
dateModified: Schema.Number,
+ dateObtained: Schema.Number,
id: Schema.NonNegativeInt,
stateId: Schema.NonNegativeInt,
});
diff --git a/src/db/schemas/works.ts b/src/db/schemas/works.ts
index f08dcd5..fff8251 100644
--- a/src/db/schemas/works.ts
+++ b/src/db/schemas/works.ts
@@ -15,6 +15,12 @@ export const MediaTypes = table("media_types", {
slug: t.text("slug").$type>().notNull().unique(),
});
+export const Posters = table("posters", {
+ artWorkId: t.integer("art_work_id").references((): AnySQLiteColumn => ArtWorks.id).notNull(),
+ id: t.integer("id").primaryKey({ autoIncrement: true }),
+ image: t.blob("image", { mode: "buffer" }).notNull(),
+});
+
export const ArtWorks = table("art_works", {
coverPath: t.text("cover_path").unique(),
dateCreated: t.integer("date_created", { mode: "timestamp" }).notNull(),
diff --git a/src/libs/apis/tmdb/orders.ts b/src/libs/apis/tmdb/orders.ts
index 3cba5b4..25fb360 100644
--- a/src/libs/apis/tmdb/orders.ts
+++ b/src/libs/apis/tmdb/orders.ts
@@ -47,7 +47,7 @@ export const getTmdbSortFunction = (sortData: TmdbSortData) =>
export const byOriginalIndexAscending = Order.mapInput(
Order.number,
- (data: [number, MergedTmdbLocalData]) => data[1].original_result_index,
+ (data: [number, MergedTmdbLocalData]) => data[1].originalResultIndex,
);
export const byPopularityAscending = Order.mapInput(
Order.number,
@@ -55,7 +55,7 @@ export const byPopularityAscending = Order.mapInput(
);
export const byReleaseDateAscending = Order.mapInput(
Order.string,
- (data: [number, MergedTmdbLocalData]) => data[1].release_date,
+ (data: [number, MergedTmdbLocalData]) => data[1].releaseDate,
);
export const byTitleAscending = Order.mapInput(
Order.string,
diff --git a/src/libs/search/schemas.ts b/src/libs/search/schemas.ts
index aaef875..83522ae 100644
--- a/src/libs/search/schemas.ts
+++ b/src/libs/search/schemas.ts
@@ -1,4 +1,4 @@
-import { MEDIA_TYPES } from "@/db/schemas/constants";
+import { APPRECIATION_STATES, MEDIA_TYPES } from "@/db/schemas/constants";
import { Schema } from "effect";
export class SearchPageQueryParams extends Schema.Class("SearchPageQueryParams")({
@@ -8,20 +8,24 @@ export class SearchPageQueryParams extends Schema.Class("
}) {}
export class MergedTmdbLocalData extends Schema.Class("MergedTmdbLocalData")({
- artWorkCoverPath: Schema.Union(Schema.String, Schema.Null),
artWorkId: Schema.NonNegativeInt.pipe(Schema.optional),
artWorkMediumTypeId: Schema.NonNegativeInt.pipe(Schema.optional),
+ entryAppreciation: Schema.Enums(APPRECIATION_STATES).pipe(Schema.optional),
+ entryCommentary: Schema.String.pipe(Schema.optional),
entryDateCreated: Schema.Date.pipe(Schema.optional),
entryDateModified: Schema.Date.pipe(Schema.optional),
+ entryDateObtained: Schema.Date.pipe(Schema.optional),
entryId: Schema.NonNegativeInt.pipe(Schema.optional),
entryStateId: Schema.NonNegativeInt.pipe(Schema.optional),
- genre_ids: Schema.Array(Schema.NonNegativeInt),
- original_language: Schema.String,
- original_result_index: Schema.Int,
- original_title: Schema.String,
+ genreIds: Schema.Array(Schema.NonNegativeInt),
+ originalLanguage: Schema.String,
+ originalResultIndex: Schema.Int,
+ originalTitle: Schema.String,
overview: Schema.String,
popularity: Schema.Number,
- release_date: Schema.String,
+ posterBlob: Schema.Unknown.pipe(Schema.optional),
+ posterUrl: Schema.Union(Schema.String, Schema.Null),
+ releaseDate: Schema.String,
title: Schema.String,
tmdbId: Schema.NonNegativeInt,
}) {}
diff --git a/src/pages/SearchPage.vue b/src/pages/SearchPage.vue
index 1c7bfa1..a3b45de 100644
--- a/src/pages/SearchPage.vue
+++ b/src/pages/SearchPage.vue
@@ -153,20 +153,23 @@
result.id,
yield* Schema.decodeUnknown(MergedTmdbLocalData)(
{
- artWorkCoverPath: result.poster_path,
artWorkId: artWork?.id,
artWorkMediumTypeId: artWork?.mediumTypeId,
+ entryAppreciation: entry?.appreciation,
+ entryCommentary: entry?.commentary,
entryDateCreated: entry?.dateCreated,
entryDateModified: entry?.dateModified,
+ entryDateObtained: entry?.dateObtained,
entryId: entry?.id,
entryStateId: entry?.stateId,
- genre_ids: result.genre_ids,
- original_language: result.original_language,
- original_result_index: index,
- original_title: result.original_title,
+ genreIds: result.genre_ids,
+ originalLanguage: result.original_language,
+ originalResultIndex: index,
+ originalTitle: result.original_title,
overview: result.overview,
popularity: result.popularity,
- release_date: result.release_date,
+ posterUrl: result.poster_path,
+ releaseDate: result.release_date,
title: result.title,
tmdbId: result.id,
} satisfies MergedTmdbLocalData,
diff --git a/src/services/images.ts b/src/services/images.ts
index e695666..cdec2ef 100644
--- a/src/services/images.ts
+++ b/src/services/images.ts
@@ -1,5 +1,13 @@
import { asInt } from "@thi.ng/color-palettes";
-import { ARGB8888, canvasFromPixelBuffer, defIndexed, imageFromURL, intBufferFromImage } from "@thi.ng/pixel";
+import {
+ ARGB8888,
+ canvasFromPixelBuffer,
+ defIndexed,
+ imageFromURL,
+ IntBuffer,
+ intBufferFromImage,
+ type IntFormat,
+} from "@thi.ng/pixel";
import { ATKINSON, ditherWith } from "@thi.ng/pixel-dither";
import { Data, Effect, pipe } from "effect";
@@ -10,12 +18,12 @@ export class Images extends Effect.Service()("Images", {
return {
ditherImage: (image: HTMLImageElement, parent?: HTMLElement) =>
Effect.gen(function*() {
- const buf = intBufferFromImage(image, ARGB8888).scale(0.8, "cubic");
- const theme = defIndexed(asInt(["salmon", "black"]));
- const ditheredBuf = ditherWith(ATKINSON, buf.copy(), {}).as(theme);
+ const buf: IntBuffer = intBufferFromImage(image, ARGB8888).scale(0.8, "cubic");
+ const theme: IntFormat = defIndexed(asInt(["salmon", "black"]));
+ const ditheredBuffer: IntBuffer = ditherWith(ATKINSON, buf.copy(), {}).as(theme);
- const canvas = canvasFromPixelBuffer(ditheredBuf, parent, { pixelated: true });
- return canvas;
+ const canvas = canvasFromPixelBuffer(ditheredBuffer, parent, { pixelated: true });
+ return { buffer: ditheredBuffer, canvas: canvas };
}),
imageFromUrl: (url: URL) =>
pipe(
diff --git a/src/services/migrations.ts b/src/services/migrations.ts
index 1a83034..360250d 100644
--- a/src/services/migrations.ts
+++ b/src/services/migrations.ts
@@ -1,6 +1,6 @@
import type { SQLocalDrizzle } from "sqlocal/drizzle";
-import v0000 from "@/db/drizzle/0000_unusual_karen_page.sql?raw";
+import v0000 from "@/db/drizzle/0000_goofy_vanisher.sql?raw";
import { Data, Effect } from "effect";
import { LocalSqlite } from "./db";
diff --git a/src/styles/themes/default.css b/src/styles/themes/default.css
index 8172902..015b7ee 100644
--- a/src/styles/themes/default.css
+++ b/src/styles/themes/default.css
@@ -48,6 +48,10 @@ body {
}
}
+strong {
+ font-weight: var(--brkly-font-weight-semibold);
+}
+
.container {
--layout-center-max-width: 100%;
--layout-center-inline-padding: var(--s1);
diff --git a/tsconfig.json b/tsconfig.json
index 65acbc7..415fe18 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -16,7 +16,13 @@
"isolatedModules": true,
"jsx": "preserve",
"jsxImportSource": "vue",
- "lib": ["ESNext", "DOM", "DOM.Iterable", "DOM.AsyncIterable", "WebWorker"],
+ "lib": [
+ "ESNext",
+ "DOM",
+ "DOM.Iterable",
+ "DOM.AsyncIterable",
+ "WebWorker"
+ ],
"module": "ESNext",
"moduleDetection": "force",
"moduleResolution": "bundler",
@@ -32,8 +38,12 @@
"noUncheckedSideEffectImports": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
- "paths": { "@/*": ["./src/*"] },
- "plugins": [{ "name": "@vue/typescript-plugin" }],
+ "paths": {
+ "@/*": ["./src/*"]
+ },
+ "plugins": [
+ { "name": "@vue/typescript-plugin" }
+ ],
"resolveJsonModule": true,
"skipDefaultLibCheck": true,
"skipLibCheck": true,
@@ -43,10 +53,20 @@
"strictNullChecks": true,
"strictPropertyInitialization": true,
"target": "ESNext",
+ "tsBuildInfoFile": ".cache/tsbuildinfo",
"useDefineForClassFields": true,
"useUnknownInCatchVariables": true,
"verbatimModuleSyntax": true
},
- "exclude": ["node_modules", "dist/", ".cache"],
- "include": ["src/router/typed-routes.d.ts", "src/env.d.ts", "**/*", "**/*.vue"]
+ "exclude": [
+ ".cache",
+ "dist/",
+ "node_modules"
+ ],
+ "include": [
+ "**/*",
+ "**/*.vue",
+ "src/vite-env.d.ts",
+ "src/router/typed-routes.d.ts"
+ ]
}