Compare commits

...

39 Commits

Author SHA1 Message Date
IRHM a0ab7d8413 v2.1.1 2025-07-15 23:21:29 +01:00
IRHM 282255dbea 2.1.1-dev3 2025-07-15 22:44:24 +01:00
JoshF fa69639123 fix bug on return from blurhash.Encode (#922) 2025-07-15 21:41:30 +00:00
JoshF e177562c5a fix Twitch init error logging bug (#921) 2025-07-15 21:35:40 +00:00
IRHM 6d0203c6e1 2.1.1-dev2 2025-07-14 23:30:58 +01:00
IRHM 45921a0c94 StarRating: Still save rating if scroll change is less than 10px in either direction
This fixes firefox mobile.

Chromium on mobile stops the page from scrolling with a grace area while dragging the stars, but firefox doesn't do this, which breaks the (if scrolled dont save logic), so added the 10px grace into logic.

Future fix could be to stop the scrolling to mimic chromium behaviour for firefox mobile too, but that sound hard. Maybe firefox can fix this.
2025-07-14 23:30:32 +01:00
IRHM 18ab577662 StarRating: Fix rating change saved twice on chromium mobile when a star is clicked
without being dragged first.
2025-07-14 23:28:12 +01:00
IRHM acb388e271 2.1.1-dev1 2025-07-14 18:53:15 +01:00
IRHM d7dafc8d67 import: Remove returning of only the perfect matches if more than 1
Just had an epiphany that it'd be better to return all results in this case, the frontend still sorts for best matches to be shown first, but then we keep all other options incase the users import data had a slight typo that matched other content etc.
2025-07-14 18:52:33 +01:00
IRHM 77f73bd03b 2.1.1-dev 2025-07-14 18:46:56 +01:00
Mr a47952e61d StarRating: Ignore star presses if scroll position changes from start to end of click (#916)
* StarRating: Ignore star presses if scroll position changes from start to end of click

This should help us avoid accidental clicks of stars being saved when the user is just trying to scroll down the page.

* StarRating: Make scrollLocAtStart a normal variable

doesnt need to be $state
2025-07-13 18:42:34 +00:00
Mr 72f8ddc8e6 import: Perfect matching now takes Year into account if provided, avoiding muli result responses (#915)
perfect matches are also collected (before only one was allowed to perfect match) and all are returned if multiple

#914
2025-07-13 15:59:52 +00:00
IRHM 6a53066b72 v2.1.0 2025-05-18 19:03:30 +01:00
IRHM 9ebc46d7d4 2.1.0-dev1 2025-05-18 17:52:13 +01:00
IRHM 0456eefe3b FaceMenu: Increase width to 140px
So the version string doesn't need to overflow when it includes the `-dev` affix
2025-05-18 17:51:10 +01:00
IRHM 3b85331f3b 2.1.0-dev 2025-05-18 17:45:45 +01:00
Mr 56fe1152c5 Search shortcut & add missing keys that search handler should ignore (#886)
* (fix) handleSearch: Add missing keys that we should ignore

* (new) Create global keybing handler, ctrl+s search bind

* focusSearch: Add try/catch
2025-05-18 16:38:06 +00:00
dependabot[bot] 699f19badb ui: bump typescript from 5.7.2 to 5.8.3 (#865)
* ui: bump typescript from 5.7.2 to 5.8.3

Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.7.2 to 5.8.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/commits)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 5.8.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* dep: bump typescript-eslint to 8.32.1

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: IRHM <37304121+IRHM@users.noreply.github.com>
2025-05-18 16:03:35 +00:00
dependabot[bot] e415f77e5a ui: bump eslint-config-prettier from 9.1.0 to 10.1.2 (#872)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 9.1.0 to 10.1.2.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v9.1.0...v10.1.2)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-version: 10.1.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-18 15:54:06 +00:00
dependabot[bot] 124323cc59 ui: bump sass from 1.83.0 to 1.86.3 (#867)
Bumps [sass](https://github.com/sass/dart-sass) from 1.83.0 to 1.86.3.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.83.0...1.86.3)

---
updated-dependencies:
- dependency-name: sass
  dependency-version: 1.86.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-18 15:52:41 +00:00
dependabot[bot] ee716a9dc8 ui: bump @typescript-eslint/eslint-plugin from 8.19.0 to 8.30.1 (#874)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.19.0 to 8.30.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.30.1/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.30.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-18 15:41:21 +00:00
dependabot[bot] c4694e577f ui: bump prettier-plugin-svelte from 3.3.2 to 3.3.3 (#773)
Bumps [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte) from 3.3.2 to 3.3.3.
- [Changelog](https://github.com/sveltejs/prettier-plugin-svelte/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/prettier-plugin-svelte/commits)

---
updated-dependencies:
- dependency-name: prettier-plugin-svelte
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-18 15:39:39 +00:00
dependabot[bot] d8f914ddca ui: bump axios from 1.7.9 to 1.8.4 (#855)
Bumps [axios](https://github.com/axios/axios) from 1.7.9 to 1.8.4.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.7.9...v1.8.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-18 15:33:58 +00:00
dependabot[bot] 4d145d593b ui: bump vite from 6.0.7 to 6.2.6 (#873)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.0.7 to 6.2.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.2.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.2.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.2.6
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-17 18:59:28 +00:00
dependabot[bot] 889aa30150 ui: bump @sveltejs/kit from 2.16.0 to 2.20.6 (#875)
Bumps [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit) from 2.16.0 to 2.20.6.
- [Release notes](https://github.com/sveltejs/kit/releases)
- [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.20.6/packages/kit)

---
updated-dependencies:
- dependency-name: "@sveltejs/kit"
  dependency-version: 2.20.6
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-17 18:51:40 +00:00
IRHM 490192b386 chore: ui: fix formatting in import 2025-05-17 19:50:55 +01:00
dependabot[bot] 9a9cf1e3fb server: bump github.com/go-co-op/gocron/v2 in /server (#842)
Bumps [github.com/go-co-op/gocron/v2](https://github.com/go-co-op/gocron) from 2.14.2 to 2.16.1.
- [Release notes](https://github.com/go-co-op/gocron/releases)
- [Commits](https://github.com/go-co-op/gocron/compare/v2.14.2...v2.16.1)

---
updated-dependencies:
- dependency-name: github.com/go-co-op/gocron/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-17 18:39:46 +00:00
dependabot[bot] 300b063b9a server: bump github.com/golang-jwt/jwt/v5 from 5.2.1 to 5.2.2 in /server (#846)
Bumps [github.com/golang-jwt/jwt/v5](https://github.com/golang-jwt/jwt) from 5.2.1 to 5.2.2.
- [Release notes](https://github.com/golang-jwt/jwt/releases)
- [Changelog](https://github.com/golang-jwt/jwt/blob/main/VERSION_HISTORY.md)
- [Commits](https://github.com/golang-jwt/jwt/compare/v5.2.1...v5.2.2)

---
updated-dependencies:
- dependency-name: github.com/golang-jwt/jwt/v5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-17 18:36:44 +00:00
IRHM 99be784453 server: Upgrade to go 1.24 2025-05-17 19:33:07 +01:00
dependabot[bot] 2f6cf1c0db server: bump golang.org/x/crypto from 0.32.0 to 0.37.0 in /server (#863)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.32.0 to 0.37.0.
- [Commits](https://github.com/golang/crypto/compare/v0.32.0...v0.37.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-17 18:26:49 +00:00
dependabot[bot] 23e686385c server: bump github.com/gin-contrib/cors from 1.7.3 to 1.7.5 in /server (#864)
Bumps [github.com/gin-contrib/cors](https://github.com/gin-contrib/cors) from 1.7.3 to 1.7.5.
- [Release notes](https://github.com/gin-contrib/cors/releases)
- [Changelog](https://github.com/gin-contrib/cors/blob/master/.goreleaser.yaml)
- [Commits](https://github.com/gin-contrib/cors/compare/v1.7.3...v1.7.5)

---
updated-dependencies:
- dependency-name: github.com/gin-contrib/cors
  dependency-version: 1.7.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-17 18:22:03 +00:00
Antonio Sarro cbe445b7d9 feat(theme): add system preference handling to theme configuration (#822)
* feat(theme): add system preference handling to theme configuration

* Moved theme logic to new file, renamed vars, move system theme btn to top

- Moved `system` theme button to top (since its default).
- Moved theme logic to new `theme.ts` file & renamed some variables.
- Store: Revert change that sets updateStore=true when rehydrating theme (not necessary since we update store manually)

---------

Co-authored-by: IRHM <37304121+IRHM@users.noreply.github.com>
2025-05-17 18:12:22 +00:00
Iván Iglesias 087071a8af Support for importing ryot 8 files (#862)
- media renamed to metadata
- shows now support overall score
2025-05-17 17:01:34 +00:00
jigglycrumb a0a74e8cdc feat: improve imdb import (#880)
Makes the IMDb importer more robust by identifying more media types like Direct-to-Video movies, TV Mini Series and more which are all not regconized and thus skipped by the current importer.

It also makes a tiny UI change by adding the year of the imported movie to the "Multiple Results Found" dialog, which makes identifying the actually imported movie more easy and should help to reduce mismatches.
2025-05-17 16:48:52 +00:00
Mr a16769e0db doc: Add text-file, trakt, watcharr pages for importing. (#883)
* doc: Add text-file, trakt, watcharr pages for importing.

* doc: importing/watcharr: Fix backup guide link
2025-05-11 19:47:56 +00:00
Andreas 565d90dbf0 feat: new about modal (#811)
* FaceMenu: Add about modal

added modal with about info to FaceMenu bottom.
added 4 new SVG icons.

* FaceMenu: npm format

* FaceMenu: refactor about modal

- moved about modal into its own file
- minor fixes

* AboutModal: Add text to gh/site links, use Modal title prop, add attribution file link

, added a hover effect to all links in the modal and removed the margin on h5.

Also updated the top paragraph.

* AboutModal: Remove unused style

* Menu: Use color variables

---------

Co-authored-by: IRHM <37304121+IRHM@users.noreply.github.com>
2025-02-21 01:14:13 +00:00
IRHM b6d6e66f04 v2.0.2 2025-02-16 21:18:27 +00:00
IRHM 0b4f3c8604 2.0.2-dev 2025-02-16 21:00:09 +00:00
Mr 0a5a4e39f5 DetailedMenu: Fix wlDetailedView not setting correctly (#814)
wasn't causing setter to trigger and save to localStorage
2025-02-16 19:57:55 +00:00
26 changed files with 986 additions and 465 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
#
# Backend
#
FROM golang:1.22-alpine AS server
FROM golang:1.24-alpine AS server
WORKDIR /server
COPY server/*.go server/go.* ./
+1 -1
View File
@@ -1,5 +1,5 @@
---
sidebar_position: 1
sidebar_position: 2
---
# MyAnimeList
+30
View File
@@ -0,0 +1,30 @@
---
sidebar_position: 1
---
# Text File (.txt list)
:::info Backup?
You may consider a backup of your server before starting any import. They are not easily reversible, though we do our best to ensure they are accurate and bug free!
:::
The text file (.txt) import is of an arbitrary format (the one I used for years before creating Watcharr).
Hopefully it is useful for others with similar files or in scenarios where its the easiest to generate for an import (though if possible, when generating a backup from another service data manually, matching a Watcharr export would enable keeping more data).
## Format
Each line is a new entry. The name of the content (show/movie) must be provided, the year can be optionally provided surrounded by brackets. Doesn't support specifying if name is for a show or movie, the importer will only automatically match on full search matches, if there are multiple results, you will be asked to pick the correct one.
```
<name> [(<year>)]
```
## An example
```
The Terminator (1984)
Breaking Bad
A Fistful of Dollars
Reacher (2022)
```
+16
View File
@@ -0,0 +1,16 @@
---
sidebar_position: 3
---
# Trakt
:::info Backup?
You may consider a backup of your server before starting any import. They are not easily reversible, though we do our best to ensure they are accurate and bug free!
:::
**Note:** Your Trakt profile must be public _during_ this process. You are free to private it again once it completes.
1. Provide your Trakt username in the text box.
2. Press `Start Import`.
This will be a long process, possibly a couple hours depending on how large of a Trakt history you have. If you think it has frozen or isn't working, try checking your server logs to see if it is doing anything.
+16
View File
@@ -0,0 +1,16 @@
---
sidebar_position: 0
---
# Watcharr
:::info Backup?
You may consider a backup of your server before starting any import. They are not easily reversible, though we do our best to ensure they are accurate and bug free!
:::
:::warning May not be what you want
Watcharr import/export is a feature intended for end users. If you are the server admin, it is recommended that you copy your server files directly to any new server you are creating (it'll be much faster and easier). [See backup guide](/docs/server_config/backup).
:::
1. Provide the Watcharr export file (that you generated from your profile page).
2. Review the import table, if everything looks good, start the import.
+400 -311
View File
File diff suppressed because it is too large Load Diff
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "watcharr",
"version": "2.0.1",
"version": "2.1.1",
"private": true,
"scripts": {
"dev": "vite dev",
@@ -15,27 +15,27 @@
},
"devDependencies": {
"@sveltejs/adapter-node": "^5.2.12",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/kit": "^2.21.0",
"@types/papaparse": "^5.3.15",
"@typescript-eslint/eslint-plugin": "^8.18.2",
"@typescript-eslint/parser": "^8.18.2",
"@typescript-eslint/eslint-plugin": "^8.32.1",
"@typescript-eslint/parser": "^8.32.1",
"@vite-pwa/sveltekit": "^0.6.6",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-prettier": "^10.1.2",
"eslint-plugin-svelte": "^2.45.1",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.2.6",
"sass": "^1.83.0",
"prettier-plugin-svelte": "^3.4.0",
"sass": "^1.89.0",
"svelte": "^5.17.3",
"svelte-check": "^4.1.3",
"svelte-eslint-parser": "^0.42.0",
"svelte-preprocess": "^6.0.3",
"typescript": "^5.7.2",
"vite": "^6.0.7"
"typescript": "^5.8.3",
"vite": "^6.3.5"
},
"type": "module",
"dependencies": {
"axios": "^1.7.4",
"axios": "^1.9.0",
"blurhash": "^2.0.5",
"papaparse": "^5.4.1"
}
+20 -21
View File
@@ -1,16 +1,16 @@
module github.com/sbondCo/Watcharr
go 1.22
go 1.24
require (
github.com/buckket/go-blurhash v1.1.0
github.com/gin-contrib/cache v1.3.1
github.com/gin-contrib/cors v1.7.3
github.com/gin-contrib/cors v1.7.5
github.com/gin-gonic/gin v1.10.0
github.com/go-co-op/gocron/v2 v2.14.2
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/go-co-op/gocron/v2 v2.16.2
github.com/golang-jwt/jwt/v5 v5.2.2
github.com/joho/godotenv v1.5.1
golang.org/x/crypto v0.32.0
golang.org/x/crypto v0.38.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gorm.io/driver/sqlite v1.5.7
gorm.io/gorm v1.25.12
@@ -18,23 +18,23 @@ require (
require (
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
github.com/bytedance/sonic v1.12.6 // indirect
github.com/bytedance/sonic/loader v0.2.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.7 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/bytedance/sonic v1.13.2 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/gin-contrib/sse v1.0.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.23.0 // indirect
github.com/goccy/go-json v0.10.4 // indirect
github.com/go-playground/validator/v10 v10.26.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/gomodule/redigo v1.9.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/jonboulle/clockwork v0.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
@@ -46,11 +46,10 @@ require (
github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.12.0 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/protobuf v1.36.1 // indirect
golang.org/x/arch v0.15.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+38 -39
View File
@@ -2,42 +2,41 @@ github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8b
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
github.com/buckket/go-blurhash v1.1.0 h1:X5M6r0LIvwdvKiUtiNcRL2YlmOfMzYobI3VCKCZc9Do=
github.com/buckket/go-blurhash v1.1.0/go.mod h1:aT2iqo5W9vu9GpyoLErKfTHwgODsZp3bQfXjXJUxNb8=
github.com/bytedance/sonic v1.12.6 h1:/isNmCUF2x3Sh8RAp/4mh4ZGkcFAX/hLrzrK3AvpRzk=
github.com/bytedance/sonic v1.12.6/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=
github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/gin-contrib/cache v1.3.1 h1:EWjkOaLocs5fGt9feQaI7rt1GZbDyatFXEUh2/s3ZI8=
github.com/gin-contrib/cache v1.3.1/go.mod h1:6Tme0p3QEF/Ck/KUcq7h/OAqZvUDjHRH1DtQbNgfIX0=
github.com/gin-contrib/cors v1.7.3 h1:hV+a5xp8hwJoTw7OY+a70FsL8JkVVFTXw9EcfrYUdns=
github.com/gin-contrib/cors v1.7.3/go.mod h1:M3bcKZhxzsvI+rlRSkkxHyljJt1ESd93COUvemZ79j4=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-contrib/cors v1.7.5 h1:cXC9SmofOrRg0w9PigwGlHG3ztswH6bqq4vJVXnvYMk=
github.com/gin-contrib/cors v1.7.5/go.mod h1:4q3yi7xBEDDWKapjT2o1V7mScKDDr8k+jZ0fSquGoy0=
github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E=
github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-co-op/gocron/v2 v2.14.2 h1:S6CbI7MVfD3S/aPJNLoSg2YcGyEqzEMwUopDejuT4Oc=
github.com/go-co-op/gocron/v2 v2.14.2/go.mod h1:ZF70ZwEqz0OO4RBXE1sNxnANy/zvwLcattWEFsqpKig=
github.com/go-co-op/gocron/v2 v2.16.2 h1:r08P663ikXiulLT9XaabkLypL/W9MoCIbqgQoAutyX4=
github.com/go-co-op/gocron/v2 v2.16.2/go.mod h1:4YTLGCCAH75A5RlQ6q+h+VacO7CgjkgP0EJ+BEOXRSI=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/gomodule/redigo v1.9.2 h1:HrutZBLhSIU8abiSfW8pj8mPhOyMYjZT/wcA4/L9L9s=
github.com/gomodule/redigo v1.9.2/go.mod h1:KsU3hiK/Ay8U42qpaJk+kuNa3C+spxapWpM+ywhcgtw=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
@@ -51,13 +50,13 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
@@ -89,11 +88,13 @@ github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6po
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
@@ -102,21 +103,19 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg=
golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw=
golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+1 -1
View File
@@ -58,7 +58,7 @@ func getBlurHash(img io.Reader) (string, error) {
slog.Error("getBlurHash decoding image failed", "error", err)
return "", errors.New("decoding image failed")
}
bh, _ := blurhash.Encode(6, 5, i)
bh, err := blurhash.Encode(6, 5, i)
if err != nil {
// Handle errors
slog.Error("getBlurHash generation failed", "error", err)
+38 -11
View File
@@ -28,6 +28,7 @@ var (
type ImportRequest struct {
Name string `json:"name"`
Year int `json:"year"`
TmdbID int `json:"tmdbId"`
Type ContentType `json:"type"`
Rating float64 `json:"rating" binding:"max=10"`
@@ -51,6 +52,7 @@ type ImportResponse struct {
}
func importContent(db *gorm.DB, userId uint, ar ImportRequest) (ImportResponse, error) {
slog.Debug("import: Processing request:", "request", ar)
// If tmdbId and type passed in request body
// we dont need to use a search tmdb request.
// Retrieve the details directly.
@@ -139,28 +141,53 @@ func importContent(db *gorm.DB, userId uint, ar ImportRequest) (ImportResponse,
// If there are multiple responses, but only one item
// from the results is a 100% match for the imported
// items name, then consider successful match with that.
var perfectMatch TMDBSearchMultiResults
perfectMatches := []TMDBSearchMultiResults{}
for _, r := range pMatches {
itemName := r.Name
if itemName == "" {
itemName = r.Title
}
if strings.EqualFold(itemName, ar.Name) {
slog.Debug("import: multiple results processing: found a perfectMatch", "match", r)
if perfectMatch.ID != 0 {
// If perfect match has been set before..
// quit looking and just show all results.
slog.Debug("import: multiple results processing: Second perfectMatch found.. returning all results")
return ImportResponse{Type: IMPORT_MULTI, Results: pMatches}, nil
itemReleaseYear := 0
// Only parse dates to find year if the import request has provided
// a year to comparisons.. otherwise don't do it to save some performance juice.
if ar.Year != 0 {
itemReleaseDateStr := r.ReleaseDate
if itemReleaseDateStr == "" {
itemReleaseDateStr = r.FirstAirDate
}
perfectMatch = r
if itemReleaseDate, err := time.Parse("2006-01-02", itemReleaseDateStr); err == nil {
itemReleaseYear = itemReleaseDate.Year()
} else {
slog.Error("import: failed to check item release year, it can't be used for matching", "error", err, "item", r)
}
}
if strings.EqualFold(itemName, ar.Name) {
slog.Debug("import: multiple results processing: found a perfect name match", "itemReleaseYear", itemReleaseYear, "ar.Year", ar.Year, "match", r)
// If we have a year for comparison, force a check to compare them for a
// match to be deemed perfect.
// `itemReleaseYear` can only ever have a value if `ar.Year` has one, so this
// check is safe as is.
if itemReleaseYear != 0 || ar.Year != 0 {
if itemReleaseYear == ar.Year {
perfectMatches = append(perfectMatches, r)
slog.Debug("import: multiple results processing: name match also matched year")
} else {
slog.Debug("import: multiple results processing: name match didnt match year")
}
continue
}
// Otherwise, if we don't have valid dates to compare, append the perfect name match anyways.
slog.Debug("import: multiple results processing: name match didn't have valid release year, adding to matches anyways")
perfectMatches = append(perfectMatches, r)
}
}
// If one perfect match found, import it
if perfectMatch.ID != 0 {
pmLen := len(perfectMatches)
if pmLen == 1 && perfectMatches[0].ID != 0 {
slog.Debug("import: importing from perfect match")
return successfulImport(db, userId, perfectMatch.ID, ContentType(perfectMatch.MediaType), ar)
return successfulImport(db, userId, perfectMatches[0].ID, ContentType(perfectMatches[0].MediaType), ar)
}
slog.Debug("import: returning all potential matches")
return ImportResponse{Type: IMPORT_MULTI, Results: pMatches}, nil
} else {
slog.Debug("import: success.. only found one result")
+1 -1
View File
@@ -389,7 +389,7 @@ func (b *BaseRouter) addGameRoutes() {
})
err := igdb.Init()
// Save cfg if init succeeded, this will save our access token
if err == nil {
if err != nil {
slog.Error("GameRoutes: Twitch init failed!", "error", err)
}
+48
View File
@@ -645,6 +645,54 @@
d="M368 192h-16v-80a96 96 0 10-192 0v80h-16a64.07 64.07 0 00-64 64v176a64.07 64.07 0 0064 64h224a64.07 64.07 0 0064-64V256a64.07 64.07 0 00-64-64zm-48 0H192v-80a64 64 0 11128 0z"
/>
</svg>
{:else if i === "github"}
<svg
xmlns="http://www.w3.org/2000/svg"
width={wh}
height={wh}
viewBox="0 0 24 25"
>
<path
fill="currentColor"
d="M12.301 0h.093c2.242 0 4.34.613 6.137 1.68l-.055-.031a12.35 12.35 0 0 1 4.449 4.422l.031.058a12.2 12.2 0 0 1 1.654 6.166c0 5.406-3.483 10-8.327 11.658l-.087.026a.72.72 0 0 1-.642-.113l.002.001a.62.62 0 0 1-.208-.466v-.014v.001l.008-1.226q.008-1.178.008-2.154a2.84 2.84 0 0 0-.833-2.274a11 11 0 0 0 1.718-.305l-.076.017a6.5 6.5 0 0 0 1.537-.642l-.031.017a4.5 4.5 0 0 0 1.292-1.058l.006-.007a4.9 4.9 0 0 0 .84-1.645l.009-.035a7.9 7.9 0 0 0 .329-2.281l-.001-.136v.007l.001-.072a4.73 4.73 0 0 0-1.269-3.23l.003.003c.168-.44.265-.948.265-1.479a4.25 4.25 0 0 0-.404-1.814l.011.026a2.1 2.1 0 0 0-1.31.181l.012-.005a8.6 8.6 0 0 0-1.512.726l.038-.022l-.609.384c-.922-.264-1.981-.416-3.075-.416s-2.153.152-3.157.436l.081-.02q-.256-.176-.681-.433a9 9 0 0 0-1.272-.595l-.066-.022A2.17 2.17 0 0 0 5.837 5.1l.013-.002a4.2 4.2 0 0 0-.393 1.788c0 .531.097 1.04.275 1.509l-.01-.029a4.72 4.72 0 0 0-1.265 3.303v-.004l-.001.13c0 .809.12 1.591.344 2.327l-.015-.057c.189.643.476 1.202.85 1.693l-.009-.013a4.4 4.4 0 0 0 1.267 1.062l.022.011c.432.252.933.465 1.46.614l.046.011c.466.125 1.024.227 1.595.284l.046.004c-.431.428-.718 1-.784 1.638l-.001.012a3 3 0 0 1-.699.236l-.021.004c-.256.051-.549.08-.85.08h-.066h.003a1.9 1.9 0 0 1-1.055-.348l.006.004a2.84 2.84 0 0 1-.881-.986l-.007-.015a2.6 2.6 0 0 0-.768-.827l-.009-.006a2.3 2.3 0 0 0-.776-.38l-.016-.004l-.32-.048a1.05 1.05 0 0 0-.471.074l.007-.003q-.128.072-.08.184q.058.128.145.225l-.001-.001q.092.108.205.19l.003.002l.112.08c.283.148.516.354.693.603l.004.006c.191.237.359.505.494.792l.01.024l.16.368c.135.402.38.738.7.981l.005.004c.3.234.662.402 1.057.478l.016.002c.33.064.714.104 1.106.112h.007q.069.002.15.002q.392 0 .767-.062l-.027.004l.368-.064q0 .609.008 1.418t.008.873v.014c0 .185-.08.351-.208.466h-.001a.72.72 0 0 1-.645.111l.005.001C3.486 22.286.006 17.692.006 12.285c0-2.268.612-4.393 1.681-6.219l-.032.058a12.35 12.35 0 0 1 4.422-4.449l.058-.031a11.9 11.9 0 0 1 6.073-1.645h.098h-.005zm-7.64 17.666q.048-.112-.112-.192q-.16-.048-.208.032q-.048.112.112.192q.144.096.208-.032m.497.545q.112-.08-.032-.256q-.16-.144-.256-.048q-.112.08.032.256q.159.157.256.047zm.48.72q.144-.112 0-.304q-.128-.208-.272-.096q-.144.08 0 .288t.272.112m.672.673q.128-.128-.064-.304q-.192-.192-.32-.048q-.144.128.064.304q.192.192.32.044zm.913.4q.048-.176-.208-.256q-.24-.064-.304.112t.208.24q.24.097.304-.096m1.009.08q0-.208-.272-.176q-.256 0-.256.176q0 .208.272.176q.256.001.256-.175zm.929-.16q-.032-.176-.288-.144q-.256.048-.224.24t.288.128t.225-.224z"
/>
</svg>
{:else if i === "website"}
<svg
xmlns="http://www.w3.org/2000/svg"
width={wh}
height={wh}
viewBox="0 0 2048 2048"
>
<path
fill="currentColor"
d="M1024 0q141 0 272 36t245 103t207 160t160 208t103 245t37 272q0 141-36 272t-103 245t-160 207t-208 160t-245 103t-272 37q-141 0-272-36t-245-103t-207-160t-160-208t-103-244t-37-273q0-141 36-272t103-245t160-207t208-160T751 37t273-37m0 1920q123 0 237-32t214-90t182-141t140-181t91-214t32-238q0-123-32-237t-90-214t-141-182t-181-140t-214-91t-238-32q-123 0-237 32t-214 90t-182 141t-140 181t-91 214t-32 238q0 123 32 237t90 214t141 182t181 140t214 91t238 32m597-880l48-144h75l-85 256h-75l-48-144l-48 144h-75l-85-256h75l48 144l48-144h74zm-464-144h75l-85 256h-75l-48-144l-48 144h-75l-85-256h75l48 144l48-144h74l48 144zm-512 0h75l-85 256h-75l-48-144l-48 144h-75l-85-256h75l48 144l48-144h74l48 144z"
/>
</svg>
{:else if i === "tmdb"}
<svg
xmlns="http://www.w3.org/2000/svg"
width={wh}
height={wh}
viewBox="0 0 185.04 133.4"
>
<path
fill="currentColor"
d="M51.06,66.7h0A17.67,17.67,0,0,1,68.73,49h-.1A17.67,17.67,0,0,1,86.3,66.7h0A17.67,17.67,0,0,1,68.63,84.37h.1A17.67,17.67,0,0,1,51.06,66.7Zm82.67-31.33h32.9A17.67,17.67,0,0,0,184.3,17.7h0A17.67,17.67,0,0,0,166.63,0h-32.9A17.67,17.67,0,0,0,116.06,17.7h0A17.67,17.67,0,0,0,133.73,35.37Zm-113,98h63.9A17.67,17.67,0,0,0,102.3,115.7h0A17.67,17.67,0,0,0,84.63,98H20.73A17.67,17.67,0,0,0,3.06,115.7h0A17.67,17.67,0,0,0,20.73,133.37Zm83.92-49h6.25L125.5,49h-8.35l-8.9,23.2h-.1L99.4,49H90.5Zm32.45,0h7.8V49h-7.8Zm22.2,0h24.95V77.2H167.1V70h15.35V62.8H167.1V56.2h16.25V49h-24ZM10.1,35.4h7.8V6.9H28V0H0V6.9H10.1ZM39,35.4h7.8V20.1H61.9V35.4h7.8V0H61.9V13.2H46.75V0H39Zm41.25,0h25V28.2H88V21h15.35V13.8H88V7.2h16.25V0h-24Zm-79,49H9V57.25h.1l9,27.15H24l9.3-27.15h.1V84.4h7.8V49H29.45l-8.2,23.1h-.1L13,49H1.2Zm112.09,49H126a24.59,24.59,0,0,0,7.56-1.15,19.52,19.52,0,0,0,6.35-3.37,16.37,16.37,0,0,0,4.37-5.5A16.91,16.91,0,0,0,146,115.8a18.5,18.5,0,0,0-1.68-8.25,15.1,15.1,0,0,0-4.52-5.53A18.55,18.55,0,0,0,133.07,99,33.54,33.54,0,0,0,125,98H113.29Zm7.81-28.2h4.6a17.43,17.43,0,0,1,4.67.62,11.68,11.68,0,0,1,3.88,1.88,9,9,0,0,1,2.62,3.18,9.87,9.87,0,0,1,1,4.52,11.92,11.92,0,0,1-1,5.08,8.69,8.69,0,0,1-2.67,3.34,10.87,10.87,0,0,1-4,1.83,21.57,21.57,0,0,1-5,.55H121.1Zm36.14,28.2h14.5a23.11,23.11,0,0,0,4.73-.5,13.38,13.38,0,0,0,4.27-1.65,9.42,9.42,0,0,0,3.1-3,8.52,8.52,0,0,0,1.2-4.68,9.16,9.16,0,0,0-.55-3.2,7.79,7.79,0,0,0-1.57-2.62,8.38,8.38,0,0,0-2.45-1.85,10,10,0,0,0-3.18-1v-.1a9.28,9.28,0,0,0,4.43-2.82,7.42,7.42,0,0,0,1.67-5,8.34,8.34,0,0,0-1.15-4.65,7.88,7.88,0,0,0-3-2.73,12.9,12.9,0,0,0-4.17-1.3,34.42,34.42,0,0,0-4.63-.32h-13.2Zm7.8-28.8h5.3a10.79,10.79,0,0,1,1.85.17,5.77,5.77,0,0,1,1.7.58,3.33,3.33,0,0,1,1.23,1.13,3.22,3.22,0,0,1,.47,1.82,3.63,3.63,0,0,1-.42,1.8,3.34,3.34,0,0,1-1.13,1.2,4.78,4.78,0,0,1-1.57.65,8.16,8.16,0,0,1-1.78.2H165Zm0,14.15h5.9a15.12,15.12,0,0,1,2.05.15,7.83,7.83,0,0,1,2,.55,4,4,0,0,1,1.58,1.17,3.13,3.13,0,0,1,.62,2,3.71,3.71,0,0,1-.47,1.95,4,4,0,0,1-1.23,1.3,4.78,4.78,0,0,1-1.67.7,8.91,8.91,0,0,1-1.83.2h-7Z"
/>
</svg>
{:else if i === "igdb"}
<svg
xmlns="http://www.w3.org/2000/svg"
width={wh}
height={wh}
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M24 6.228H0v11.543a89 89 0 0 1 2.271-.333a74 74 0 0 1 17.038-.28c1.57.153 3.134.363 4.69.614zm-.706.707v10.013a74.8 74.8 0 0 0-22.588 0V6.934zM7.729 8.84a2.62 2.62 0 0 0-1.857.72a2.55 2.55 0 0 0-.73 1.33c-.098.5-.063 1.03.112 1.51c.177.488.515.917.954 1.196c.547.354 1.224.472 1.865.401a3.24 3.24 0 0 0 1.786-.777c-.003-.724.002-1.449-.002-2.173c-.725.004-1.45-.002-2.174.003c.003.317 0 .634.001.951h1.105c.002.236 0 .473.002.71a1.7 1.7 0 0 1-.932.298c-.32.02-.65-.05-.922-.225a1.46 1.46 0 0 1-.59-.744c-.18-.499-.134-1.085.163-1.53c.23-.355.619-.61 1.043-.647a1.8 1.8 0 0 1 1.012.206c.152.082.286.192.424.295q.344-.42.692-.838a3 3 0 0 0-.595-.403c-.418-.212-.892-.285-1.357-.283m11.66.086q-.14.002-.28 0c-.68.002-1.359-.004-2.038.003c.003 1.666 0 3.332.002 4.998h2.497q.36-.003.709-.097c.276-.076.546-.208.742-.422c.194-.208.297-.492.304-.776c.016-.278-.032-.572-.195-.804c-.175-.252-.453-.408-.734-.514c.211-.122.407-.285.521-.505c.134-.246.149-.535.117-.807a1.16 1.16 0 0 0-.436-.73c-.264-.207-.599-.304-.93-.334a3 3 0 0 0-.279-.012m-16.715 0v5.002h1.102V8.927q-.552-.002-1.102 0zm8.524 0v5.002h2.016a2.9 2.9 0 0 0 1.07-.211a2.44 2.44 0 0 0 1.174-.993c.34-.555.429-1.244.292-1.876a2.37 2.37 0 0 0-.828-1.338c-.478-.387-1.096-.577-1.707-.584zm6.949.967c.392.002.784-.001 1.176.002c.183.011.38.054.51.19c.11.112.136.28.112.43a.44.44 0 0 1-.22.316a1.1 1.1 0 0 1-.483.116c-.365.002-.73-.001-1.094.001l-.001-1.054zm-5.031.026c.28 0 .567.053.815.19c.274.149.491.396.607.685c.113.272.138.574.107.865a1.46 1.46 0 0 1-.335.786a1.43 1.43 0 0 1-.865.466c-.168.031-.34.022-.51.023h-.632V9.92zm5.03 1.948h1.36c.174.006.354.035.505.127a.45.45 0 0 1 .212.308c.025.15.004.32-.099.44c-.102.12-.258.176-.409.2c-.172.032-.348.02-.522.022c-.35-.001-.698.002-1.047-.001z"
/>
</svg>
{/if}
<style lang="scss">
+22 -1
View File
@@ -100,10 +100,31 @@
}
}
a.menu-footer,
button.menu-footer {
font-size: 11px;
padding: 2px;
text-align: center;
transition: inherit;
color: $text-color-accent;
cursor: pointer;
border: none;
display: inline;
font-weight: initial;
width: auto;
&:hover,
&:focus-visible {
text-decoration: underline;
background-color: $bg-color;
color: $text-color;
}
}
span {
margin-top: 8px;
font-size: 11px;
color: gray;
color: $text-color-accent;
text-align: center;
}
}
+101
View File
@@ -0,0 +1,101 @@
<script lang="ts">
import Icon from "../Icon.svelte";
import Modal from "../Modal.svelte";
interface Props {
onClose: () => void;
}
let { onClose }: Props = $props();
</script>
<Modal title="About" {onClose} maxWidth="400px">
<div class="content">
<div class="inner">
<p>
An open source project that helps you keep the content you are watching
or playing organized and places you in control.
</p>
<div class="horizontal-icon-list">
<a
href="https://github.com/sbondCo/Watcharr"
target="_blank"
title="Github"
>
<Icon i="github" wh={60} />
Source<br />
Code
</a>
<a
href="https://watcharr.app/"
target="_blank"
title="Watcharr Website & Documentation"
>
<Icon i="website" wh={60} />
Website<br />
& Docs
</a>
</div>
<h5 class="norm">Watcharr uses the following media databases:</h5>
<div class="horizontal-icon-list">
<a href="https://www.themoviedb.org/" target="_blank" title="TMDB">
<Icon i="tmdb" wh={60} />
</a>
<a href="https://www.igdb.com/" target="_blank" title="IGDB">
<Icon i="igdb" wh={60} />
</a>
</div>
<h5 class="norm">
<!-- Linking to the file in `dev` branch would break every old version of
Watcharr if the file were ever moved in the future. Using the current version
as the branch should ensure this file is always accessible (but only as up to
date as the current version) -->
<a
href="https://github.com/sbondCo/Watcharr/blob/v{__WATCHARR_VERSION__}/ATTRIBUTION.md"
target="_blank"
>
See our attribution file.
</a>
</h5>
</div>
</div>
</Modal>
<style lang="scss">
p {
margin: 8px 0px;
}
h5.norm {
margin: 8px 0px;
> a {
text-decoration: underline;
}
}
div.horizontal-icon-list {
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 20px;
padding-top: 5px;
> a {
display: flex;
flex-flow: column;
align-items: center;
gap: 5px;
margin: 0 10px;
text-align: center;
}
}
a {
transition: opacity 150ms ease-in;
&:hover {
opacity: 0.5;
}
}
</style>
+1
View File
@@ -9,6 +9,7 @@
store.wlDetailedView = store.wlDetailedView.filter((a) => a !== d);
} else {
store.wlDetailedView.push(d);
store.wlDetailedView = store.wlDetailedView;
}
}
</script>
+29 -2
View File
@@ -7,9 +7,11 @@
import { goto } from "$app/navigation";
import { clearWatcharrData } from "../logout";
import { notify } from "../util/notify";
import AboutModal from "./AboutModal.svelte";
let user = $derived(store.userInfo);
let proxyUserLogoutShown = $state(false);
let aboutModalOpen = $state(false);
function logout() {
if (user?.type === UserType.Proxy) {
@@ -61,9 +63,13 @@
notify({ id: nid, type: "error", text: "Failed to get link" });
}
}
function closeAbout() {
aboutModalOpen = false;
}
</script>
<Menu conf={{ arrowRight: "10px" }}>
<Menu conf={{ width: "140px", arrowRight: "10px" }}>
{#if user?.username}
<h5 title={user.username}>Hi {user.username}!</h5>
{/if}
@@ -85,5 +91,26 @@
{#if proxyUserLogoutShown}
<ProxyUserLogoutModal onClose={() => (proxyUserLogoutShown = false)} />
{/if}
<span>v{__WATCHARR_VERSION__}</span>
<span>
<button
class="menu-footer"
onclick={() => {
aboutModalOpen = !aboutModalOpen;
}}
>
about
</button>
|
<a
class="menu-footer"
href="https://github.com/sbondCo/Watcharr/releases"
target="_blank"
>
v{__WATCHARR_VERSION__}
</a>
</span>
</Menu>
{#if aboutModalOpen}
<AboutModal onClose={closeAbout} />
{/if}
+30 -2
View File
@@ -6,6 +6,7 @@
import { store } from "@/store.svelte";
import { RatingStep, RatingSystem } from "@/types";
import { onMount } from "svelte";
import { isTouch } from "../util/helpers";
interface Props {
rating: number | undefined;
@@ -26,6 +27,14 @@
* Percentage star step.
*/
let starStep = $state(10);
/**
* The scroll position at start of star pointer click,
* saved for comparison at end of star click. If same,
* new rating will be saved, otherwise ignored to fix
* issue where user is just trying to scroll down, but
* presses star accidentally.
*/
let scrollLocAtStart = 0;
const ratingDesc = [
"Apalling",
@@ -45,6 +54,16 @@
console.warn("saveSelectedRating: Rating not set, ignoring call.");
return;
}
// We attempt to avoid accidental clicks on stars being saved while trying
// to scroll down the page, so if the scroll pos has changed since the press
// started, ignore it. This issue only affects touch devices, so ignore on pc.
// Scroll pos has changed if starting pos has more than 10 dif than now.
if (isTouch() && Math.abs(scrollLocAtStart - window.scrollY) >= 10) {
console.info(
"saveSelectedRating: Scroll location has changed since star was pressed, not saving rating to avoid a misclick.",
);
return;
}
// Rating needs to always scale to out of 10 before saving,
// scaling down the shown percentage will work.
const r = Math.round(shownPerc) / 10;
@@ -119,6 +138,7 @@
ev: (TouchEvent | MouseEvent) & {
currentTarget: EventTarget & HTMLDivElement;
},
start = false,
) {
const rect = ev.currentTarget.getBoundingClientRect();
const x =
@@ -128,6 +148,9 @@
Math.ceil(Math.round((x * 100) / rect.width) / starStep) * starStep;
setHoveredRatingFromPerc(perc);
moveRatingText();
if (start) {
scrollLocAtStart = window.scrollY;
}
}
function handleKeyDown(
@@ -318,7 +341,7 @@ shownPerc: {shownPerc}<br /> -->
// this flow (touchstart -> touchend) for clicks too will
// workaround that difference.
ev.preventDefault();
handleMouseOver(ev);
handleMouseOver(ev, true);
}}
onmouseleave={(ev) => {
if (!ev.relatedTarget) {
@@ -343,7 +366,12 @@ shownPerc: {shownPerc}<br /> -->
handleRatingHoverEnd();
}}
onclick={() => {
saveSelectedRating();
// If tapping a star on mobile we don't want to save
// with onclick event, only the touch end to avoid double
// save.
if (!isTouch()) {
saveSelectedRating();
}
}}
onkeydown={(ev) => handleKeyDown(ev)}
role="button"
-22
View File
@@ -1,10 +1,8 @@
import { store } from "@/store.svelte";
import {
UserPermission,
type Icon,
type MediaType,
type TMDBContentCreditsCrew,
type Theme,
type TokenClaims,
type Watched,
type WatchedStatus,
@@ -294,26 +292,6 @@ export function getOrdinalSuffix(i: number) {
return "th";
}
/**
* Toggle site wide theme.
* @param theme The theme to switch to.
* @param updateStore Should the store be updated to new theme?
* **If set to `false`, state should be manually updated.**
*/
export function toggleTheme(theme: Theme, updateStore = true) {
if (theme === "dark") {
document.documentElement.classList.add("theme-dark");
if (updateStore) {
store.appTheme = "dark";
}
} else {
document.documentElement.classList.remove("theme-dark");
if (updateStore) {
store.appTheme = "light";
}
}
}
export function parseTokenPayload(): TokenClaims | undefined {
try {
const token = localStorage.getItem("token");
+66
View File
@@ -0,0 +1,66 @@
// App Theme logic.
import { browser } from "$app/environment";
import { store } from "@/store.svelte";
import type { Theme } from "@/types";
/**
* Utility function to handle media queries for theme preferences.
*/
const prefersDarkThemeQuery: MediaQueryList | undefined = browser
? window.matchMedia("(prefers-color-scheme: dark)")
: undefined;
/**
* prefersDarkThemeQuery onChange handler.
*/
function prefersDarkThemeChanged(e: MediaQueryListEvent) {
console.info(
"prefersDarkThemeChanged: User preferred theme has changed. prefersDark:",
e.matches,
);
document.documentElement.classList.toggle("theme-dark", e.matches);
}
/**
* Toggle site wide theme.
* @param theme The theme to switch to.
* @param updateStore Should the store be updated to new theme?
* **If set to `false`, state should be manually updated.**
*/
export function toggleTheme(theme: Theme, updateStore = true) {
if (updateStore) {
store.appTheme = theme;
}
switch (theme) {
case "dark":
document.documentElement.classList.add("theme-dark");
break;
case "light":
document.documentElement.classList.remove("theme-dark");
break;
case "system":
document.documentElement.classList.toggle(
"theme-dark",
prefersDarkThemeQuery?.matches,
);
break;
}
if (prefersDarkThemeQuery) {
// Always remove first before adding to avoid cases
// where we add multiple events at same time.
prefersDarkThemeQuery.removeEventListener(
"change",
prefersDarkThemeChanged,
);
// If using system theme, add change listener (since
// system theme supports live updating when user
// preference changes on os or wherever).
if (theme === "system") {
prefersDarkThemeQuery.addEventListener("change", prefersDarkThemeChanged);
}
}
}
+42 -1
View File
@@ -43,13 +43,25 @@
function handleSearch(ev: KeyboardEvent) {
if (
ev.key === "ContextMenu" ||
ev.key === "Home" ||
ev.key === "End" ||
ev.key === "PageDown" ||
ev.key === "PageUp" ||
ev.key === "NumLock" ||
ev.key === "Escape" ||
ev.key === "Tab" ||
ev.key === "CapsLock" ||
ev.key === "OS" ||
ev.key === "ArrowLeft" ||
ev.key === "ArrowRight" ||
ev.key === "ArrowUp" ||
ev.key === "ArrowDown"
ev.key === "ArrowDown" ||
ev.key === "Control" ||
ev.key === "Alt" ||
ev.key === "AltGraph" ||
ev.key === "Shift" ||
ev.key === "Meta"
)
return;
clearTimeout(searchTimeout);
@@ -162,6 +174,33 @@
scroll = window.scrollY;
}
function focusSearch() {
try {
if (!mainSearchEl) {
console.warn("focusSearch: mainSearchEl not defined!");
return;
}
if (document.activeElement === mainSearchEl) {
console.debug("focusSearch: mainSearchEl is already focused.");
return;
}
mainSearchEl.focus();
} catch (err) {
console.error("focusSearch: Failed!", err);
}
}
function handleGlobalKeybind(ev: KeyboardEvent) {
switch (ev.key.toLowerCase()) {
case "s":
if (ev.ctrlKey) {
ev.preventDefault();
focusSearch();
}
break;
}
}
afterNavigate(() => {
decideOnNavSplit();
closeAllSubMenus();
@@ -172,10 +211,12 @@
decideOnNavSplit();
window.addEventListener("resize", decideOnNavSplit);
window.document.addEventListener("scroll", docOnScroll);
window.document.addEventListener("keydown", handleGlobalKeybind);
return () => {
window.removeEventListener("resize", decideOnNavSplit);
window.document.removeEventListener("scroll", docOnScroll);
window.document.removeEventListener("keydown", handleGlobalKeybind);
};
} else {
console.error(
+6 -8
View File
@@ -225,7 +225,7 @@
}
}
if (h.year) {
t.year = h.year;
t.year = Number(h.year);
}
if (ratingsEntry && ratingsEntry?.userRating) {
t.rating = Number(ratingsEntry.userRating);
@@ -314,7 +314,7 @@
const t: ImportedList = {
tmdbId: v.content.tmdbId,
name: v.content.title,
year: new Date(v.content.release_date)?.getFullYear()?.toString(),
year: new Date(v.content.release_date)?.getFullYear(),
type: v.content.type,
rating: v.rating,
status: v.status,
@@ -430,7 +430,7 @@
// Build toImport array
const toImport: ImportedList[] = [];
const fileText = await readFile(new FileReader(), file);
const jsonData = JSON.parse(fileText)["media"] as any[];
const jsonData = JSON.parse(fileText)["metadata"] as any[];
for (const v of jsonData) {
if (
!v.source_id ||
@@ -491,11 +491,9 @@
? v.reviews[0].review?.text
: "",
// Ryot does not support overall rating for shows
rating:
v.lot === "movie" && v.reviews?.length
? validifyRating(Number(v.reviews[0].rating))
: undefined,
rating: v.reviews?.length
? validifyRating(Number(v.reviews[0].rating))
: undefined,
datesWatched:
v.lot === "movie" && v.seen_history?.length
+35 -18
View File
@@ -1,4 +1,4 @@
<!--
<!--
/import/process is for processing the
selected files data. Here it will be
displayed and imported.
@@ -74,7 +74,7 @@
const l: ImportedList = { name: el };
const year = el.match(yearRegex);
if (year && year.length > 0) {
l.year = year[0].replaceAll(/\(|\)/g, "");
l.year = Number(year[0].replaceAll(/\(|\)/g, ""));
l.name = l.name.replace(yearRegex, "").trim();
}
rList.push(l);
@@ -98,7 +98,7 @@
? new Date(el["Release Date"])
: undefined;
if (year) {
l.year = String(year.getFullYear());
l.year = year.getFullYear();
}
if (el.Type === "movie" || el.Type === "tv") {
l.type = el.Type;
@@ -164,19 +164,35 @@
? new Date(el["Release Date"])
: undefined;
if (year) {
l.year = String(year.getFullYear());
l.year = year.getFullYear();
}
if (type === "movie") {
l.type = "movie";
} else if (type === "tv series") {
l.type = "tv";
} else if (type === "tv episode") {
l.type = "tv_episode";
} else {
console.warn("Skipping item with invalid type", `(${type})`, el);
anySkipped = true;
continue;
switch (type) {
case "movie":
case "video":
case "tv movie":
case "short":
l.type = "movie";
break;
case "tv series":
case "tv mini series":
case "tv special":
case "tv short":
l.type = "tv";
break;
case "tv episode":
l.type = "tv_episode";
break;
default:
console.warn(
"Skipping item with invalid type",
`(${type})`,
el,
);
anySkipped = true;
continue;
}
if (imdbId) {
l.imdbId = imdbId;
}
@@ -385,7 +401,7 @@
const lo = { name: ev.currentTarget.value } as ImportedList;
const yearEl = document.getElementById("addYear") as HTMLInputElement;
if (yearEl?.value) {
lo.year = yearEl.value;
lo.year = Number(yearEl.value);
}
rList.push(lo);
rList = rList;
@@ -495,8 +511,7 @@
w.content?.type === "movie"
? w.content?.release_date
: w.content?.first_air_date;
if (release)
item.year = String(new Date(Date.parse(release)).getFullYear());
if (release) item.year = new Date(Date.parse(release)).getFullYear();
item.type = w.content?.type;
store.watchedList.push(w);
}
@@ -709,7 +724,9 @@
{#if importMultiItem}
<Modal
title="Multiple Results Found"
desc="Select the correct item for {importMultiItem.original.name}"
desc="Select the correct item for {importMultiItem.original
.name} {importMultiItem.original.year &&
'(' + importMultiItem.original.year + ')'}"
onClose={() => {
importMultiItem?.callback("closed results modal");
importMultiItem = undefined;
+23 -5
View File
@@ -7,11 +7,7 @@
import Stat from "@/lib/stats/Stat.svelte";
import Stats from "@/lib/stats/Stats.svelte";
import { updateUserSetting } from "@/lib/util/api";
import {
getOrdinalSuffix,
monthsShort,
toggleTheme,
} from "@/lib/util/helpers";
import { getOrdinalSuffix, monthsShort } from "@/lib/util/helpers";
import { store } from "@/store.svelte";
import { UserType, type Image, type Profile } from "@/types";
import axios from "axios";
@@ -21,6 +17,7 @@
import SyncModal from "./modals/SyncModal.svelte";
import RegionDropDown from "@/lib/RegionDropDown.svelte";
import RatingSetting from "@/lib/rating/RatingSetting.svelte";
import { toggleTheme } from "@/lib/util/theme";
let user = $derived(store.userInfo);
let settings = $derived(store.userSettings);
@@ -218,6 +215,13 @@
<div class="theme">
<h4 class="norm">Theme</h4>
<div class="row">
<button
class={`plain${selectedTheme === "system" ? " selected" : ""}`}
id="system"
onclick={() => toggleTheme("system")}
>
<span>system</span>
</button>
<button
class={`plain${selectedTheme === "light" ? " selected" : ""}`}
id="light"
@@ -504,6 +508,20 @@
}
}
&#system {
background: linear-gradient(to right bottom, white 50%, black 50.3%);
outline-color: black;
span {
mix-blend-mode: difference;
}
&:hover {
color: white;
-webkit-text-stroke: 0.5px white;
}
}
&.selected {
outline-color: gold !important;
}
+4 -7
View File
@@ -12,7 +12,7 @@ import type {
} from "./types";
import type { Notification } from "./lib/util/notify";
import { browser } from "$app/environment";
import { toggleTheme } from "./lib/util/helpers";
import { toggleTheme } from "./lib/util/theme";
export const defaultSort = ["DATEADDED", "DOWN"];
@@ -54,7 +54,7 @@ const _store: Store = $state({
notifications: [],
activeSort: defaultSort,
activeFilters: { type: [], status: [] },
appTheme: "light",
appTheme: "system",
importedList: undefined,
parsedImportedList: undefined,
searchQuery: "",
@@ -186,7 +186,7 @@ export const clearAllStores = () => {
store.watchedList = [];
store.notifications = [];
store.activeSort = defaultSort;
store.appTheme = "light";
store.appTheme = "system";
store.importedList = undefined;
store.parsedImportedList = undefined;
store.searchQuery = "";
@@ -244,10 +244,7 @@ function rehydrateStore() {
$state.snapshot(store.appTheme),
);
} else {
let defTheme: Theme = "light";
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
defTheme = "dark";
}
let defTheme: Theme = "system";
_store.appTheme = defTheme;
toggleTheme(defTheme, false);
console.debug(
+7 -3
View File
@@ -57,9 +57,13 @@ export type Icon =
| "sparkles"
| "tag"
| "ticket"
| "lock-closed";
| "lock-closed"
| "github"
| "website"
| "tmdb"
| "igdb";
export type Theme = "light" | "dark";
export type Theme = "light" | "dark" | "system";
export type WLDetailedViewOption =
| "statusRating"
@@ -902,7 +906,7 @@ export interface ImportResponse {
export interface ImportedList {
tmdbId?: number;
name: string;
year?: string;
year?: number;
type?: ContentType;
state?: string;
rating?: number;