Compare commits

...

1211 commits

Author SHA1 Message Date
ThaUnknown
4cc35e56d9
fix: offline cache not working
Some checks failed
Check / check (push) Has been cancelled
2025-10-19 03:01:56 +02:00
ThaUnknown
8d71c5bff3
chore: deprecate domain
Some checks failed
Check / check (push) Has been cancelled
2025-10-14 22:06:52 +02:00
ThaUnknown
43d5bc5224
feat: improve relation graph with episode count and format 2025-10-14 16:26:50 +02:00
ThaUnknown
77dc3c28f3
feat: new more performant cache 2025-10-13 19:21:32 +02:00
ThaUnknown
49a5e26155
feat: add confirmation dialog for library deletions
fix: entries not being deselected after deletion [yikes!!!!]
2025-10-13 17:32:22 +02:00
ThaUnknown
e9faddc96f
fix: hold to ff, cycle subtitles backwards when holding shift, disable chromatic abberation animation
fix: validate entries when app first loads but cache doesnt sync with online, this fixes issues when syncing across multiple devices
2025-10-13 16:54:18 +02:00
ThaUnknown
a79b993fbd
fix: actually require all NNTP properties 2025-10-09 02:35:25 +02:00
ThaUnknown
fcb4139d68
fix: dont query NNTP without pass 2025-10-09 02:34:07 +02:00
ThaUnknown
f2b6f12fcb
feat: NNTP streaming 2025-10-09 00:46:19 +02:00
ThaUnknown
de3da8acf8
feat: hide hentai by default
Some checks failed
Check / check (push) Has been cancelled
fix: improve airing schedule results
2025-09-29 17:30:21 +02:00
ThaUnknown
bccaac3c24
fix: setting desc and UI scale float
Some checks failed
Check / check (push) Has been cancelled
2025-09-22 20:10:43 +02:00
ThaUnknown
7da60e252a
fix: playbackRate bounds, score scroll 2025-09-22 20:05:01 +02:00
ThaUnknown
7bfdd4ab79
fix: remove default install of extensions 2025-09-22 14:23:42 +02:00
ThaUnknown
5f37eebf87
fix: adjust animation timmings 2025-09-17 01:05:17 +02:00
ThaUnknown
015676648b
feat: preload fonts 2025-09-16 22:04:31 +02:00
ThaUnknown
b1ac5422b8
fix: wait for page preload to finish before exiting splash 2025-09-16 20:12:46 +02:00
ThaUnknown
9c1359b5d4
feat: splash screen for loading 2025-09-16 20:00:41 +02:00
ThaUnknown
761cc038e4
fix: more strict episode number type fixes 2025-09-15 17:13:05 +02:00
ThaUnknown
0ecb194a45
fix: episode number not being parsed correctly 2025-09-15 17:10:52 +02:00
ThaUnknown
700fabd970
fix: DoH auto-opening on startup 2025-09-14 09:54:33 +02:00
ThaUnknown
12eb271873
fix: properly fix checkbox 2025-09-13 22:40:14 +02:00
ThaUnknown
65cff92b52
fix: checkbox oops 2025-09-13 21:02:44 +02:00
ThaUnknown
61b587f2b5
feat: show total episodes in player
fix: checkboxes in library
2025-09-13 20:52:53 +02:00
ThaUnknown
abdf02d9c5
fix: set dns to empty on disable 2025-09-13 20:01:01 +02:00
ThaUnknown
77dc221578
Merge branch 'master' of https://github.com/thaunknown/miru 2025-09-12 16:38:48 +02:00
ThaUnknown
2ca71a31c6
fix: remove extension/repository search/filtering, people are stupid and think its the add button 2025-09-12 16:38:44 +02:00
ThaUnknown
df64f26fa5
fix: remove extension/repository search/filtering, people are stupid and think its the add button 2025-09-12 16:38:18 +02:00
ThaUnknown
8218833448
feat: ui scale setting as slider 2025-09-12 12:36:55 +02:00
ThaUnknown
4deacc6471
feat: support ALL for extension languages
feat: accented progress bar for episodelist
2025-09-12 10:59:11 +02:00
ThaUnknown
7b92b594c5
feat: add row select count to library table 2025-09-12 09:55:26 +02:00
ThaUnknown
bf2e645daa
fix: remove global app chat 2025-09-11 21:09:42 +02:00
ThaUnknown
3a15a1fcf3
fix: remove transparency 2025-09-11 21:05:12 +02:00
ThaUnknown
14a21b1051
fix: dragging of relations 2025-09-11 16:52:41 +02:00
ThaUnknown
78e16e7210
fix: imports 2025-09-11 16:47:40 +02:00
ThaUnknown
b7e06e89cb
fix: scrolling in view anime page
feat: new relations tree
2025-09-11 16:38:23 +02:00
ThaUnknown
4efd9449d6
fix: use load img for profile banners 2025-09-07 19:46:58 +02:00
ThaUnknown
a670e1c7cd
fix: disable audio scrolling in player when a modal is visible 2025-09-07 16:15:14 +02:00
ThaUnknown
3d51e9a084
fix: skip a little past the chapter end 2025-09-06 14:24:44 +02:00
ThaUnknown
e92efc3e20
feat: progress loader button for autoskip op/ed 2025-09-05 18:57:05 +02:00
ThaUnknown
da4d56f44d
fix: bring searchmodal cards more inline with episode cards 2025-09-05 16:53:51 +02:00
ThaUnknown
56fc8f9a6d
fix: properly center release group, clip oveflow 2025-09-05 01:26:31 +02:00
ThaUnknown
6bd2d1105e
fix: remove debug lol 2025-09-05 01:22:49 +02:00
ThaUnknown
3573a63dfd
fix: missing dual audio tag on searchmodal
fix: improve group parsing on searchmodal
fix: bad tag replacements on searchmodal
feat: redesign searchmodal, improve visibility
2025-09-05 01:21:43 +02:00
ThaUnknown
1cbc29f96a
feat: better looking modals
chore: split video player into sub components
2025-09-04 19:48:16 +02:00
ThaUnknown
58d9854b79
feat: scroll wheen in player
feat: track change and volume animations/toasts
2025-09-03 17:03:51 +02:00
ThaUnknown
34cdb22ae8
feat: auto-set rewatch/watching status when starting playback of episode 1 2025-09-03 00:42:22 +02:00
ThaUnknown
9151d37754
fix: android gestures attempt 2
fix: unclickable space in home screen highlight
2025-09-02 21:20:57 +02:00
ThaUnknown
a0561ec0f7
fix: attempt to fix gestures breaking seekbar on android 2025-09-02 21:15:53 +02:00
ThaUnknown
2a594255a4
chore: lockfile 2025-09-02 19:57:29 +02:00
ThaUnknown
8e5ffd45db
feat: cycle subtitles to off
fix: more forgiving checkbox button
2025-09-02 17:10:48 +02:00
ThaUnknown
132b805ff3
fix: revert in-world torrent port 2025-09-02 16:50:14 +02:00
ThaUnknown
cbe5392d5f
chore: add nocheck for TS deps 2025-09-02 16:34:37 +02:00
ThaUnknown
ced4296fae
feat: enable rescan and deletion
perf: in-world messageport
2025-09-02 15:55:10 +02:00
ThaUnknown
e7b168ca09
chore: cloudflare struggling with dependency resolution 2025-09-02 01:26:56 +02:00
ThaUnknown
bdbcacb3ee
fix: w2g undefined? 2025-09-02 01:16:31 +02:00
ThaUnknown
9e1cdb7017
feat: library and files filtering
feat: library rescan and delete buttons [disabled for now]
2025-09-01 22:57:08 +02:00
ThaUnknown
7e8ac47cdf
feat: improve threads, add markdown editor 2025-09-01 15:55:44 +02:00
ThaUnknown
8dd43a635b
feat: animated icons 2025-08-31 21:19:24 +02:00
ThaUnknown
0f0f06d6aa
fix: right...
Some checks failed
Check / check (push) Has been cancelled
2025-08-29 09:31:43 +02:00
ThaUnknown
bd5aa6652d
fix: entryeditor metadata not updating
Some checks are pending
Check / check (push) Waiting to run
fix: chapters not capitalized in video player
2025-08-28 16:55:36 +02:00
ThaUnknown
313be6bfd1
perf: intrinsic size on anime cards
Some checks are pending
Check / check (push) Waiting to run
perf: pre-load downloads library
2025-08-28 13:47:28 +02:00
ThaUnknown
57cb165d55
fix: rare state error in toFixed
Some checks are pending
Check / check (push) Waiting to run
2025-08-27 23:38:00 +02:00
ThaUnknown
589b3170b1
fix: oops import order 2025-08-27 23:05:01 +02:00
ThaUnknown
c5c6c35799
fix: reduce caching to 14 days
fix: episode list width on external player on mobile
fix: start miniplayer dragging at >3px of movement
fix: seekbar getting stuck when using android swipe gestures
fix: android popups being weird width [maybe]
2025-08-27 23:01:45 +02:00
ThaUnknown
3e94d66b29
fix: more specific audio exclusions for android
Some checks failed
Check / check (push) Has been cancelled
2025-08-07 20:56:52 +02:00
ThaUnknown
2a4dcb0f24
feat: add profile command
Some checks failed
Check / check (push) Has been cancelled
2025-08-02 00:19:01 +02:00
ThaUnknown
b32b5035b8
fix: resolver failing on some 2nd seasons
Some checks are pending
Check / check (push) Waiting to run
2025-08-01 17:13:40 +02:00
ThaUnknown
d7c80a844c
feat: better dates in library table 2025-08-01 14:36:48 +02:00
ThaUnknown
4cc501feaf
fix: filler episode offset by 1
Some checks are pending
Check / check (push) Waiting to run
feat: improve torrent client tables
2025-08-01 14:09:31 +02:00
ThaUnknown
39db7af384
fix: binds on android
Some checks failed
Check / check (push) Has been cancelled
2025-07-30 18:55:48 +02:00
ThaUnknown
7869123930
fix: ah... 2025-07-30 18:14:46 +02:00
ThaUnknown
d50f1304c5
fix: proper fix for subtitle squares on nl 2025-07-30 18:06:05 +02:00
ThaUnknown
ec26b46f76
fix: scroll to bottom in w2g, app chat
fix: auto-contrast text in search modal
fix: new lines on bad subs
2025-07-30 18:01:42 +02:00
ThaUnknown
e76e01df46
feat: add safety checks to loading last torrent
Some checks are pending
Check / check (push) Waiting to run
2025-07-29 22:03:52 +02:00
ThaUnknown
0963c69a2b
chore: android review ^^
Some checks are pending
Check / check (push) Waiting to run
2025-07-29 19:10:54 +02:00
ThaUnknown
4206bef69b
feat: colored anime pages, clickable genres, and meta
fix: better color contrast text calculation
fix: bad bg color for spoilers
2025-07-29 13:04:12 +02:00
ThaUnknown
fde2528df1
feat: log retry better
Some checks failed
Check / check (push) Has been cancelled
2025-07-27 20:37:00 +02:00
ThaUnknown
51ed969702
fix: actually wait for store to load before making requests 2025-07-27 20:35:06 +02:00
ThaUnknown
b73ee4a841
fix: imlprove debug formatters
Some checks are pending
Check / check (push) Waiting to run
2025-07-27 19:23:18 +02:00
ThaUnknown
967ad751b4
fix: direct dep debug log 2025-07-27 18:45:05 +02:00
ThaUnknown
7ca22198b3
feat: debug logging 2025-07-27 18:22:13 +02:00
ThaUnknown
28283725e0
fix: load al cache before app
Some checks are pending
Check / check (push) Waiting to run
2025-07-26 12:00:26 +02:00
ThaUnknown
8f17d9f3ca
fix: hide subs on seeking
Some checks are pending
Check / check (push) Waiting to run
2025-07-25 23:02:44 +02:00
ThaUnknown
ff4598cc84
fix: some settings updating when not necessary
fix: re-introduce app chat
2025-07-25 22:57:59 +02:00
ThaUnknown
715374711c
feat: persistent playbackrate
Some checks are pending
Check / check (push) Waiting to run
fix: don't autoselect tracks when lang is none
2025-07-24 18:26:31 +02:00
ThaUnknown
7f84100c22
feat: add partial support for ancient browsers
Some checks failed
Check / check (push) Has been cancelled
2025-07-23 15:41:56 +02:00
ThaUnknown
7ff57561c2
fix: text wrapping on setup
Some checks are pending
Check / check (push) Waiting to run
2025-07-22 22:29:53 +02:00
ThaUnknown
4084293d46
fix: try fix hover updates on mobile touch 2025-07-22 20:18:55 +02:00
ThaUnknown
76b1b2dfd6
fix: player options not clickable on mobile 2025-07-22 18:30:27 +02:00
ThaUnknown
13eab72944
feat: double tap to seek
Some checks are pending
Check / check (push) Waiting to run
2025-07-22 12:41:53 +02:00
ThaUnknown
490937a271
feat: auto-enter fullscreen in player on androidTV 2025-07-22 10:14:42 +02:00
ThaUnknown
3d84a63145
fix: bad navigation logic
Some checks are pending
Check / check (push) Waiting to run
2025-07-22 09:11:53 +02:00
ThaUnknown
118d40d3c6
fix: navigate to player on PiP media control
Some checks are pending
Check / check (push) Waiting to run
2025-07-22 01:05:07 +02:00
ThaUnknown
49427ed00d
fix: don't allow path editing on android 2025-07-21 21:39:04 +02:00
ThaUnknown
199dd66c8b
fix: actually update extensions 2025-07-21 21:20:38 +02:00
ThaUnknown
9f28b570d5
fix: support MAL on android 2025-07-21 20:53:25 +02:00
ThaUnknown
19b8c412fa
fix: google reviewers physically are too inept to read text 2025-07-21 18:32:11 +02:00
ThaUnknown
89c337fe31
feat: re-introduce partial batches 2025-07-21 17:02:42 +02:00
ThaUnknown
36df9897cc
fix: pointer release errors on android
Some checks are pending
Check / check (push) Waiting to run
2025-07-20 18:12:24 +02:00
ThaUnknown
7875a57af0
fix: make setting card select
fix: improve download location switching reliability during download
feat: validate directory availability, disable transparency on linux
feat: force CORS on 429 from AniList
2025-07-20 18:11:20 +02:00
ThaUnknown
4bf572e71f
feat: better android file picker, validate that selected directories have read/write permissions 2025-07-20 16:38:48 +02:00
ThaUnknown
6b37f517c9
fix: more hold to FF issues
Some checks are pending
Check / check (push) Waiting to run
2025-07-20 02:49:33 +02:00
ThaUnknown
c5ca279227
fix: support pointer cancelling for other components too 2025-07-20 02:44:01 +02:00
ThaUnknown
71d91d2a8e
fix: hold to FF pointer cancel 2025-07-20 02:42:13 +02:00
ThaUnknown
ad4ed78b76
fix: made text selectable 2025-07-20 02:16:13 +02:00
ThaUnknown
1df63a0716
fix: improve keyboard navigation in text inputs
fix: w2g link pasting
2025-07-20 02:13:14 +02:00
ThaUnknown
1c76730528
fix: only ff on lmouse 2025-07-20 00:53:03 +02:00
ThaUnknown
be67c21bea
fix: increase seekbar x2 click to fullscreen on android
Some checks are pending
Check / check (push) Waiting to run
2025-07-19 19:52:58 +02:00
ThaUnknown
e435e09b6d
fix: polyfill grupby 2025-07-19 19:32:57 +02:00
ThaUnknown
2cd4764cbd
fix: promise withresolvers polyfill 2025-07-19 19:10:29 +02:00
ThaUnknown
f6297e8be3
fix: remove broken badly screen 2025-07-19 18:58:35 +02:00
ThaUnknown
f28784583f
feat: view transitions [not done correctly, but i dont understand it]
Some checks are pending
Check / check (push) Waiting to run
2025-07-19 12:41:14 +02:00
ThaUnknown
0fb10cce85
fix: make settings handle better on small phone displays
Some checks are pending
Check / check (push) Waiting to run
2025-07-19 01:13:42 +02:00
ThaUnknown
4d67618390
fix: android mediastate
Some checks are pending
Check / check (push) Waiting to run
2025-07-18 20:32:17 +02:00
ThaUnknown
4cc657d818
fix: deband for anamorphic videos 2025-07-18 18:40:49 +02:00
ThaUnknown
7e43d855f2
fix: airdate entries 2025-07-18 16:27:55 +02:00
ThaUnknown
8c5e19a9b7
perf: further improvements to ep list speed for onepiece
Some checks are pending
Check / check (push) Waiting to run
2025-07-18 14:32:57 +02:00
ThaUnknown
35bc9a48c0
fix: improve the performance of episode scoping 2025-07-18 13:17:21 +02:00
ThaUnknown
56c3d7359c
fix: improve setup and search on tiny mobile displays
Some checks are pending
Check / check (push) Waiting to run
2025-07-18 02:28:09 +02:00
ThaUnknown
0ed81a4c07
fix: dont allow back navigation on setup
fix: togglegroup navigation in settings
fix: combobox navigation
fix: schedule skeletonloader on android
fix: disable autofocus on modals
fix: episodelist overflowing
fix: mobile player buttons not working on android
2025-07-18 01:27:54 +02:00
ThaUnknown
39aed8afb8
feat: re-introduce airdate based episode limiting
Some checks are pending
Check / check (push) Waiting to run
2025-07-17 18:43:07 +02:00
ThaUnknown
3ad8d5039e
fix: airdate episode match 2025-07-17 17:48:12 +02:00
ThaUnknown
ce9e01c2c2
fix: improve episode search, more date info, dont query batches or movies when not necessary 2025-07-17 17:24:54 +02:00
ThaUnknown
fabff3a32c
fix: disable focustrap for profile icons
Some checks are pending
Check / check (push) Waiting to run
2025-07-17 13:38:29 +02:00
ThaUnknown
cc1d4df640
fix: make keyboard selected elements stand out more 2025-07-17 13:13:32 +02:00
ThaUnknown
d8ebb596e5
fix: rating scale on kitsu, local and MAL
fix: initial focus element when using keyboard navigation
2025-07-17 13:08:17 +02:00
ThaUnknown
1c39526afb
temp: hide chat
Some checks are pending
Check / check (push) Waiting to run
2025-07-17 00:07:23 +02:00
ThaUnknown
9bd6b6b12b
fix: try to fix continue watching not updating in rare cases
Some checks are pending
Check / check (push) Waiting to run
2025-07-16 21:51:25 +02:00
ThaUnknown
c8af048473
fix: further improve navigation and visiblity of selected buttons 2025-07-16 20:32:46 +02:00
ThaUnknown
71947f0c5e
fix: further timming tests
Some checks are pending
Check / check (push) Waiting to run
2025-07-16 00:40:02 +02:00
ThaUnknown
57cf3956a2
fix: version oops 2025-07-16 00:36:37 +02:00
ThaUnknown
bed0bee507
fix: reduce re-immerse delay 2025-07-16 00:34:55 +02:00
ThaUnknown
0a2bce9d78
fix: initial isMiniplayer check for external player 2025-07-16 00:22:53 +02:00
ThaUnknown
3c132aeb3c
feat: DoH on android, delay unimerse on seeking, don't autostart external player 2025-07-16 00:17:54 +02:00
ThaUnknown
32a777b997
fix: player settigns button on atv
Some checks failed
Check / check (push) Has been cancelled
2025-07-14 21:25:01 +02:00
ThaUnknown
c4b4cb0e6d
fix: hide bottom controls on weird androidTVs 2025-07-14 19:16:40 +02:00
ThaUnknown
204e9ad1ea
fix: some issues with TV navigation in player 2025-07-14 17:58:48 +02:00
ThaUnknown
ee98dcb58b
perf: disable blur and increase native call time on underpowered devices
fix: doubleclick seekbar on androidTV
feat: player button for androidTV
2025-07-14 17:08:23 +02:00
ThaUnknown
d8ada044ce
feat: disable performance heavy UI elements on underpowered devices 2025-07-14 15:13:59 +02:00
ThaUnknown
45a85644ca
fix: checkboxes on androidTV 2025-07-14 13:43:40 +02:00
ThaUnknown
e68a51399a
fix: androidTV scaling and navigation
Some checks are pending
Check / check (push) Waiting to run
2025-07-14 12:56:14 +02:00
ThaUnknown
1b63898e8b
fix: AL login popup size
Some checks are pending
Check / check (push) Waiting to run
fix: default sort on your list, search and move missed sequels down
2025-07-14 01:47:33 +02:00
ThaUnknown
a54a709c65
feat: support back gesture in episode and search modals
feat: immerse all ui when fastforwarding
fix: smaller mobile buttons on video player
fix: only show media track selection if supported
feat: hide settings overlay when activating PiP
feat: close hamburger menu on outside click and navigate
fix: mal and kitsu entry values getting overwritten
fix: no longer exclude ember
fix: some settings scaling on mobile
2025-07-14 00:59:17 +02:00
ThaUnknown
f078ae8f19
fix: touch support for miniplayer and fastforward
Some checks are pending
Check / check (push) Waiting to run
fix: mobile responsive UI for player episodelist, and settings pages
2025-07-13 15:48:23 +02:00
ThaUnknown
571efea41e
fix: support UI scale on android
Some checks failed
Check / check (push) Has been cancelled
2025-07-11 02:07:49 +02:00
ThaUnknown
83b3c8a1d9
fix: hide menubar on android 2025-07-10 19:49:01 +02:00
ThaUnknown
303a138107
feat: cancel thumbnailer if the render request is long-running
Some checks failed
Check / check (push) Has been cancelled
2025-07-09 17:01:52 +02:00
ThaUnknown
a0cbacd6c6
fix: try to improve video loading times in extreme cases
Some checks are pending
Check / check (push) Waiting to run
2025-07-08 22:16:49 +02:00
ThaUnknown
740857065c
fix: fullscreen exiting on next episode play
Some checks are pending
Check / check (push) Waiting to run
2025-07-08 17:45:02 +02:00
ThaUnknown
37acecddca
fix: mal redirects
Some checks are pending
Check / check (push) Waiting to run
2025-07-07 23:31:30 +02:00
ThaUnknown
86a305ce7c
feat: MAL sync 2025-07-07 20:21:59 +02:00
ThaUnknown
2c84ff0c62
fix: new repo URL
Some checks are pending
Check / check (push) Waiting to run
2025-07-07 10:43:36 +02:00
ThaUnknown
b0cc1cb760
fix: explicit package imports
Some checks are pending
Check / check (push) Waiting to run
2025-07-07 00:50:03 +02:00
ThaUnknown
f6918f4bc1
fix: 60s cooldown on refocus AL data updates, higher burst ratelimits 2025-07-07 00:45:24 +02:00
ThaUnknown
5d433c7788
fix: library table sometimes crashing 2025-07-06 23:18:00 +02:00
ThaUnknown
64298ff10d
fix: w2g/chat overflowing issues
Some checks are pending
Check / check (push) Waiting to run
fix: navigation scroll on anime page
feat: forums spoilers and youtube embeds
2025-07-06 16:18:13 +02:00
ThaUnknown
b258b67f1b
fix: bad logic on player navigate
Some checks are pending
Check / check (push) Waiting to run
2025-07-05 19:21:22 +02:00
ThaUnknown
5194b085a3
feat: better description UI for irc, w2g, and torrent client
fix: navigation with arrow keys on player
feat: view schedule without my list
2025-07-05 18:44:34 +02:00
ThaUnknown
b52d9dccc4
fix: w2g hanging when entering a new w2g lobby while in an existing w2g lobby
Some checks are pending
Check / check (push) Waiting to run
fix: hide NAT64 mappings
feat: increase maxpeers if forwarding is available
2025-07-05 15:34:01 +02:00
ThaUnknown
3720645775
fix: dont try to scrape peers while offline
fix: episodelist and library not navigating to player on media/episode select
feat: make banner image clickable
2025-07-05 13:55:35 +02:00
Cas_
b200e933b6
docs: fix embeds
Some checks failed
Check / check (push) Has been cancelled
2025-06-29 17:57:47 +02:00
ThaUnknown
6074dac1d5
docs: readme 2025-06-29 17:53:24 +02:00
ThaUnknown
d032ae36d1
fix: play button not working when nothing is loaded 2025-06-29 17:21:11 +02:00
ThaUnknown
df514c0fbe
fix: bump ver 2025-06-29 15:47:14 +02:00
ThaUnknown
86679f6398
fix: remember current episode in batch on reopen, play anime from current batch when using episodelist 2025-06-29 15:41:12 +02:00
ThaUnknown
f907a97358
feat: hide speeds on minimal player UI
Some checks are pending
Check / check (push) Waiting to run
2025-06-29 11:48:12 +02:00
ThaUnknown
73608972c6
fix: dont prevent paste 2025-06-29 10:45:25 +02:00
ThaUnknown
45018f9747
feat: support search sort by ascending
Some checks are pending
Check / check (push) Waiting to run
2025-06-29 00:13:10 +02:00
ThaUnknown
5e867d8558
fix: pad sidebar on mac 2025-06-29 00:04:39 +02:00
ThaUnknown
cbab1b2c71
feat: show playback rate in player, underline title in player on hover 2025-06-29 00:01:51 +02:00
ThaUnknown
f9105e5433
feat: show library entries when searching specific episode while offline 2025-06-28 23:48:25 +02:00
ThaUnknown
d611e4662d
fix: explain streamed download better 2025-06-28 23:39:17 +02:00
ThaUnknown
16c57f1fb6
feat: support for pasting images, w2g lobby links
fix: banner image darken not working
fix: make banner take up less space
2025-06-28 23:17:50 +02:00
ThaUnknown
d89b007c9e
fix: temp UI for app chat title/watch together title, UI needs redesign badly
Some checks are pending
Check / check (push) Waiting to run
2025-06-28 20:16:32 +02:00
ThaUnknown
4969644374
feat: offline library support
Some checks are pending
Check / check (push) Waiting to run
2025-06-28 00:06:46 +02:00
ThaUnknown
f481bf7c09
fix: play/pause button in miniplayer
Some checks failed
Check / check (push) Has been cancelled
2025-06-26 16:38:30 +02:00
ThaUnknown
ace3860226
fix: PiP play/pause button not updating
fix: PiP not opening on button click when video paused
fix: improve PiP performance
fix: improve deband performance
feat: miniplayer play/pause button
fix: hayase cache not saving correctly on first load
2025-06-26 15:42:13 +02:00
ThaUnknown
9a7ea1f888
fix: add forced update apology for broken auto-updater
Some checks are pending
Check / check (push) Waiting to run
2025-06-26 01:10:35 +02:00
ThaUnknown
ead30618f8
feat: new icon
Some checks are pending
Check / check (push) Waiting to run
2025-06-25 17:31:21 +02:00
ThaUnknown
95ed1aeaf1
feat: new torrent client UI
Some checks are pending
Check / check (push) Waiting to run
fix: better breakpoints code for JS
fix: macOS external player spawning
2025-06-25 00:31:02 +02:00
ThaUnknown
12155eaabb
feat: new torrent client UI 2025-06-24 16:51:27 +02:00
ThaUnknown
aabab32413
feat: native update handling for forced updates
Some checks failed
Check / check (push) Has been cancelled
2025-06-21 17:59:38 +02:00
ThaUnknown
a9415e59c0
feat: nicer sidebar buttons
Some checks are pending
Check / check (push) Waiting to run
fix: dragging in fullscreen
2025-06-20 22:13:43 +02:00
ThaUnknown
9dcdaf20c2
fix: #669 external player playlist
Some checks are pending
Check / check (push) Waiting to run
2025-06-20 14:13:37 +02:00
ThaUnknown
3cbb5e108e
fix: imports 2025-06-20 12:36:13 +02:00
ThaUnknown
163e6d580f
fix: add proper offline path, dont cache root path, turns out thats bad! 2025-06-20 12:20:25 +02:00
ThaUnknown
0cd0db7e53
feat: add debug logging to torrent client
Some checks are pending
Check / check (push) Waiting to run
2025-06-19 21:54:27 +02:00
ThaUnknown
0a2fbfec45
feat: login redirect route for AL [just in case]
Some checks failed
Check / check (push) Has been cancelled
2025-06-17 22:24:16 +02:00
ThaUnknown
56a1cfbc98
feat: support leaving chat, chat message toasts for non-guests IF logged into chat
Some checks are pending
Check / check (push) Waiting to run
2025-06-16 21:40:14 +02:00
ThaUnknown
361ca69f42
fix: panic 2025-06-16 20:30:30 +02:00
ThaUnknown
0db7c3bbd4
fix: anime incorrectly marked as completed when anilist doesn't provide an episode count 2025-06-16 19:51:46 +02:00
ThaUnknown
a5fa723db1
fix: dont query kitsu when not necessary 2025-06-16 18:21:34 +02:00
ThaUnknown
342327b14a
feat: log torrent errors
Some checks are pending
Check / check (push) Waiting to run
fix: disabling discord details
2025-06-15 23:40:47 +02:00
ThaUnknown
a9db439a26
feat: improve some setting descriptions
Some checks are pending
Check / check (push) Waiting to run
2025-06-15 23:08:41 +02:00
ThaUnknown
00dae69e9b
feat: re-introduce watch progress 2025-06-15 23:00:36 +02:00
ThaUnknown
d8c2a25a34
fix: w2g initial sync state, chat bug on message send
feat: message toasts for w2g
2025-06-15 20:47:54 +02:00
ThaUnknown
9b2df7646b
fix: w2g stutters 2025-06-15 17:18:09 +02:00
ThaUnknown
1cb234a368
fix: default native transparency, clamp scaling, fix linux icon 2025-06-15 15:26:32 +02:00
ThaUnknown
9f414cd7d3
fix: rewatch on complete
Some checks are pending
Check / check (push) Waiting to run
2025-06-15 12:17:25 +02:00
ThaUnknown
48f87a25d5
feat: new readme
Some checks are pending
Check / check (push) Waiting to run
feat: add DoH to setup
2025-06-15 01:24:35 +02:00
ThaUnknown
8b88e23594
fix: oopsie
Some checks are pending
Check / check (push) Waiting to run
2025-06-14 21:33:43 +02:00
ThaUnknown
c78b18c5e8
fix: episode list widths
fix: macOS menubar
2025-06-14 21:23:55 +02:00
ThaUnknown
5330207f12
fix: indent epispdelist 2025-06-14 17:28:14 +02:00
ThaUnknown
4486212fa9
hack: loosing sanity
Some checks failed
Check / check (push) Has been cancelled
2025-06-08 23:14:05 +02:00
ThaUnknown
b985a265b0
feat: add tests [just strict static analysis] 2025-06-08 22:43:41 +02:00
ThaUnknown
1eef1f25fe
hack: prevent spacebar interactions in player UI 2025-06-08 14:53:38 +02:00
ThaUnknown
d06c20ae52
fix: proper skeleton loaders for episode cards 2025-06-07 00:21:34 +02:00
ThaUnknown
8d500252c6
feat: search by image episode cards 2025-06-06 23:37:08 +02:00
ThaUnknown
51a2a6d736
fix: media banner flashing 2025-06-06 22:00:11 +02:00
ThaUnknown
bb9f7a79d0
feat: subtitle delay keybinds and info, keybind descriptions 2025-06-06 21:56:25 +02:00
ThaUnknown
14720a07c6
feat: kitsu sync, local sync continue/planning list
fix: fav and bookmark icon not updating for local sync
fix: cards not showing local progress
fix: animated anilist PFPs not working
fix: menubar being selectable
fix: offline banner moving content outside of screen
fix: local sync entry deletion being problematic
2025-06-06 18:53:43 +02:00
ThaUnknown
1f82dc8fa9
fix: dont constrain sub delay 2025-06-02 15:22:18 +02:00
ThaUnknown
11f8c58739
feat: add sub delay
fix: oopsie overwriting media resolve
2025-06-02 15:20:11 +02:00
ThaUnknown
8523232899
fix: bad null handling 2025-06-02 13:38:15 +02:00
ThaUnknown
5ddfc8338e
fix: how did this work...? 2025-06-01 22:48:53 +02:00
ThaUnknown
c2ad19261b
fix: language code names 2025-05-31 19:40:04 +02:00
ThaUnknown
0b64e43432
feat: detect external sub language based on content 2025-05-31 18:08:50 +02:00
ThaUnknown
9a230b302d
fix: improve navigating tabs, threads, menubar, player with keyboard 2025-05-31 02:01:58 +02:00
ThaUnknown
df57e3bc60
chore: bump ver 2025-05-30 20:29:56 +02:00
ThaUnknown
ef48ac12e5
fix: optimise asian fonts 2025-05-30 20:29:01 +02:00
ThaUnknown
869f012734
feat: support asian languages 2025-05-30 19:30:32 +02:00
ThaUnknown
fd01257bdf
feat: animethemes 2025-05-30 02:04:54 +02:00
ThaUnknown
bc35557ebd
feat: previously known as miru on first setup page
fix: initial subtitle override state
wip: animethemes
2025-05-29 22:59:43 +02:00
ThaUnknown
d632ad5b49
fix: correctly unscale style overrides 2025-05-29 14:15:17 +02:00
ThaUnknown
a6eebe4ebd
fix: style overrides scaling 2025-05-29 13:38:59 +02:00
ThaUnknown
936ff5daae
fix: reactive sub overrides 2025-05-29 02:31:20 +02:00
ThaUnknown
6dfc5f70e9
feat: subtitle dialogue style overrides, increase al cache duration, optimise fonts 2025-05-29 02:01:13 +02:00
ThaUnknown
393276c9e2
feat: proper changelog 2025-05-28 02:01:48 +02:00
ThaUnknown
e767d8b0cc
fix: OOPS 2025-05-28 01:39:18 +02:00
ThaUnknown
0adb515873
fix: ci 2025-05-28 01:34:51 +02:00
ThaUnknown
a22d5d16ef
feat: UI scale 2025-05-28 01:31:10 +02:00
ThaUnknown
0037dc2231
feat: greatly improve setup screen 2025-05-27 23:17:03 +02:00
ThaUnknown
c4ee54beba
fix: quality selection in fullscreen, pip only while playing, outdated player episodelist, save port availability 2025-05-27 20:46:21 +02:00
ThaUnknown
c5ff2a0104
fix: dont scroll to end of episode list when completed, unimmerse on pointermove 2025-05-24 21:18:34 +02:00
ThaUnknown
12a08f9bb7
feat: improve player navigation 2025-05-24 19:46:46 +02:00
ThaUnknown
b0662b4b1c
fix: improve typedef and type safety 2025-05-24 17:25:01 +02:00
ThaUnknown
612a13ad99
fix(native): forums opening links, link share, infinite scroll in search 2025-05-23 18:17:00 +02:00
ThaUnknown
035e1dfdac
fix: autoplay animation playing when no results are available 2025-05-23 16:26:38 +02:00
ThaUnknown
fb9ec3da12
fix: greatly improve home screen performance 2025-05-23 16:15:04 +02:00
ThaUnknown
d10ba49228
feat: readme and templates 2025-05-22 20:15:45 +02:00
ThaUnknown
696c32c5a8
append hayase 2025-05-22 18:32:40 +02:00
ThaUnknown
bebd53468c
chore: nuke 2025-05-22 18:21:55 +02:00
ThaUnknown
ec8074ff16
fix: config 2025-05-22 16:06:00 +02:00
ThaUnknown
e1e2fe14be
fix: finish w2g 2025-05-22 16:06:00 +02:00
ThaUnknown
11d069821f
fix: force dep 2025-05-22 16:05:59 +02:00
ThaUnknown
516f26d765
feat: W2G, persist search state tru navigation
fix: window title dissapearing lol
2025-05-22 16:05:59 +02:00
ThaUnknown
db2b0a738a
wip: initial kitsu impl 2025-05-22 16:05:59 +02:00
ThaUnknown
7ba810057e
fix: exit fullscreen on navigate, dont re-scan ports on any setting change
feat: find sub files, prefer non-forced tracks
2025-05-22 16:05:59 +02:00
ThaUnknown
d3ce9a629d
feat: proper token refresh 2025-05-22 16:05:59 +02:00
ThaUnknown
7157869fe8
chore: improve dev compile speeds and intellisense [monkey change, svelte doesn't like mass-export libs like icons] 2025-05-22 16:05:58 +02:00
ThaUnknown
94e62ebe48
feat: auto-hide miniplayer on pause 2025-05-22 16:05:58 +02:00
ThaUnknown
fa44f15776
fix: better UI update code for service worker 2025-05-22 16:05:58 +02:00
ThaUnknown
2b49145d24
fix: draggable links, torrent and anilist client loading inside setup, adding external subs crashing 2025-05-22 16:05:58 +02:00
ThaUnknown
1542dccf54
feat: hayase:// protocol handling 2025-05-22 16:05:58 +02:00
ThaUnknown
42977a921b
fix: improve AL error handling 2025-05-22 16:05:57 +02:00
ThaUnknown
8ff16ace6d
fix: cleaner deband code 2025-05-22 16:05:57 +02:00
ThaUnknown
c9a0a98fee
fix: right... cant call that 2025-05-22 16:05:57 +02:00
ThaUnknown
c7f3431798
fix: seek swallowing, seek preview cover 2025-05-22 16:05:57 +02:00
ThaUnknown
7c738fa01e
feat: initial miniplayer improvements, dragging, torrent loading feedback 2025-05-22 16:05:57 +02:00
ThaUnknown
e16bc903d4
fix: heart animation 2025-05-22 16:05:57 +02:00
ThaUnknown
a6e669c0ec
fix: reduce home screen query re-running
feat: thread title tooltip
2025-05-22 16:05:57 +02:00
ThaUnknown
db5d8f4362
fix: threads, comments, tooltip on player options playlist mark as complete for entries not on list 2025-05-22 16:05:57 +02:00
ThaUnknown
d4d51af0e2
fix: subtitle issues 2025-05-22 16:05:56 +02:00
ThaUnknown
2d6178c7e8
feat: sourcemap
fix: maybe improve thumbnailer perf
2025-05-22 16:05:56 +02:00
ThaUnknown
4c00e289ed
perf: change thumbnail quality
fix: naming of torrent port setting
fix: network setup speeds
2025-05-22 16:05:56 +02:00
ThaUnknown
8df081c2ec
fix: prevent user select in fullscreen mode 2025-05-22 16:05:56 +02:00
ThaUnknown
5ac86b8c98
fix: fullscreen issues in player 2025-05-22 16:05:56 +02:00
ThaUnknown
b76ce678df
feat: show errors in search when no results found
feat: file picker for subtitles in options
feat: drag/drop/paste subtitle files/text
fix: hide video on seek
fix: profile icon not centered
2025-05-22 16:05:55 +02:00
ThaUnknown
d2335b1e15
fix: improve hold to FF code 2025-05-22 16:05:55 +02:00
ThaUnknown
e1dbf1bd66
fix: playnext on batches
feat: download progress in status bar
chore: try logging subtitle listener errors
2025-05-22 16:05:55 +02:00
ThaUnknown
3ff14a94c6
fix: i got sick of anitomyscript, its now all an array 2025-05-22 16:05:55 +02:00
ThaUnknown
40fee5ffcc
feat: version info 2025-05-22 16:05:55 +02:00
ThaUnknown
eee9c549ab
fix: minor memory leaks, force remove unused dependencies, make banner show all releases 2025-05-22 16:05:55 +02:00
ThaUnknown
4da12bfd5d
feat: reset
fix: continue watching order on home screen
2025-05-22 16:05:55 +02:00
ThaUnknown
2fca2c4d4f
fix: improve bad PiP code 2025-05-22 16:05:54 +02:00
ThaUnknown
a095f91d37
fix: oops 2025-05-22 16:05:54 +02:00
ThaUnknown
47a9076474
feat: add onList search, clean up search a little bit 2025-05-22 16:05:54 +02:00
ThaUnknown
124e97f0a7
fix: skippable progress
fix: dont show dropped on schedule
2025-05-22 16:05:54 +02:00
ThaUnknown
78d6037272
fix: changing seek duration
feat: your list
fix: reduce thread queries
2025-05-22 16:05:54 +02:00
ThaUnknown
10c385e60f
fix:: more typos, repaing episode list on media change 2025-05-22 16:05:54 +02:00
ThaUnknown
13ab7ec214
fix: privacy policy url
fix: fitwidth previews
2025-05-22 16:05:54 +02:00
ThaUnknown
acce767c88
fix: setting descriptions and typos 2025-05-22 16:05:53 +02:00
ThaUnknown
1034966ab4
fix: resolver 2025-05-22 16:05:53 +02:00
ThaUnknown
667062031e
fix: chapters 2025-05-22 16:05:53 +02:00
ThaUnknown
ce3665f2d8
chore: ver bump 2025-05-22 16:05:53 +02:00
ThaUnknown
180ca53ac5
feat: license info
fix: thread tab and comments pagination
2025-05-22 16:05:53 +02:00
ThaUnknown
6a5937bd8c
hack: patch bad deband code 2025-05-22 16:05:53 +02:00
ThaUnknown
db9020fde2
fix: "video." calls re-painting video 2025-05-22 16:05:53 +02:00
ThaUnknown
b880c99be3
fix: properly implement setup version 2025-05-22 16:05:52 +02:00
ThaUnknown
7c9ffab987
feat: forums skeleloaders
fix: thread child comments [again]
feat: proper port support check
2025-05-22 16:05:52 +02:00
ThaUnknown
e3c96176d0
fix: correctly clean up deband 2025-05-22 16:05:52 +02:00
ThaUnknown
6057f8d57e
chore: better gitignore 2025-05-22 16:05:52 +02:00
ThaUnknown
f483e75e08
fix: hide on android 2025-05-22 16:05:52 +02:00
ThaUnknown
5161ebf368
fix: thumbnailer crashing
feat: hide to tray
2025-05-22 16:05:52 +02:00
ThaUnknown
5f82f0649f
fix: deband not working
fix: offline component
2025-05-22 16:05:52 +02:00
ThaUnknown
41994fe7fb
fix: initial subtitle track styling 2025-05-22 16:05:51 +02:00
ThaUnknown
ef4303810f
feat: profile view component 2025-05-22 16:05:51 +02:00
ThaUnknown
34f9a196ea
fix: make episodelist reactive
feat: allow pasting of torrent indentifiers into modal search
feat: media score in preview
feat: colored media score in anime apges
fix: annoying to click text area on forums
feat: show downloaded torrents in search
fix: minor UI fixes
2025-05-22 16:05:51 +02:00
ThaUnknown
b7c7c0866f
fix: offline mode UI shifts
fix: issues with SaveMediaListEntry, lists, optimistic mutations etc
feat: generate video thumbnails during playback
2025-05-22 16:05:51 +02:00
ThaUnknown
433b474ead
chore: import sort 2025-05-22 16:05:51 +02:00
ThaUnknown
0f0cf183f9
feat: proper liting support 2025-05-22 16:05:50 +02:00
ThaUnknown
6b32ae67e3
feat: forums posting, replies, likes, markdown 2025-05-22 16:05:50 +02:00
ThaUnknown
6c4be388a2
fix: minor UI and CSS fixes 2025-05-22 16:05:50 +02:00
ThaUnknown
e10fef4b3d
fix: entry, hold to ff 2025-05-22 16:05:50 +02:00
ThaUnknown
494b06b3d0
fix: bad typedefs
feat: load more comments
2025-05-22 16:05:50 +02:00
ThaUnknown
ac1e51a736
chore: bump ver 2025-05-22 16:05:49 +02:00
ThaUnknown
0e6270ac88
feat: read-only forums 2025-05-22 16:05:49 +02:00
ThaUnknown
5dbe5821dc
chore: bump ver 2025-05-22 16:05:49 +02:00
ThaUnknown
61688bc2ac
fix: thumbnailer not generating images on the go 2025-05-22 16:05:49 +02:00
ThaUnknown
5de442010b
feat: contributing and security 2025-05-22 16:05:49 +02:00
ThaUnknown
df0c1328c5
feat: following on episodeslist 2025-05-22 16:05:49 +02:00
ThaUnknown
bbc58c4e0c
chore: LOL 2025-05-22 16:05:49 +02:00
ThaUnknown
75668d1f1b
feat: update progress bar 2025-05-22 16:05:48 +02:00
ThaUnknown
a53c13073e
feat: hold to FF, auto-skip filler 2025-05-22 16:05:48 +02:00
ThaUnknown
4f65b9135c
feat: external player 2025-05-22 16:05:48 +02:00
ThaUnknown
8b372a3d3e
fix: pull correct extensions 2025-05-22 16:05:48 +02:00
ThaUnknown
b8683300b4
fix: keybinds, improve animation perf
feat: subset fonts
feat: extensions languages & sub/dub
2025-05-22 16:05:48 +02:00
ThaUnknown
70a4995bf8
fix: more UI fixes
feat: autoplay
2025-05-22 16:05:47 +02:00
ThaUnknown
36b11b91bb
chore: bump ver 2025-05-22 16:05:47 +02:00
ThaUnknown
080a7721d0
fix: UI fixes 2025-05-22 16:05:47 +02:00
ThaUnknown
841a8ac149
fix: subtitle languages, refs, headers 2025-05-22 16:05:47 +02:00
ThaUnknown
e0723f10d9
feat: aniskip chapters, minimal player UI 2025-05-22 16:05:47 +02:00
ThaUnknown
fff664e35f
fix: auto-contrasting text, improve banner, "theres nothing here" text for player, schedule for local 2025-05-22 16:05:47 +02:00
ThaUnknown
0f49f36dcd
fix: angle copy LOL 2025-05-22 16:05:46 +02:00
ThaUnknown
cb0388fef9
fix: irc, AL auth, miniplayer loading 2025-05-22 16:05:46 +02:00
ThaUnknown
cf49796b0b
fix: load loop 2025-05-22 16:05:46 +02:00
ThaUnknown
904e5912b0
fix: fake ver update 2025-05-22 16:05:46 +02:00
ThaUnknown
7edfbc3a1e
fix: player ui issues, autocomplete irc 2025-05-22 16:05:46 +02:00
ThaUnknown
db0b9b6b69
fix: cleanp some rules 2025-05-22 16:05:46 +02:00
ThaUnknown
b37b48922d
fix: force app in root 2025-05-22 16:05:46 +02:00
ThaUnknown
fd951a2acc
fix: version check
fix: settings synn
2025-05-22 16:05:45 +02:00
ThaUnknown
eb542299fe
feat: torrent status 2025-05-22 16:05:45 +02:00
ThaUnknown
0c2614e6c4
feat: more player options
fix: player PiP listener
fix: minor cleanup
2025-05-22 16:05:45 +02:00
ThaUnknown
b74a53c4c5
feat: autocomplete 2025-05-22 16:05:45 +02:00
ThaUnknown
a6fa96f61e
feat: proper logo
fix: setup
fix: actually make sync toggable
2025-05-22 16:05:44 +02:00
ThaUnknown
ad4a6f9cbe
feat: autoskip, autopause 2025-05-22 16:05:44 +02:00
ThaUnknown
14476a19aa
feat: local sync
feat: video deband
2025-05-22 16:05:44 +02:00
ThaUnknown
0128ce7efe
feat: default extensions on PC
feat: forced updates
2025-05-22 16:05:44 +02:00
ThaUnknown
9d98c00dd6
perf: disable pulse animation when not necessary
chore: improve activity checking code and stores
2025-05-22 16:05:44 +02:00
ThaUnknown
37266b88e8
feat: sw offline cache
feat: detect if outdated version and force update
fix: use drag scroll everywhere
2025-05-22 16:05:43 +02:00
ThaUnknown
e95aef43dc
feat: subtitles, miniplayer, burn-in 2025-05-22 16:05:43 +02:00
ThaUnknown
0fb7535cee
wip: media resolver [mostly done] 2025-05-22 16:05:43 +02:00
ThaUnknown
86492ed76f
feat: player stats, prev/next
fix: import order
2025-05-22 16:05:41 +02:00
ThaUnknown
86cfff1ec7
wip: player keybinds 2025-05-22 16:05:41 +02:00
ThaUnknown
445afd1320
feat: animation settings 2025-05-22 16:05:41 +02:00
ThaUnknown
3846de3d9d
feat: mobile sidebar 2025-05-22 16:05:41 +02:00
ThaUnknown
6616b9347e
fix: image decoding perf
feat: relative touch seeking on seekbar
feat: idle animation
fix: disable zoom with touch
2025-05-22 16:05:32 +02:00
ThaUnknown
d5b9c8dee7
feat: finish setup
feat: UI for toggle sync
fix: better settings types
fix: reorganize extension settings
feat: finish extension search modal
fix: use pick for media utils
fix: change how native is loaded
feat: debug ribbon
wip: trace anime
2025-05-22 16:05:26 +02:00
ThaUnknown
5862e4d69b
feat: setup page
feat: proper extensions settings page
2025-05-22 16:05:19 +02:00
ThaUnknown
f61c702f7b
WIP: setup page
fix: settings cards overflow
fix: clip performance
fix: schedule page timestamp responsiveness
fix: episodelist hover scale clipping
feat: error route image
fix: incorrect lastYear calculation
fix: donate animation perf
feat: player volume control
fix: improve some animation perf
fix: simplity global native typedef
2025-05-22 16:05:18 +02:00
ThaUnknown
0cabb00499
chore: move 2025-05-22 16:05:10 +02:00
ThaUnknown
93513b6a74
feat: autoPiP, better episode list 2025-05-22 16:05:05 +02:00
ThaUnknown
a06df5c6c5
fix: flyout animation with modals 2025-05-22 16:04:58 +02:00
ThaUnknown
1daa949534
feat: player episode list, seekbar navigation, immersed view 2025-05-22 16:04:49 +02:00
ThaUnknown
0fd3e29ec9
wip: player 2025-05-22 16:04:41 +02:00
ThaUnknown
a8a73ee9cc
test 2025-05-22 16:04:25 +02:00
ThaUnknown
e17dcb4a6f
extensions ui 2025-05-22 16:04:25 +02:00
ThaUnknown
9b1ec67e69
feat: initial 2025-05-22 16:04:25 +02:00
ThaUnknown
c21139af1f
fix: correct fix for androidTV crash
Some checks failed
Build/release / release (macos-latest) (push) Has been cancelled
Build/release / release (ubuntu-latest) (push) Has been cancelled
Build/release / release (windows-latest) (push) Has been cancelled
2025-02-21 13:53:40 +01:00
ThaUnknown
4b44230d20
fix: pnpm action
Some checks are pending
Build/release / release (macos-latest) (push) Waiting to run
Build/release / release (ubuntu-latest) (push) Waiting to run
Build/release / release (windows-latest) (push) Waiting to run
2025-02-20 21:46:13 +01:00
ThaUnknown
b3db378790
feat: override modern WASM support [potential fix for androidTV crashes]
fix: poor download performance while streaming batches
fix: minor fixes
2025-02-20 21:09:42 +01:00
ThaUnknown
6a8d0cbea8
fix: uTP crash hanging torrent client, uTP peers not being preferred
feat: increase video buffer [hopefully]
2024-11-17 17:10:52 +01:00
ThaUnknown
b079e7978d fix: linux perm level 2024-11-10 21:43:35 +01:00
ThaUnknown
66218b8996 chore: bump submodules 2024-11-10 16:06:17 +01:00
ThaUnknown
7039262404 fix: #583 2024-11-10 16:01:03 +01:00
ThaUnknown
9be05949fc feat: checkout submodule 2024-11-10 14:19:28 +01:00
ThaUnknown
7ba2b2591f chore: pnpmlock 2024-11-10 14:09:01 +01:00
ThaUnknown
3bcb910be8 fix: attempt AL fix 2024-11-10 14:07:13 +01:00
Cas_
6f953a3e03
Merge pull request #547 from akadroid/master
fix: AniList completion for external players
2024-10-11 14:02:25 +02:00
Cas_
d02396334e
Merge pull request #520 from onkofonko/master
feat: Introduce custom title bar
2024-10-11 14:02:05 +02:00
ThaUnknown
adeb19c2b2 fix: blur edges 2024-10-11 14:01:43 +02:00
akadroid
1d21f493c3
Fix external player anilist completion 2024-09-26 17:16:04 -07:00
onkofonko
c94b34c563 Address feedback 2024-09-05 20:08:01 +02:00
Cas_
95e0274384
chore: Create CONTRIBUTING.md 2024-09-05 19:56:19 +02:00
onkofonko
7323c9ee2d Address feedback 2024-09-05 19:22:45 +02:00
onkofonko
a3efe63b59 Address feedback 2024-09-05 16:58:07 +02:00
onkofonko
e09dcd1d9d Remove linux only close button 2024-09-01 01:20:14 +02:00
onkofonko
ba3f6f87f5 Fix lint issues 2024-08-31 19:12:07 +02:00
onkofonko
30578016b0 Introduce custom title bar 2024-08-30 22:27:31 +02:00
ThaUnknown
9cfdd02b91 feat: v5.5.6 2024-08-27 19:47:57 +02:00
ThaUnknown
d28681d44c fix: potential w2g errors 2024-08-27 19:47:17 +02:00
ThaUnknown
e5cda31e78 feat: v5.5.5 2024-08-27 15:35:02 +02:00
ThaUnknown
6a8cb28c6a fix: search allow any 2024-08-27 15:30:03 +02:00
ThaUnknown
2a12814fa1 feat: v5.5.4 2024-08-27 13:50:34 +02:00
ThaUnknown
d1a2f714de fix: no peers condition 2024-08-27 13:01:16 +02:00
ThaUnknown
7957f2ff11 fix(electron): load settings before connecting 2024-08-27 10:17:45 +02:00
ThaUnknown
2ce33ff530 fix(web): preview card 2024-08-27 09:36:33 +02:00
ThaUnknown
7bb83a8dd5 feat: v5.2.2 2024-08-26 11:26:24 +02:00
ThaUnknown
adcb93abfd fix: icon sutff 2024-08-26 11:25:26 +02:00
ThaUnknown
e8376c69c3 feat: v5.5.1 2024-08-25 23:38:51 +02:00
ThaUnknown
cc00aca737 fix: lastFinished
fix: close app on webtorrent crash
feat: torrent loading status and errors
2024-08-25 23:36:43 +02:00
ThaUnknown
4712ae95b0 fix: center container icons 2024-08-25 22:44:14 +02:00
ThaUnknown
91861ccf02 feat: debug colors 2024-08-25 20:53:36 +02:00
ThaUnknown
8086d0571f fix: message box pop when sending messages 2024-08-25 18:02:24 +02:00
ThaUnknown
7c8b50aab0 fix: loading/sending torrents 2024-08-25 17:47:36 +02:00
ThaUnknown
581997444e fix: oopsie 2024-08-25 17:14:04 +02:00
ThaUnknown
d768b613a3 feat: v5.5.0 2024-08-25 16:51:29 +02:00
ThaUnknown
67d19eb324 feat: w2g chat 2024-08-25 16:51:16 +02:00
ThaUnknown
cbcc021209 feat: v5.4.1 2024-08-24 13:51:56 +02:00
ThaUnknown
7251f468e5 fix: episode list filler numbers 2024-08-24 13:51:43 +02:00
ThaUnknown
c28872572a fix(web): icons 2024-08-24 13:20:15 +02:00
ThaUnknown
5d52386670 feat: v5.4.0 2024-08-24 13:05:26 +02:00
ThaUnknown
6386b97262 fix: icons on web 2024-08-24 13:04:57 +02:00
ThaUnknown
a6638ef05c fix: correct optical size of player icons 2024-08-24 12:57:58 +02:00
ThaUnknown
9acf663f33 feat: show filler episodes
perf: optimise fonts
perf: use svg icons
fix: exit fullscreen on navigation
fix: exit rss on navigation
2024-08-24 12:40:53 +02:00
ThaUnknown
9c24904021 feat: android external player 2024-08-22 20:02:51 +02:00
ThaUnknown
94f8fafc6b fix: torrent client sometimes loading without settings on android
feat: persist files on android
feat: custom download directory on android
2024-08-22 02:03:16 +02:00
ThaUnknown
c595dd7224 feat: v5.3.8 2024-08-21 20:19:06 +02:00
ThaUnknown
27ec83d858 fix: actually fix keybinds 2024-08-21 20:18:54 +02:00
ThaUnknown
68253334b5 feat: v5.3.7 2024-08-21 17:30:11 +02:00
ThaUnknown
ccb0e1ac83 fix: seek keybinds not working 2024-08-21 17:29:59 +02:00
ThaUnknown
3a4a2fd7e1 fix: trailer on website 2024-08-21 00:00:23 +02:00
ThaUnknown
de6a09ca7d feat: v5.3.6 2024-08-20 23:53:22 +02:00
ThaUnknown
68ab42c22e fix: al login crashing 2024-08-20 23:53:08 +02:00
ThaUnknown
5cf2357976 feat: sort continue watching by last updated 2024-08-20 23:46:45 +02:00
ThaUnknown
f88cca3e29 fix: trailers, go back to iframes 2024-08-20 22:58:33 +02:00
ThaUnknown
5fcd5937e6 feat: v5.3.5 2024-08-20 20:15:18 +02:00
ThaUnknown
08cdae43b7 fix: oopsie 2024-08-20 19:37:14 +02:00
ThaUnknown
62b21bd380 fix: minor css fixes 2024-08-20 19:24:30 +02:00
ThaUnknown
848726bd23 feat: autoskip
feat: reduce search padding on mobile
2024-08-20 19:13:46 +02:00
ThaUnknown
1d05a71b39 feat: open original anime on long press 2024-08-20 18:44:37 +02:00
ThaUnknown
a50b78590f fix: home section re-ordering on android 2024-08-20 17:42:18 +02:00
ThaUnknown
246e713c6e feat: seek duration 2024-08-20 17:34:57 +02:00
ThaUnknown
3eb349c31e fix: dont exclude torrents if user is using external player 2024-08-20 17:16:29 +02:00
ThaUnknown
32d1d03d11 feat: #470 use a router for navigation, support backwards/forwards navigation 2024-08-20 17:10:59 +02:00
ThaUnknown
1923be429a fix: home page error 2024-08-20 11:46:21 +02:00
ThaUnknown
7921e87c49 fix: disabled elements interrupting dpad navigation
fix: disabled buttons not being clear enough
fix: return toaster to old position [didint show in modals]
2024-08-19 23:04:09 +02:00
ThaUnknown
9770eb9976 fix: bad logging 2024-08-18 21:13:21 +02:00
ThaUnknown
3d3dcf9e1d fix: use local version of debug 2024-08-18 18:14:10 +02:00
ThaUnknown
f0c1e952ac Revert "hack: disable debug colors"
This reverts commit 4ab2d359ec.
2024-08-18 17:54:24 +02:00
ThaUnknown
c0977e0cb3 chore: deps 2024-08-18 17:24:14 +02:00
ThaUnknown
4ab2d359ec hack: disable debug colors 2024-08-18 17:00:16 +02:00
ThaUnknown
fdec580314 feat: verbose debug logging 2024-08-18 16:29:35 +02:00
ThaUnknown
eeed27ffcf feat: better debug tooling, debug mode
fix: make account related buttons disabled when not signed in
fix: improve DTS exclusions
fix: softlock on navigation in androidTV
2024-08-18 10:22:15 +02:00
ThaUnknown
0ef55b1f34 fix: #493 updater errors 2024-08-14 01:48:59 +02:00
ThaUnknown
d9236f9ffa fix: catch close error 2024-08-14 01:48:32 +02:00
ThaUnknown
0a6f446e2d feat: 5.2.15 2024-08-14 01:04:21 +02:00
ThaUnknown
3ad7a987a2 fix: #487 reduce failure rate on nyaa scrape 2024-08-14 01:04:08 +02:00
ThaUnknown
25ba650161 fix: fake update for macos, simply open miru download page because macos sucks 2024-08-06 00:45:01 +02:00
ThaUnknown
d32c579896 feat: improve update behavior 2024-08-05 23:42:23 +02:00
ThaUnknown
e1f6caabdc feat: 5.2.12 2024-08-05 18:50:12 +02:00
ThaUnknown
11ccef2287 fix: destroy store correctly 2024-08-05 18:49:30 +02:00
ThaUnknown
4f9fbb8806 feat: 5.2.11 2024-08-05 18:07:44 +02:00
ThaUnknown
5a6ea08db8 fix: batch resolving media 2024-08-05 18:05:21 +02:00
ThaUnknown
c07ca0f56f fix: HACK: capacitor http 2024-08-04 03:22:36 +02:00
ThaUnknown
575aedf453 feat: 5.2.7 2024-07-29 22:51:14 +02:00
ThaUnknown
38c43ee93f feat: update icon 2024-07-29 22:51:07 +02:00
ThaUnknown
22878b4e27 fix: android TV softlock 2024-07-26 13:53:43 +02:00
ThaUnknown
ee12892ae0 feat: 5.2.6 2024-07-26 12:38:54 +02:00
ThaUnknown
333f02120f fix: mpv url encodign
fix: maybe macos updater?
2024-07-26 12:37:07 +02:00
ThaUnknown
cf6f3093ff fix(web): home cards 2024-07-18 15:34:09 +02:00
ThaUnknown
7b71cd925d feat(web): document extensions 2024-07-17 23:20:28 +02:00
ThaUnknown
13bed67f4a feat: 5.2.3 2024-07-13 15:41:49 +02:00
ThaUnknown
a5c465c636 fix: not being able to change tracks 2024-07-13 15:41:39 +02:00
ThaUnknown
582ee42e4d fix: allow specifying android as OS 2024-07-12 22:22:53 +02:00
ThaUnknown
e9d97ee9fa feat: 5.2.2 2024-07-12 17:01:44 +02:00
ThaUnknown
ba34c0d12a fix: subtitle fonts being incorrectly encoded
fix: touch seeking controlls issues
2024-07-12 17:01:28 +02:00
ThaUnknown
ccb05122ec feat: PiP on mobile
feat: better mobile seeking
2024-07-12 01:05:53 +02:00
ThaUnknown
84b0a557a7 fix: layering on episode cards
fix: mobile hover touch
2024-07-11 23:49:52 +02:00
ThaUnknown
1386b5f8e0 feat: 5.2.1 2024-07-11 21:24:51 +02:00
ThaUnknown
c32d4f9888 fix: don't scale bars 2024-07-11 21:24:38 +02:00
ThaUnknown
99842902cc feat: 5.2.0 2024-07-11 20:18:40 +02:00
ThaUnknown
3d807ebe55 fix: futher improve card styling on mobile
fix: crash on massive fonts on mobile
2024-07-11 20:16:19 +02:00
ThaUnknown
087075a9fd fix: reduce message size for large fonts 2024-07-11 19:11:50 +02:00
ThaUnknown
96cac8180e fix: make scrape errors warnings 2024-07-11 18:38:54 +02:00
ThaUnknown
53b9f5590b fix: #474 Some shows listed in the carousel don't open list of torrents/start playing and error out 2024-07-11 18:17:28 +02:00
ThaUnknown
e9775843e6 fix: #477 banner gradient too small 2024-07-11 17:52:40 +02:00
ThaUnknown
806633fc33 fix: #478 improve touch interaction styles 2024-07-11 17:32:43 +02:00
ThaUnknown
76f3140f05 fix: build 2024-07-11 00:12:27 +02:00
ThaUnknown
5abd6faa7a fix: incorrect path encoding 2024-07-07 01:59:23 +02:00
ThaUnknown
696e2c2193 feat: 5.1.10 2024-07-04 12:24:03 +02:00
ThaUnknown
248ff4f3c1 fix: subtitles not working
fix: some performance flags potentially not working
feat: log renderer output in .log files
2024-07-04 12:23:44 +02:00
ThaUnknown
98a9c25ada chore: 5.1.9 2024-07-03 22:36:13 +02:00
ThaUnknown
5f67d3c109 feat: streamed download 2024-07-03 22:34:13 +02:00
ThaUnknown
d44ae0dce8 fix: macOS updater 2024-07-03 21:09:41 +02:00
ThaUnknown
3ca45b5192 feat: improve extension errors 2024-07-03 20:54:08 +02:00
ThaUnknown
c344d54190 fix: #461 allow for gradient customization 2024-07-01 01:02:42 +02:00
ThaUnknown
ec9d9ab28c fix: exclude dual audio if not supported
fix: dont use crypto for UUID
2024-07-01 00:54:02 +02:00
ThaUnknown
eb21eff4cf feat: better looking search menu on mobile
fix: clipping on home rss feeds
2024-06-30 17:54:49 +02:00
ThaUnknown
2c67c9ee7d chore: 5.1.8 2024-06-30 14:49:28 +02:00
ThaUnknown
13c83bf297 feat: further improve dpad navigation
feat: make home lists scrollable on mobile
2024-06-30 14:47:45 +02:00
ThaUnknown
67407a5693 fix: dpad navigation improvements 2024-06-30 00:49:42 +02:00
ThaUnknown
3dcf5abb9b feat: v5.1.6 2024-06-25 22:14:00 +02:00
ThaUnknown
41d85a15a9 feat: capacitor notifications
fix: capacitor version in settings
2024-06-25 22:13:37 +02:00
ThaUnknown
14f33029c3 feat: electron notifications 2024-06-24 00:29:20 +02:00
ThaUnknown
8902833ee3 fix: new mobile logos 2024-06-17 21:10:17 +02:00
ThaUnknown
6eb67d0467 fix: mac builds 2024-06-17 19:43:09 +02:00
ThaUnknown
af8147a22b fix: typos 2024-06-17 00:31:17 +02:00
ThaUnknown
1451553617 fix: winget not being installer 2024-06-16 23:57:44 +02:00
ThaUnknown
372288cfa4 fix: revert hybrid chunk store changes 2024-06-16 23:44:43 +02:00
ThaUnknown
249444899f chore: deps 2024-06-16 23:33:01 +02:00
ThaUnknown
a8cd6201ce fix: Failed making request to anilist! Try again in a minute. 404-not found #453 2024-06-16 23:26:57 +02:00
ThaUnknown
33f9124cc9 fix: improve default fonts for subtitle renderer 2024-06-16 22:20:18 +02:00
ThaUnknown
7b3020bf35 fix: external player URL encoding
fix: al entry running when not necessary
fix: androidTV getting stuck in torrent select modal
fix: bottom of settings not visible on medium size displays
2024-06-16 20:10:28 +02:00
ThaUnknown
aeee8f74e5 fix: android clicks 2024-06-16 18:01:25 +02:00
ThaUnknown
082444f2a7 fix: magnet invalid json
fix: torrent error "object Object"
fix: macos microphone notification prompt
fix: bring back error logging [oops]
2024-06-16 16:32:27 +02:00
ThaUnknown
31c371f828 fix: build 2024-05-29 00:15:01 +02:00
ThaUnknown
fc8bab640b fix: CI 2024-05-28 23:57:10 +02:00
ThaUnknown
2862b0235c fix: improve controller navigation 2024-05-17 22:35:36 +02:00
ThaUnknown
bcbb01fcf2 feat(web): add android download link 2024-05-17 15:22:15 +02:00
ThaUnknown
16fa806db5 fix: native import 2024-04-19 18:51:27 +02:00
ThaUnknown
5c592b2b30 chore: bump ver 2024-04-19 18:31:12 +02:00
ThaUnknown
a1ca14caf8 feat: permanent upnp mappings 2024-04-19 18:30:20 +02:00
ThaUnknown
7a2367f4a5 chore: bump ver 2024-04-18 19:24:44 +02:00
ThaUnknown
6017ab1dab fix: dont mark as complete when not necessary
fix: dont spam failed resolve media
2024-04-18 19:16:36 +02:00
ThaUnknown
2f9db0fe54 fix: subtitle negative offset
fix: go back episode on media with no episodes
2024-04-17 21:25:41 +02:00
ThaUnknown
4dbf3817a6 fix: re-force high perf gpu 2024-04-16 17:44:19 +02:00
ThaUnknown
34e3a39688 fix: Settings panel doesn't work and breaks entire UI #442 2024-04-15 22:34:22 +02:00
ThaUnknown
a23a855655 fix: missing MIME type 2024-04-15 12:49:38 +02:00
ThaUnknown
059f2e6df9 chore: lockfile 2024-04-15 11:15:00 +02:00
ThaUnknown
984d00b725 chore: update deps 2024-04-15 11:05:37 +02:00
ThaUnknown
6d8027cb39 fix: settings login icon 2024-04-15 01:28:54 +02:00
ThaUnknown
d68aa05a0b fix: banner cycling causing scrolling jumps
breaking: remove recommendations [too much bandwidth wasted]
fix: remove all cors
perf: decrease load times by removing preflight, and caching user data
2024-04-15 00:20:11 +02:00
ThaUnknown
6abc544d01 fix: GPU flag stuff 2024-04-14 17:32:52 +02:00
ThaUnknown
ad53734aff fix: sanitise Pip window size 2024-04-14 00:04:22 +02:00
ThaUnknown
453c79fa4e fix: PiP deband video 2024-04-13 23:39:34 +02:00
ThaUnknown
947ac1cac5 feat: use media cache for cards 2024-04-13 23:33:48 +02:00
ThaUnknown
963db909d8 fix: remove both curly brackets in variables to avoid confusion 2024-04-13 23:20:29 +02:00
ThaUnknown
f54e5cb076 feat: deband keybind
feat: keybind descriptions
2024-04-13 23:16:59 +02:00
ThaUnknown
13c4526f2a fix: episode list progress for completed anime
fix: fit-width for debanded video
fix: step on upload speed settings
2024-04-13 22:41:36 +02:00
ThaUnknown
0433d0242f fix: dont auto play when torrent menu is closed 2024-04-04 14:46:20 +02:00
ThaUnknown
5d41354145 fix: torrent modal not overlaying video player
fix: incorrectly reporting torrent download location
feat: card type setting
fix: nicer looking torrent errors
fix: throw error when no extensions are configured
2024-04-04 14:25:34 +02:00
ThaUnknown
95fcaeb454 feat(web): improve hero on firefox, improve FAQ 2024-04-04 01:03:17 +02:00
ThaUnknown
db08cff1a1 fix: capacitor torrent path 2024-03-29 23:18:52 +01:00
ThaUnknown
6e426630f4 fix: drag-drop subtitle files
fix: episodes marked as complete too early
2024-03-27 14:52:21 +01:00
ThaUnknown
92e5207e3a fix: batch resolves in 50 elements at once
fix: don't run AL when not necessary
fix: reduce compound variable count
2024-03-24 21:18:23 +01:00
ThaUnknown
c0d1f97c89 feat: use compound queries for name resolving
fix: errors on episode cards with no media
feat: use AL media cache in resolver
2024-03-24 17:14:30 +01:00
ThaUnknown
7f8dd7841e chore: bump ver 2024-03-22 11:58:21 +01:00
ThaUnknown
36fa2e3313 fix: don't store torrentPath on UI 2024-03-22 11:57:46 +01:00
ThaUnknown
17498e8e69 feat: spawn custom video player process #415 2024-03-22 01:16:53 +01:00
ThaUnknown
58209181bf fix: currentMedia on torrent menu 2024-03-21 19:54:00 +01:00
ThaUnknown
2c3af49f76 fix: "Pause when tabbing out" Feature not working as expected #369
fix: scrollbars
2024-03-21 01:44:41 +01:00
ThaUnknown
ebc65133ed fix: rollback anitomyscript 2024-03-20 22:58:07 +01:00
ThaUnknown
51e2e53649 chore: update electron 2024-03-20 22:51:13 +01:00
ThaUnknown
c03a795a59 feat(web): update images for features 2024-03-20 21:58:29 +01:00
ThaUnknown
c5d0dce864 feat(web): update open graph 2024-03-20 20:26:12 +01:00
ThaUnknown
3908e54ba1 feat(web): better open graph 2024-03-20 20:19:46 +01:00
ThaUnknown
393626f619 chore: docs 2024-03-20 19:13:42 +01:00
ThaUnknown
88d05a75a9 chore: docs 2024-03-20 19:10:49 +01:00
ThaUnknown
777794d488 fix: banner issues 2024-03-20 18:43:48 +01:00
ThaUnknown
e43b55549b fix: improve banner skeleloader position 2024-03-19 23:43:03 +01:00
ThaUnknown
67ce45c437 feat: airing schedule leftovers #431 2024-03-19 23:25:14 +01:00
ThaUnknown
f61874e665 fix: further banner improvements 2024-03-19 22:51:18 +01:00
ThaUnknown
d760761bba feat: cycling home screen banner #404 2024-03-19 22:37:08 +01:00
ThaUnknown
01e3bb7810 feat: use YT thumbnail for trailer thumbnail #428 2024-03-19 22:05:09 +01:00
ThaUnknown
4ea889951b fix: electron build
fix: load anime watch progress
2024-03-19 21:41:20 +01:00
ThaUnknown
e412bda820 fix: mobile settings and video player 2024-03-19 20:08:00 +01:00
ThaUnknown
b1e81af397 chore: bump vers 2024-03-19 19:07:02 +01:00
ThaUnknown
6fc485143f feat: extension system
feat: new torrent modal
2024-03-19 18:50:10 +01:00
ThaUnknown
96609ba479 feat(web): improve testimonials 2024-03-10 23:52:06 +01:00
ThaUnknown
78895e05f5 feat(web): testimonials 2024-03-10 23:43:50 +01:00
ThaUnknown
6e3b2caed4 feat(web): features page 2024-03-10 21:01:56 +01:00
ThaUnknown
01e5af9b23 fix(web): infinite refresh loop on dl screen 2024-03-09 15:38:35 +01:00
ThaUnknown
ef6a79114d feat:(web): WIP WIP features UI 2024-03-09 14:55:58 +01:00
ThaUnknown
527e288732 feat(web): more wip features page 2024-03-08 14:17:42 +01:00
ThaUnknown
2967fb8afd feat(web): WIP features page 2024-03-06 20:20:55 +01:00
ThaUnknown
7a1793c3db feat(web): improve home screen 2024-03-05 22:44:07 +01:00
ThaUnknown
4f797de139 chore: update deps
feat(web): error route, loader font size clamp, download page looping errors
2024-03-05 00:36:03 +01:00
ThaUnknown
1f8a13bd22 fix: mobile check event listener leak 2024-02-24 18:28:57 +01:00
ThaUnknown
b9f3042e1f feat: mobile, reduce icons, make miniplayer smaller 2024-02-24 18:26:35 +01:00
ThaUnknown
35fa5f11f8 feat: change icon 2024-02-24 16:34:22 +01:00
ThaUnknown
d0593e8907 feat(web): new logo 2024-02-18 17:20:49 +01:00
ThaUnknown
6a5347dfd2 fix(web): opensearch 2024-02-18 15:40:54 +01:00
ThaUnknown
c995b5a8db chore: update types 2024-02-13 21:03:51 +01:00
ThaUnknown
45b03c068a feat: media cache 2024-02-08 23:13:36 +01:00
ThaUnknown
4cabb017cb fix: #416 2024-02-08 23:08:05 +01:00
ThaUnknown
00e398948e feat: improve media types 2024-02-06 10:37:55 +01:00
ThaUnknown
712717e587 Merge branch 'master' of https://github.com/thaunknown/miru into master 2024-02-05 23:48:28 +01:00
ThaUnknown
67c7bf3cc9 feat: typed anilist client 2024-02-05 23:47:57 +01:00
Cas_
8bb711a911
Merge pull request #409 from michielcx/feature/progress
feat: Episode Progress Tracking and Resume
2024-02-02 11:13:47 +01:00
ThaUnknown
de69850d03 fix: address review 2024-02-02 11:12:38 +01:00
michiel-cox
17a1f12463 refactor: switch episode progress tracking database from Dexie.js to LocalStorage 2024-01-21 04:08:19 +01:00
ThaUnknown
35da5a2ca6 refactor: switch episode progress tracking database from Dexie.js to LocalStorage 2024-01-21 03:24:51 +01:00
ThaUnknown
42d4c1c4fa chore: bump ver 2024-01-20 21:07:20 +01:00
ThaUnknown
f5cd3d745e fix: handle anilist 500 errors 2024-01-20 21:07:02 +01:00
michiel-cox
b140fbc03d feat: add episode progress tracking 2024-01-20 21:01:27 +01:00
michiel-cox
58e5721642 feat: add episode progress tracking 2024-01-20 20:57:44 +01:00
michiel-cox
01fb2aad90 feat: add episode progress tracking 2024-01-20 20:24:34 +01:00
michiel-cox
472bc08353 feat: add episode progress tracking 2024-01-20 18:25:03 +01:00
ThaUnknown
1bb771992f feat: anime resolve cache 2024-01-15 16:23:48 +01:00
ThaUnknown
941abeeeff chore: update deps 2024-01-13 18:41:30 +01:00
ThaUnknown
fb1630511a fix(web): scroll to top on navigate 2024-01-11 12:44:05 +01:00
ThaUnknown
0af1a464a5 fix: #405 2024-01-11 11:36:54 +01:00
ThaUnknown
5600485f4d feat: give sneedex results when no mappings
fix: find in current movie
2024-01-09 23:54:14 +01:00
ThaUnknown
a67a204cd1 fix: #396 2024-01-08 23:24:32 +01:00
ThaUnknown
3b3f278d1e fix: #392 2024-01-08 23:01:22 +01:00
ThaUnknown
a2903a26ba fix: #400 2024-01-08 22:35:49 +01:00
ThaUnknown
9ee56128e3 fix: remove green text on verified 2024-01-08 20:36:18 +01:00
ThaUnknown
ec21cf5bef feat: mobile click vibrations
fix: seadex audio term
2024-01-07 00:40:32 +01:00
ThaUnknown
df7a82e9c3 chore: bump ver 2024-01-02 03:08:03 +01:00
ThaUnknown
71cd8e9157 feat: add seadex mappings
fix: increase amt of tosho results
feat: new styling on rss view
2024-01-02 03:04:59 +01:00
ThaUnknown
686d1aceda fix: random stuff 2023-12-31 19:58:03 +01:00
ThaUnknown
3dad5ef491 fix: remove passive from removelistener 2023-12-29 09:41:11 +01:00
ThaUnknown
e9335b1f6f fix: remove pointer events on glow elements 2023-12-27 19:54:27 +01:00
ThaUnknown
874d99e78f feat(web): pink-ish glow 2023-12-27 17:14:46 +01:00
ThaUnknown
cfc03593fa fix: change showcase video url 2023-12-27 16:44:14 +01:00
ThaUnknown
af3f311232 feat(web): showcase video
fix: showcase cards clipping and gradients
fix: touch scroll position
2023-12-27 16:37:10 +01:00
ThaUnknown
8b77da7400 feat: better looking showcase cards
feat: better looking home sections
fix: small gap under video on preview cards
2023-12-27 01:22:38 +01:00
ThaUnknown
33d13c4649 chore: excludes 2023-12-26 15:05:40 +01:00
ThaUnknown
374eb9158e fix: functions redirect 2023-12-26 15:00:01 +01:00
ThaUnknown
f0a7f8d402 fix: type errors 2023-12-26 14:47:15 +01:00
ThaUnknown
8d158944b5 fix: hide logout modal when not used 2023-12-26 14:40:56 +01:00
ThaUnknown
b598067245 fix: improve navigating to player on TV
fix: preferred audio language
fix: some type errors
2023-12-26 14:15:57 +01:00
ThaUnknown
42e345f095 fix: last torrent loading on android 2023-12-26 13:58:00 +01:00
ThaUnknown
541dc831e6 fix: keybinds overriding forms 2023-12-26 13:15:53 +01:00
ThaUnknown
75e819f6ae fix: keybinds and dpad navigation interfering 2023-12-26 03:24:22 +01:00
ThaUnknown
e23e7f9c72 fix: current subtitle index 2023-12-26 02:53:12 +01:00
ThaUnknown
9cbdfd876b fix: hanging when playing video on smart TV's 2023-12-26 02:40:22 +01:00
ThaUnknown
e3c64e1ead feat: improve changelog 2023-12-26 00:28:58 +01:00
ThaUnknown
4bc6981ca7 fix: dont show hover effects when touch scrolling 2023-12-25 23:45:07 +01:00
ThaUnknown
127b57416f fix: #394 2023-12-25 23:40:18 +01:00
ThaUnknown
0c0f29f295 feat: improve mobile click handling for player
feat: allow navigation into player on smart tvs
2023-12-25 23:38:17 +01:00
ThaUnknown
12e1636981 fix: deband reactive settings 2023-12-21 16:12:06 +01:00
ThaUnknown
6ef13b00db fix: deband support and descriptions
fix: captions menu sizing and offset button
2023-12-21 15:57:59 +01:00
ThaUnknown
88e7b56c86 feat: video deband [no worky] 2023-12-21 14:32:44 +01:00
ThaUnknown
0a282027a6 fix: miru:// redirects 2023-12-09 18:32:12 +01:00
ThaUnknown
0f14a90a9b fix: dpad navigation running on pc
fix: last torrent loading
fix: remove autofocus on search
2023-12-09 17:32:03 +01:00
ThaUnknown
beab364ac9 fix: #387 2023-12-09 17:05:10 +01:00
ThaUnknown
499d8aadbe feat(capacitor): utp native build 2023-12-09 00:00:58 +01:00
ThaUnknown
ee480d992b fix: TMP path on android, keybinds on android, not immersed when paused
feat: greatly improve dpad navigation
fix: #386
2023-12-08 21:45:17 +01:00
ThaUnknown
1a309d74f9 fix: w2g and anime redirects 2023-12-08 18:35:06 +01:00
ThaUnknown
e09053bb27 feat: dpad navigation, wt error handling 2023-12-08 18:06:02 +01:00
ThaUnknown
053c4adb10 feat(mobile): android tv manifest 2023-12-07 22:38:09 +01:00
ThaUnknown
bc528c5cac fix: capacitor IPC 2023-12-07 20:10:00 +01:00
Cas_
df3fc91704
Merge pull request #383 from ThaUnknown/node-js-mobile
feat: node js mobile
2023-12-07 16:04:51 +01:00
ThaUnknown
d3c68d00d8 chore: improve type configs 2023-12-07 15:02:12 +01:00
ThaUnknown
d4b82958c4 fix: capacitor server access 2023-12-07 13:00:13 +01:00
ThaUnknown
215692ae8b chore: update gitignore for android 2023-12-07 12:58:02 +01:00
ThaUnknown
7cf537827e chore: remove java activity 2023-12-07 12:57:36 +01:00
ThaUnknown
b7eef76204 fix(mobile): ipc 2023-12-06 18:59:59 +01:00
ThaUnknown
bffcc306f4 fix(capacitor): ipc 2023-12-06 17:10:45 +01:00
ThaUnknown
0bea618803 fix: stuff 2023-12-06 16:39:42 +01:00
ThaUnknown
13e98f12fc fix(capacitor): dist nodejs files correctly 2023-12-06 14:42:59 +01:00
ThaUnknown
f1f2fe39bb fix: newlines 2023-12-06 13:09:34 +01:00
ThaUnknown
a0d57b782d fix: submodules 2023-12-06 10:36:59 +01:00
ThaUnknown
9ad8c1d1c1 fix: update submodules 2023-12-06 10:28:31 +01:00
ThaUnknown
18ef3153db feat(capacitor): nodejs mobile native dependencies 2023-12-06 10:11:07 +01:00
ThaUnknown
65bd321f4a wip: node-mobile 2023-12-05 23:29:45 +01:00
ThaUnknown
5cdcfda4a1 fix(web): OG image paths 2023-12-05 22:24:05 +01:00
ThaUnknown
e307e5bde5 fix(web): consistent padding and spacing 2023-12-05 17:00:25 +01:00
ThaUnknown
32568cc32b fix(web): OG image URL 2023-12-05 15:12:35 +01:00
ThaUnknown
e279ca2c88 fix(web): lazy load trailer 2023-12-05 15:09:24 +01:00
ThaUnknown
9f164a5a54 fix(web): optimise images 2023-12-05 14:47:55 +01:00
ThaUnknown
c2b367f8d5 feat(web): stargazers, player 2023-12-05 13:22:03 +01:00
ThaUnknown
3081976587 feat: minor SEO stuff 2023-12-05 11:10:30 +01:00
ThaUnknown
3260b7ce8e fix: just remove loading text 2023-12-05 01:28:05 +01:00
ThaUnknown
e3d373c38f fix: further improve loader 2023-12-05 01:20:53 +01:00
ThaUnknown
ee1afbe910 fix: improve loader
fix: improve card preview initial state
fix: improve smoothscroll
feat: more home screen stuff
2023-12-05 01:16:27 +01:00
ThaUnknown
15beef8963 feat(web): smooth scroll, about section, cards, scroll animations 2023-12-05 00:23:31 +01:00
ThaUnknown
2ef05e3d4e feat(site): fullscreen loader 2023-12-02 15:56:52 +01:00
ThaUnknown
3320b94d77 fix: web fonts 2023-11-29 23:47:50 +01:00
ThaUnknown
afd6b86f22 fix: #379 2023-11-29 23:32:16 +01:00
ThaUnknown
057dd6a94a fix: improve image scaling 2023-11-29 23:26:36 +01:00
ThaUnknown
ddb756ee96 chore(deps): svelte-sonner 2023-11-27 20:26:05 +01:00
ThaUnknown
7d257d43f3 fix: use links on downloads page 2023-11-27 20:22:41 +01:00
ThaUnknown
ad33093ec0 fix: dont pre-render 2023-11-27 01:59:55 +01:00
ThaUnknown
dc456d2749 fix: add empty features page 2023-11-27 01:55:06 +01:00
ThaUnknown
4826f0735a fix: website dependencies 2023-11-27 01:50:56 +01:00
ThaUnknown
1f742452a4 feat: website, landing page, etc 2023-11-27 01:42:54 +01:00
ThaUnknown
d453aca9a2 feat: further improve mobile UI for viewAnime
feat: add option to reverse episode list on small displays
fix: nyaa not reachable peer count errors
2023-11-24 20:51:42 +01:00
ThaUnknown
e1a22a7dc1 fix: time out nyaa lookup after 5s 2023-11-24 18:01:58 +01:00
ThaUnknown
2c9b019074 feat: better setting validation
fix: crash on invalid DoH URL
2023-11-24 17:57:30 +01:00
ThaUnknown
637b614410 chore(electron): bump ver 2023-11-24 02:24:45 +01:00
ThaUnknown
28ae66a804 fix: search spam
feat: show "oops!" when no data is available for search or feed
fix: error handling for sections and search
2023-11-24 02:24:34 +01:00
ThaUnknown
d8ad810681 chore(electron): bump ver 2023-11-24 00:24:15 +01:00
ThaUnknown
9c1ea2c679 chore: update deps 2023-11-24 00:23:28 +01:00
ThaUnknown
33c4d4563a fix: #356 2023-11-24 00:17:05 +01:00
ThaUnknown
9bdae8777f chore: dead code removal 2023-11-23 23:59:48 +01:00
ThaUnknown
3e9e015945 fix: #373 2023-11-23 23:34:25 +01:00
ThaUnknown
31226fbf89 fix: update supports table for DHT 2023-11-23 20:43:16 +01:00
ThaUnknown
8a876a1053 feat: nat pmp for android 2023-11-23 20:21:18 +01:00
ThaUnknown
a41d076929 fix: capacitor al login loop 2023-11-23 19:20:58 +01:00
ThaUnknown
535e83cdca fix: app not showing up on app list
removed main activity like a fool
2023-11-23 19:04:31 +01:00
ThaUnknown
8b3992ff06 fix: always add anime title 2023-11-23 16:13:00 +01:00
ThaUnknown
009e26974d feat: capacitor NAT traversal 2023-11-23 16:05:18 +01:00
ThaUnknown
665861b92c fix: scrolling in settings 2023-11-21 22:24:44 +01:00
ThaUnknown
d75c6e77f3 feat: DHT on capacitor 2023-11-21 21:35:59 +01:00
ThaUnknown
34770e590d fix: #367
fix: #368
2023-11-21 19:31:55 +01:00
ThaUnknown
4b4137a8e1 feat: smooth scroll in settings 2023-11-21 18:32:56 +01:00
ThaUnknown
1400abb6a9 fix: build and config 2023-11-21 18:07:11 +01:00
ThaUnknown
9320111dac yeet 2023-11-21 17:59:46 +01:00
Cas_
97d977bd08
Merge pull request #375 from ThaUnknown/monorepo
feat: monorepo
2023-11-21 17:53:02 +01:00
Cas_
0f679c26f8
Merge branch 'master' into monorepo 2023-11-21 17:49:10 +01:00
ThaUnknown
52b1aa6608 fix: flashing on load
fix: menubar on electron
fix: sections loading errors
fix: changelog styling
fix: restore settings
2023-11-21 17:48:43 +01:00
ThaUnknown
88ab29e6a1 fix: torrent port on android
fix: better font select componennt
fix: menubar being clickable on android
feat: subtitle render height limit
feat: higher memory limits for libass
feat: better looking settings
feat: hide settings unsupported by platform
feat: better setting descriptions
fix: miniplayer dragging on mobile
2023-11-21 01:17:09 +01:00
ThaUnknown
80447bdee9 fix: torrentPort issues 2023-11-19 20:52:35 +01:00
ThaUnknown
11356d1646 feat: dev and build configs
fix: subtitles not rendering in portrait
fix: notch inset safe areas
chore: better code structure for capacitor
feat: capacitor AL login
2023-11-19 20:10:03 +01:00
ThaUnknown
94155bdd59 fix: try to fix insets 2023-11-18 18:47:22 +01:00
ThaUnknown
1d450ba778 fix: stuff 2023-11-18 16:38:36 +01:00
ThaUnknown
1c176e8a61 fix: color flashing on load
fix: player top controls under notch
2023-11-18 15:07:20 +01:00
ThaUnknown
f99ce83da2 feat: capacitor android build options
feat: capacitor assets
fix: capacitor service worker registration
feat: capacitor auto service worker registration
2023-11-18 14:57:35 +01:00
ThaUnknown
4b50352885 feat: improve mobile miniplayer handling 2023-11-16 01:23:57 +01:00
ThaUnknown
00972173ac feat: better keyboard click
feat: mobile controls for video player
2023-11-15 22:34:44 +01:00
ThaUnknown
9278e91dfc fix: click 2023-11-15 20:15:41 +01:00
ThaUnknown
8b992cb779 feat: force landscape on fullscreen 2023-11-15 01:09:28 +01:00
ThaUnknown
80050fa6e1 feat: more responsive view anime page
fix: click listener behavior with touch
feat: bottom nabar
feat: hide android nav and status bars
feat: gamepad controls logic
2023-11-15 01:04:18 +01:00
ThaUnknown
3b5acf019b fix: #313 2023-11-13 15:53:31 +01:00
ThaUnknown
a315e6ed1e fix: dgram callback 2023-11-13 14:51:21 +01:00
ThaUnknown
f16041225c fix: buffer creation
fix: drop cors fetch, it wont function
feat: storage quota
2023-11-13 14:19:32 +01:00
ThaUnknown
11eae1593a chore: bump ver 2023-11-13 13:09:03 +01:00
ThaUnknown
e27d4c4ab5 feat: cors-fetch
feat: clean up chrome libs
2023-11-13 13:07:56 +01:00
ThaUnknown
6c93cdf22d fix: stuff 2023-11-12 22:58:40 +01:00
ThaUnknown
9a73497fc6 feat: capacitor build
fix: separate IPC calls
2023-11-12 21:12:28 +01:00
ThaUnknown
832b3bb33d feat: monorepo 2023-11-12 14:43:06 +01:00
ThaUnknown
c04db6548e fix: default setting loading 2023-11-11 21:31:53 +01:00
ThaUnknown
ff123086bf fix: full card skeleloader 2023-11-11 21:17:09 +01:00
ThaUnknown
200f54f63c fix: RSS feeds getting multiple requests
fix: banner skeleloader
2023-11-11 21:09:00 +01:00
ThaUnknown
a806bd1f08 feat: update user lists every 15 minutes
feat: allow custom order and sections on home screen
fix: improve settings code
2023-11-11 20:22:43 +01:00
ThaUnknown
ab1d14eee6 fix: widget layering 2023-11-11 00:22:21 +01:00
ThaUnknown
7b7ffc49d7 fix: airing schedule not updating 2023-11-10 23:58:06 +01:00
ThaUnknown
65a1499956 fix: cors for fetch 2023-11-10 23:46:09 +01:00
ThaUnknown
1e5b887be9 feat: allow specifying angle backend 2023-11-10 23:25:53 +01:00
ThaUnknown
d7f3f1177d Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2023-11-10 01:23:30 +01:00
ThaUnknown
40420bd58f chore: update webtorrent 2023-11-10 01:23:29 +01:00
Cas_
a42021f1e0
Merge pull request #366 from Waaiez/fix-failing-macos-build
fix: build failing on macos
2023-11-10 01:14:17 +01:00
Waaiez Kinnear
0017562573 fix: build failing on macos 2023-11-10 01:35:34 +02:00
ThaUnknown
15b1ad3aaa Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2023-11-09 23:14:44 +01:00
ThaUnknown
4cadfa6b1f fix: destroy background
fix: animetype keys
2023-11-09 23:14:42 +01:00
ThaUnknown
a155ceca2e fix: #358 2023-10-23 10:50:21 +02:00
ThaUnknown
13e25131da fix: re-add devtools
fix: update matroska metadata [performance issues]
2023-10-22 13:41:59 +02:00
ThaUnknown
6b3d543630 fix: parser destroy error
chore: update deps
2023-10-21 14:59:41 +02:00
ThaUnknown
77ec896fa2 chore: update mkv parser 2023-10-21 14:50:46 +02:00
ThaUnknown
12a47c17e1 feat: new mkv parsing backend 2023-10-21 12:17:23 +02:00
ThaUnknown
995c8a621a fix: reduce flickering on high DPI displays 2023-10-20 13:34:46 +02:00
ThaUnknown
a506a06688 chore: types 2023-10-16 18:06:02 +02:00
ThaUnknown
fcb4af670c fix: type errors 2023-10-16 11:44:11 +02:00
ThaUnknown
2328c2a832 fix: 341 2023-10-16 11:10:46 +02:00
Cas_
11651cd3b4
Merge pull request #350 from EnergoStalin/feat/russian-autoselect
feat(settings): russian subtitle and audio autoselect option
2023-10-08 13:00:58 +02:00
EnergoStalin
170bdbcd36 feat(settings): russian sbutitle and audio autoselect option 2023-10-08 03:45:06 +03:00
ThaUnknown
916476aeb8 feat: update jassub 2023-10-02 21:48:38 +02:00
ThaUnknown
e3d15ca868 feat: add bottom padding in viewanime 2023-09-30 23:06:15 +02:00
ThaUnknown
9a339342aa feat: resolve adult media
fix: episode list issues
2023-09-25 11:17:29 +02:00
ThaUnknown
9e96c21605 fix: error on close 2023-09-23 23:17:14 +02:00
ThaUnknown
86b45b8d95 fix: close error 2023-09-21 12:57:01 +02:00
ThaUnknown
b0a1dc025f fix: w2g state not updating 2023-09-18 10:26:56 +02:00
ThaUnknown
3aaba8525f fix: #343 2023-09-17 15:53:54 +02:00
ThaUnknown
7520c3feaa feat: #314 2023-09-14 01:22:11 +02:00
ThaUnknown
ae3e7cfdd2 feat: #323 2023-09-14 00:23:28 +02:00
ThaUnknown
c8eca13e07 feat: #338 2023-09-13 23:58:56 +02:00
ThaUnknown
1b176b8ed5 fix: dont autoplay next in w2g 2023-09-13 23:08:29 +02:00
ThaUnknown
e92341ef9a feat: resolve anime by year
fix: remove dead findSubFiles legacy code
chore: improve type declarations
2023-09-12 22:06:26 +02:00
ThaUnknown
fb6bdcab8a fix: macOS not loading 2023-09-11 14:50:55 +02:00
ThaUnknown
183bdfe632 feat: use external font files in torrent
fix: make episode number and title smaller in player
2023-09-11 01:02:01 +02:00
ThaUnknown
9827958a09 chore: restructure main 2023-09-10 18:28:00 +02:00
ThaUnknown
657cc55551 fix: no media title 2023-09-10 12:43:11 +02:00
ThaUnknown
9caae03c3d fix: episodetitle 2023-09-10 12:34:59 +02:00
ThaUnknown
2b063e9deb feat: better looking episode title in player 2023-09-10 12:27:04 +02:00
ThaUnknown
a864d92173 feat: drag-drop images, subtitles, torrents, links
feat: auto-detect external subtitle files
2023-09-10 12:05:20 +02:00
ThaUnknown
98a6034dcc fix: player toast interaction 2023-09-05 23:49:37 +02:00
ThaUnknown
d73fe4ccd3 fix: ready state
fix: title matching in tosho
2023-09-05 23:34:39 +02:00
ThaUnknown
09d386818a feat: trackpad scrolling 2023-09-05 23:29:55 +02:00
ThaUnknown
62544d7754 fix: verification error 2023-09-05 13:54:51 +02:00
ThaUnknown
d40df8a1ff fix: throw no entries error sooner 2023-09-04 00:49:50 +02:00
ThaUnknown
468d857225 perf: MUCH faster loading and simpler IPC 2023-09-03 23:05:27 +02:00
ThaUnknown
2612bdfc1e chore: update deps 2023-09-03 17:55:19 +02:00
ThaUnknown
ea2076c138 fix: #330 2023-09-03 17:43:52 +02:00
ThaUnknown
d39757c360 fix: load last torrent faster 2023-09-03 16:46:07 +02:00
ThaUnknown
e5abb02a7d fix: force add trackers
fix: only preload http torrent files
fix: include OTF fonts
2023-09-03 16:41:26 +02:00
ThaUnknown
5f73799ce4 fix: add WebRTC errors to error message exclusions 2023-09-02 23:05:03 +02:00
ThaUnknown
dd2d298537 fix: further improve animation performance 2023-08-24 22:49:09 +02:00
ThaUnknown
ee67013b3d fix: greatly improve UI performance 2023-08-24 22:21:17 +02:00
ThaUnknown
4a4644d710 fix: more cloning errors 2023-08-23 23:02:43 +02:00
ThaUnknown
5aad7f81e9 fix: more minor errors 2023-08-23 13:05:38 +02:00
ThaUnknown
21886f2277 fix: errors on buffer transfer
fix: menubar background position
2023-08-23 12:46:31 +02:00
ThaUnknown
404a223ac8 fix: update winget releaser 2023-08-23 00:11:04 +02:00
ThaUnknown
d87e864c41 feat: log all errors [probably a bad idea] 2023-08-22 15:40:57 +02:00
ThaUnknown
f93017fba3 fix: include roboto font
fix: fix scrolling never reaching top
fix: scrolling not starting
fix: add delay to immerse/unimmerse time
2023-08-22 14:14:23 +02:00
ThaUnknown
b04793443d feat: make custom CSS stricter
fix: find more movies
fix: dont show video player controls in modals
2023-08-21 22:17:34 +02:00
ThaUnknown
800eba7a48 fix: improve subtitle parsing state handling 2023-08-18 16:27:33 +02:00
ThaUnknown
fb81cb9367 fix: errors when no anime mappings are found
fix: make nyaa scrape more accurate
2023-08-17 20:53:36 +02:00
ThaUnknown
1ad311cadf feat: cover mode 2023-08-08 17:15:03 +02:00
ThaUnknown
584b166a1e feat: CSS theming
perf: transferable buffers
fix: font loading
2023-08-08 17:02:07 +02:00
ThaUnknown
c70f55a94b fix: settings not being clickable 2023-08-03 00:40:19 +02:00
ThaUnknown
3185644a6a chore: update depedencies 2023-08-03 00:03:18 +02:00
ThaUnknown
0cc5117c2b fix: HDR rendering
feat: encrypted DV >P8
fix: miniplayer positions
fix: improve ultrawide support
2023-08-02 23:53:00 +02:00
ThaUnknown
4ca131d3ee perf: canvas subtitle size
fix: empty entries
2023-08-02 10:35:30 +02:00
ThaUnknown
e1d661f623 fix: loadTillFull errors
fix: scroll errors
feat: better search by image
fix: search by image toast in search
fix: search by image refreshing search
2023-08-01 00:22:30 +02:00
ThaUnknown
a3a945bd45 fix: episode list epoch date 2023-07-31 16:08:37 +02:00
ThaUnknown
2964882536 fix: non-fps bound scrolling 2023-07-31 14:20:41 +02:00
ThaUnknown
fda8fb3d2a fix: show toasts in fullscreen
fix: don't persist RSS search
it was confusing for people where the search got disabled when they went to episodes and back
2023-07-30 12:38:06 +02:00
ThaUnknown
6e1cf2f8e7 fix: dont march prequel for anime resolved with season number 2023-07-30 12:11:25 +02:00
ThaUnknown
f40e164085 fix: #302 PiP mode pause not working 2023-07-30 00:04:38 +02:00
ThaUnknown
281c5c7c7b fix: #304, confirm signout 2023-07-29 23:39:23 +02:00
ThaUnknown
b717e696a3 fix: #306, rss feed not showing up when fullscreen 2023-07-29 23:24:39 +02:00
ThaUnknown
36e2672a13 fix: preview card trailers
feat: preview card trailer volume toggle
fix: dont resolve trusted media
fix: episode list air dates and numbers
2023-07-25 19:03:11 +02:00
ThaUnknown
665d4a3748 fix: split cour mapping error 2023-07-20 16:27:43 +02:00
ThaUnknown
cd23d0b4f3 fix: w2g links 2023-07-19 22:50:05 +02:00
ThaUnknown
a6b026d9b0 feat: display torrent errors in client
fix: w2g page not updating on clicklist
2023-07-19 18:37:22 +02:00
ThaUnknown
985af2a0df feat: torrent and dht port
feat: import and export settings
fix: exclude ember releases
2023-07-18 18:01:14 +02:00
ThaUnknown
0b92faf27e chore: update dependenices
chore: update electron
fix: button yellow color
feat: more descriptive RSS errors
feat: arabic lang selections
fix: status changing with autocomplete disabled
fix: episode list not showing
fix: w2g lobbies getting wiped
2023-07-18 13:51:08 +02:00
ThaUnknown
a4b3a17c93 fix: base64 tosho url 2023-07-15 22:19:09 +02:00
ThaUnknown
bbe220bab1 feat: toggle for sidebar expanding animation 2023-07-15 22:03:19 +02:00
ThaUnknown
4ca90751e6 feat: nicer notifications 2023-07-15 21:50:28 +02:00
ThaUnknown
2597e00f45 fix: improve term mapping for torrent search 2023-07-15 10:54:56 +02:00
ThaUnknown
a29468615d fix: close on episode play 2023-07-15 00:19:08 +02:00
ThaUnknown
9843ff54e1 fix: don't hang on scrape error 2023-07-15 00:14:19 +02:00
ThaUnknown
aa6a4b64b6 feat: re-scrape torrent search results 2023-07-14 23:51:37 +02:00
ThaUnknown
1dd08046d8 feat: new better RSS View 2023-07-14 18:22:30 +02:00
ThaUnknown
4e68d5349f feat: new viewanime page
fix: support 4k movies
fix: no quality searches
feat: support nyaa feeds
2023-07-14 13:28:05 +02:00
ThaUnknown
2f9b1e5792 feat: improve special support
fix: improve handling of shit titles
2023-07-13 00:00:38 +02:00
ThaUnknown
517b9ce3e8 fix: #295 2023-07-12 23:37:52 +02:00
ThaUnknown
f651e38c1d fix: linux jumplist 2023-07-11 22:02:15 +02:00
ThaUnknown
adb15a71a8 fix: menubar close on linux 2023-07-11 19:56:49 +02:00
ThaUnknown
6d344a90cb feat: shortcut jumplist on windows
feat: airing schedule
fix: remove preview cards from full cards
2023-07-11 17:35:15 +02:00
ThaUnknown
81296ac128 fix: w2g
fix: top player title
fix: sidebar hover region
2023-07-11 00:14:34 +02:00
ThaUnknown
dc307ddb84 feat: touchpad and keyboard support 2023-07-10 21:57:51 +02:00
ThaUnknown
eebb8128d3 feat: smooth scroll setting
temp: more accessible trailers
2023-07-10 17:33:20 +02:00
ThaUnknown
3266e152e2 fix: use tosho URL setting for RSS lookup
fix: include repeating in continue watching
fix: use api to check tosho availability
2023-07-10 15:08:00 +02:00
ThaUnknown
68d2cfe6ed fix: improve episode resolve 2023-07-09 11:56:11 +02:00
ThaUnknown
98cf51a8e6 perf: improve smooth scrolling performance 2023-07-07 23:29:11 +02:00
ThaUnknown
fc0c7f5c11 fix: section updating 2023-07-07 21:12:49 +02:00
ThaUnknown
0557ac3280 chore: bump ver 2023-07-07 19:46:42 +02:00
ThaUnknown
4163db7a0d feat: use tosho instead of nyaa for RSS 2023-07-07 16:02:15 +02:00
ThaUnknown
0c55d543f1 feat: date since last ep 2023-07-07 14:20:26 +02:00
ThaUnknown
432a4e9ccf feat: update rss feeds periodically 2023-07-07 11:52:59 +02:00
ThaUnknown
f7c4c7ec6a fix: scrolling pagination errors 2023-07-07 00:19:14 +02:00
ThaUnknown
2f9a22f41a feat: filled incons on active pages 2023-07-06 23:43:26 +02:00
Cas
2605718c0a
fix: discord rpc options
regression
2023-07-06 23:41:07 +02:00
ThaUnknown
6d699751ae fix: dont repaint on infinite scroll 2023-07-06 23:19:02 +02:00
ThaUnknown
51728d1ced feat: change card display mode
feat: pagination hasNextPage
fix: tosho fake stats
2023-07-06 22:42:12 +02:00
kyngs
6aab0a3da3 Change the discord icon to "settings" in Settings.svelte, because "discord" no longer works. Not ideal, but usable for now. 2023-07-06 21:35:06 +02:00
kyngs
fc130ff843 Fix borked discord RPC controls 2023-07-06 21:29:36 +02:00
ThaUnknown
d954314e9b feat: improve tosho batch lookup
feat: infinite scroll on search
fix: update data on list update
2023-07-06 19:40:16 +02:00
ThaUnknown
517352b7ce fix: small errors 2023-07-06 01:19:38 +02:00
ThaUnknown
583e15c5ca feat: update userlists on change
fix: improve tosho specials lookup
fix: deprecate enime API
fix: search
2023-07-06 00:17:40 +02:00
ThaUnknown
c39f9c28a7 feat: make search work 2023-07-05 19:53:27 +02:00
ThaUnknown
f2c359f8f4 fix: content layout shifts, better trailer 2023-07-05 19:51:58 +02:00
ThaUnknown
22e4cc99b3 fix: organise css, use local fonts 2023-07-05 14:38:53 +02:00
ThaUnknown
342dae0237 fix: sections loading error 2023-07-02 22:57:06 +02:00
ThaUnknown
851281b2f3 feat: tosho quality search
fix: player load stuck
wip: search
2023-06-28 22:15:30 +02:00
ThaUnknown
98beb4e8e4 fix: exclude unsupported codeds from tosho
fix: undefined episode on cards
2023-06-25 11:11:14 +02:00
ThaUnknown
f13848d9f8 fix: update pnpm version on ci 2023-06-25 01:35:02 +02:00
ThaUnknown
f2de180f9a feat: eslint config
wip: tosho provider
2023-06-25 01:31:28 +02:00
ThaUnknown
273d5edb3e fix: improve click handling on touch screens 2023-06-21 23:42:45 +02:00
ThaUnknown
4a2ae51a61 feat: faster home loading [deferred]
fix: lower latency AL request
fix: first child small cards padded from left
chore: simplify css
fix: episode cards when no media is resolved
fix: banner buttons
2023-06-21 15:45:20 +02:00
ThaUnknown
f0291806ef fix: update package-lock 2023-06-21 11:45:17 +02:00
ThaUnknown
0e3bc4ad8f feat: full redesign 2023-06-21 11:34:43 +02:00
ThaUnknown
717a2844b3 fix: re-implement w2g 2023-06-17 12:46:13 +02:00
ThaUnknown
cbd71108d2 fix: stream based changes 2023-06-16 20:32:30 +02:00
ThaUnknown
3a159b3967 chore: update lockfile 2023-06-14 20:52:38 +02:00
ThaUnknown
5e5aa7b6ab fix: memory leaks 2023-06-14 20:35:21 +02:00
ThaUnknown
68c05a71f9 chore: bump ver 2023-06-13 22:01:09 +02:00
ThaUnknown
73556f8403 fix: ws tracker connection
fix: update ws tracker list
2023-06-13 22:00:46 +02:00
ThaUnknown
ecfabb3866 fix: improve keybinds button position
fix: display keybinds ui in fullscreen
fix: display modals in-app rather than as an overlay
2023-06-13 21:34:21 +02:00
ThaUnknown
7967ad51f4 fix: subtitle parsing 2023-06-09 14:27:01 +02:00
ThaUnknown
5cf2a5d876 fix: update webtorrent 2023-06-08 17:01:19 +02:00
ThaUnknown
158d6c159b fix: update webtorrent 2023-06-08 13:32:29 +02:00
ThaUnknown
630d6c6777 chore(release): bump ver 2023-06-05 23:41:10 +02:00
ThaUnknown
2156e3defd chore: restructure 2023-06-05 23:40:54 +02:00
ThaUnknown
521d69f238 fix(deps): update webtorrent to fix http server issues 2023-06-05 23:38:43 +02:00
ThaUnknown
d4677bc293 feat: sourcemaps 2023-06-05 17:57:10 +02:00
ThaUnknown
12325b96f3 perf(filesize): don't include bundled dependencies 2023-06-05 17:51:38 +02:00
ThaUnknown
6d4cbc7fb9 fix: uTP, adding new torrents 2023-06-05 17:40:39 +02:00
ThaUnknown
8565c1a9ce fix: env, native deps 2023-06-04 23:28:55 +02:00
ThaUnknown
e94db5997f fix: support fs native extensions 2023-06-04 23:23:18 +02:00
ThaUnknown
764c5a1519 feat: ESM, webtorrent v2 2023-06-04 23:18:30 +02:00
Cas
7fb6a83138
Merge pull request #282 from kyngs/master
Add an option to control Discord RPC. (Fix issue #157)
2023-06-03 21:44:53 +02:00
kyngs
a13f4b3b9e Update discord RPC settings title. 2023-06-03 21:23:29 +02:00
kyngs
e12a24570a Add an option to control discord RPC 2023-06-03 20:51:32 +02:00
ThaUnknown
d82bf27d41 fix: initial media loading 2023-06-02 23:31:54 +02:00
ThaUnknown
b4be30ed70 fix: return on first match 2023-06-02 11:58:13 +02:00
ThaUnknown
eb49c6e9c9 fix: dont include music in search results 2023-06-02 11:37:12 +02:00
ThaUnknown
41b0af3048 fix: title bar controls 2023-05-30 20:00:56 +02:00
ThaUnknown
d94c54df09 fix: support old CPUs 2023-05-30 19:33:39 +02:00
ThaUnknown
8a7bc1e167 fix: file pick errors 2023-05-28 23:02:19 +02:00
ThaUnknown
c92eb1bf23 chore: update jassub
feat: losssy subtitle rendering
feat: support cat proxies
fix: reduce references to cat
2023-05-27 12:41:00 +02:00
ThaUnknown
37d0d8dece fix: movie playback
fix: darwin title bar
2023-05-26 17:43:17 +02:00
ThaUnknown
d82c0ee920 fix: update lockfile 2023-05-25 20:11:28 +02:00
ThaUnknown
8ba9d9f4cc feat: new w2g sync 2023-05-25 20:06:38 +02:00
ThaUnknown
4da3254493 feat: dns over http
fix: repeating badge color
fix: w2g url
2023-05-24 20:42:53 +02:00
ThaUnknown
2d3013e226 fix: mediahandler error 2023-05-16 21:59:04 +02:00
Cas
5e7b071efd
Merge pull request #274 from razzeee/keywords
fix: Don't list application name in keywords
2023-05-13 18:13:22 +02:00
Kolja Lampe
5eb45ecb28
Don't list application name in keywords 2023-05-12 10:21:11 +02:00
ThaUnknown
6d076498e9 fix: bad initial media status 2023-05-07 14:53:48 +02:00
ThaUnknown
6beb5b14bd fix: better chapter sanitisation
feat: basic debug logging
fix: NCED/OP being filtered too late
2023-05-07 12:36:35 +02:00
ThaUnknown
c2ca168aa3 fix: seekbar breaking with out of order chapters
fix: seekbar breaking with misstimed chapters
fix: playnext/last not available when no media was detected
fix: NCOP/NCED playing from batches
fix: aniskip lookup error on files with no media
2023-05-05 20:11:01 +02:00
ThaUnknown
e676036a4e fix: reloading the same torrent while scanning drive
fix: update jassub
2023-05-05 18:12:58 +02:00
ThaUnknown
0b570f9921 feat: update jassub
fixes incorrectly colored subtitles
2023-05-03 21:39:04 +02:00
ThaUnknown
94b280377d fix: make sure chapter start is > 0 2023-05-01 13:19:56 +02:00
ThaUnknown
5a687c0cd5 feat: add timestamps to cards and RSS feeds 2023-04-25 21:22:51 +02:00
Cas
7b3045d973
Merge pull request #269 from GizmoTjaz/master
feat: Use the native MacOS window controls
2023-04-22 22:29:26 +02:00
ThaUnknown
4d4506894e fix: actually fix menu bar not being draggable on darwin 2023-04-22 22:28:40 +02:00
Tjaz
c5ff0df2b0
fix Mac menubar not being draggable 2023-04-22 00:40:54 +02:00
ThaUnknown
6ae395cafb feat: Mac: use native traffic lights over custom menubar 2023-04-21 23:28:55 +02:00
ThaUnknown
21e15c87a2 fix: bad looking seekbar when no chapters 2023-04-20 16:02:04 +02:00
ThaUnknown
20f9111cdd chore: v3.9.10 2023-04-20 00:14:26 +02:00
ThaUnknown
126f767675 fix: edge case when release had partial chapters 2023-04-20 00:13:45 +02:00
ThaUnknown
3f2bc3e6b4 fix: bugged subtitle styles 2023-04-19 23:53:09 +02:00
ThaUnknown
87c639d204 fix: subtitle styles dying 2023-04-19 23:18:52 +02:00
ThaUnknown
66287f3883 feat: use miru.watch domain for sharing anime 2023-04-18 23:36:20 +02:00
ThaUnknown
bd3329cdc9 fix: #267 add changelog 2023-04-18 19:19:59 +02:00
ThaUnknown
2262189624 fix: subtitles sometimes not loading
fix: improve default subtitle style
fix: revert timestamp shadow
2023-04-17 18:14:34 +02:00
ThaUnknown
cc524125fd fix: actually fix playpause 2023-04-15 22:20:29 +02:00
ThaUnknown
e5e545467f fix: playpause on non-left keys 2023-04-14 00:43:51 +02:00
ThaUnknown
4011a81a1d fix: #246 show episode progress 2023-04-13 14:47:07 +02:00
ThaUnknown
b7d7c3108a fix: #264 show notification on auto update finish 2023-04-12 20:54:13 +02:00
ThaUnknown
f19dbdb400 fix: improve design
fixed sidebar hover animations
added card status dots
fixed card genre overflow
fixed card no genre
search is now sticky
viewanime now uses cards to display things
2023-04-11 17:23:54 +02:00
ThaUnknown
1aecac107b fix: #256 2023-04-10 13:18:14 +02:00
ThaUnknown
c0393c1786 chore: update jassub 2023-04-10 12:59:17 +02:00
ThaUnknown
547100a835 feat: preferred sub and audio 2023-04-10 00:54:33 +02:00
ThaUnknown
e5e69f39d0 fix: sort chapters correctly 2023-04-05 15:10:15 +02:00
ThaUnknown
4106a13b94 feat: better seekbar
fix: chapter errors
2023-04-05 14:34:47 +02:00
ThaUnknown
9b38f8cc09 fix: typo 2023-02-27 00:15:58 +01:00
ThaUnknown
435d8aa52c fix: exclude link files 2023-02-26 20:40:30 +01:00
ThaUnknown
cf28d565c1 fix: singleArch registerScheme 2023-02-26 20:35:52 +01:00
ThaUnknown
8bce6e0945 fix: macos singleArch for utp-native 2023-02-26 20:22:12 +01:00
ThaUnknown
569f00e5a3 chore: bump electron ver 2023-02-26 19:56:44 +01:00
ThaUnknown
3d05c598bf chore: update to 23.1.0, universal macos build 2023-02-26 19:55:26 +01:00
ThaUnknown
06ec8c204c v3.7.6 2023-02-21 21:53:29 +01:00
ThaUnknown
cc692b9ef7 fix: indefinite rss feed loop crash
fix: rss feeds not loading
2023-02-21 21:53:18 +01:00
ThaUnknown
21f085b0e4 fix: unblock url
fix: blue top bar on start
fix: some releases card bugs
2023-02-20 20:29:37 +01:00
ThaUnknown
7918050127 chore: bump ver 2023-02-09 22:55:19 +01:00
ThaUnknown
f4698875aa fix: #252 scroll position resetting in animeview 2023-02-05 17:08:01 +01:00
ThaUnknown
a697e88c18 fix: skip intro persisting across videos #253 2023-02-05 16:41:57 +01:00
ThaUnknown
49e94bc089 chore: bump ver 2023-02-05 16:16:37 +01:00
ThaUnknown
8c79a9f358 fix: update electron 2023-02-05 16:09:04 +01:00
ThaUnknown
544b9d1083 fix: improve aniskip results, improve seek keybind 2023-01-21 14:30:59 +01:00
ThaUnknown
c474ecd447 fix: missing font toggle 2023-01-18 17:38:47 +01:00
ThaUnknown
2b12bd690e feat: aniskip API 2023-01-16 17:15:06 +01:00
ThaUnknown
d9c9d6849f chore: cleanup trace.moe search 2023-01-16 15:28:48 +01:00
ThaUnknown
efddc211fc chore: bump ver 2023-01-15 22:59:16 +01:00
ThaUnknown
bdd1371445 fix: continue where u left off playing bad stuff 2023-01-15 22:58:54 +01:00
ThaUnknown
d119243ad2 fix: dashes in RSS
feat: selectable titles, synopsis and details
feat: re-add maxConnections
2023-01-15 03:18:24 +01:00
ThaUnknown
005a6718f4 feat: keyboard navigation 2023-01-06 15:16:24 +01:00
ThaUnknown
63d088710d fix: styles breaking in certain situations 2023-01-06 13:19:48 +01:00
ThaUnknown
00cb3deca0 fix: noauth, anilist login 2023-01-02 02:28:58 +01:00
ThaUnknown
29059d1caa bump ver 2023-01-01 00:01:31 +01:00
ThaUnknown
1f8b2b5b0f feat: useLocalFonts toggle 2022-12-31 23:51:28 +01:00
ThaUnknown
a19920729f feat: custom default font 2022-12-31 23:32:48 +01:00
ThaUnknown
bd6e302705 chore: standard 2022-12-29 00:28:06 +01:00
ThaUnknown
7daf32f91a feat: sequels you missed 2022-12-29 00:27:44 +01:00
ThaUnknown
bd18755b48 perf: insanely faster main menu loading 2022-12-28 16:27:28 +01:00
ThaUnknown
73ba8ed623 chore: minor debloat 2022-12-28 00:57:11 +01:00
ThaUnknown
5f4e711254 fix: discord RPC, file episode finder/picker
feat: title on releases cards, NC-Raws
2022-12-27 18:10:38 +01:00
ThaUnknown
9e5b239ea3 ux: better main menu loading order [lazy fix]
fix: don't re-create torrents on reload
feat: skip op/ed/recap button, chapter nubs
2022-12-27 05:53:56 +01:00
ThaUnknown
b951910ea7 fix: actually update matroska-subtitles 2022-12-25 18:45:12 +01:00
ThaUnknown
e8086c65ee fix: update matroska-subtitles, fixes seeking on NC-Raws and ASW releases 2022-12-25 18:26:12 +01:00
ThaUnknown
920e672d17 fix: sub parser event leak 2022-12-18 16:02:56 +01:00
ThaUnknown
002bf97331 fix: repeating in currently watching 2022-12-14 21:12:45 +01:00
ThaUnknown
fe565234bd fix: throttle 2022-12-12 21:33:32 +01:00
ThaUnknown
5057d4473a chore: update webtorrent 2022-12-03 20:48:57 +01:00
ThaUnknown
a8af665f3a fix: update webtorrent, fix loading error, fixes infinite loops 2022-12-03 18:37:01 +01:00
ThaUnknown
34de2bd295 fix: process leak 2022-12-02 01:52:14 +01:00
ThaUnknown
389549d93d fix, perf: better seek bars 2022-12-01 22:31:28 +01:00
ThaUnknown
405c71460a fix: lockfile 2022-11-30 22:13:11 +01:00
ThaUnknown
ae17be05a6 feat: WebRTC support, better rendering performace 2022-11-30 22:08:56 +01:00
ThaUnknown
41617bd556 feat: bump jassub 2022-11-29 20:04:19 +01:00
ThaUnknown
6512abd33b fix: #223 2022-11-24 02:09:50 +01:00
ThaUnknown
27ea709d79 fix: dono component, dev server kill 2022-11-24 01:16:30 +01:00
ThaUnknown
107ba13367 fix: weighted title search #220 2022-11-24 01:06:18 +01:00
ThaUnknown
75c7b0d01c feat: proper rate limit handling 2022-11-17 02:05:10 +01:00
ThaUnknown
9c5adcc933 feat: faster anitomy parsing
fix: donation component
2022-10-24 17:54:30 +02:00
ThaUnknown
d01e5b639c chore: bump ver 2022-10-18 18:50:25 +02:00
ThaUnknown
2a4a7cc792 fix: viewAnime styling improvements 2022-10-18 18:44:56 +02:00
ThaUnknown
b55df5acbf fix: sidebar tooltips 2022-10-18 18:29:54 +02:00
ThaUnknown
f455a9cffb fix: parsing leak 2022-10-13 14:33:16 +02:00
ThaUnknown
b92738f8ef fix: try to reduce TMP file spam 2022-10-11 19:08:10 +02:00
ThaUnknown
ba7858e3b0 fix: videos with undef duration 2022-10-09 13:46:32 +02:00
Cas
f6e92879ba
fix: alt master title 2022-10-06 19:40:28 +02:00
Cas
d07ce0de32
fix: double workflow 2022-10-06 19:39:51 +02:00
ThaUnknown
1244ee7ba9 fix: minor cosmetics 2022-10-06 19:09:23 +02:00
Cas
28707f6663
Merge pull request #217 from nlxdodge/feature/winget-action
Winget Github Action
2022-10-06 14:16:39 +02:00
NLxDoDge
16eb4a2aad feat: winget github action 2022-10-04 19:02:53 +02:00
ThaUnknown
f233bb277c fix: only emit update notification once 2022-10-02 13:22:43 +02:00
ThaUnknown
43d690807a fix: default keybinds error 2022-09-29 18:11:12 +02:00
ThaUnknown
5f022b3209 fix: autoplay indications 2022-09-28 21:49:02 +02:00
ThaUnknown
4658473546 chore: bump down dono 2022-09-24 15:35:40 +02:00
ThaUnknown
f749c0bce4 fix: miniplayer being janky 2022-09-22 00:35:00 +02:00
ThaUnknown
003231aa39 fix: close track controls on track change 2022-09-19 17:40:51 +02:00
ThaUnknown
4660b2494f fix: rewatch progress 2022-09-16 16:15:18 +02:00
ThaUnknown
8eb5f4581b chore: bump vers 2022-09-07 22:03:10 +02:00
ThaUnknown
fb08ee3b13 fix: support multi-digit shows 2022-09-06 22:56:02 +02:00
ThaUnknown
855dddf89c fix: canvas performance 2022-09-05 17:59:08 +02:00
ThaUnknown
3500988610 Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2022-09-03 22:51:17 +02:00
ThaUnknown
b48f3255c6 fix: custom lists order 2022-09-03 22:51:13 +02:00
Cas
fcaef62bff
Update FUNDING.yml 2022-09-03 21:20:33 +02:00
Cas
c4a717702c
Update faq.md 2022-08-29 16:57:58 +02:00
ThaUnknown
b111357b45 fix: force lowercase comparisons 2022-08-25 01:12:39 +02:00
ThaUnknown
03bceb7ef2 feat: improve anilist search result accuracy 2022-08-25 00:27:30 +02:00
ThaUnknown
41ae69a057 fix: seeking into unloaded ties 2022-08-24 20:16:39 +02:00
ThaUnknown
c8127c617f fix: movie completion 2022-08-23 20:12:44 +02:00
Cas
e200b9cc63
fix: package.json 2022-08-20 18:22:20 +02:00
Muril-o
49aaad3e56
Merge pull request #206 from kutzlect/master
Categories and mimetypes
2022-08-20 13:18:03 -03:00
kutzlect
f4b0b9c164
Categories and mimetypes
Changes to match Freedesktop specifications on registered categories and deduplication of MimeTypes.
2022-08-20 13:45:58 +00:00
ThaUnknown
92af79f01b fix: title parsing 2022-08-20 06:34:39 +02:00
ThaUnknown
304e8fc284 feat: add filename to stats for nerds 2022-08-20 02:04:23 +02:00
ThaUnknown
324b32ed6f chore: simplify artifacts names 2022-08-19 00:17:52 +02:00
ThaUnknown
c7d747efc1 fix: continue batch finding multiple media
fix: disable hw accell HEVC decode
2022-08-19 00:06:36 +02:00
ThaUnknown
6f1a19ab47 feat: continue where left off on batches
fix: subtitle errors, worker errors
2022-08-18 20:01:48 +02:00
ThaUnknown
723ef9d8d8 fix: batch playback when no media is set or multiple media with ep 1 exist 2022-08-17 22:46:02 +02:00
ThaUnknown
e07680e348 fix: lockfile 2022-08-13 22:42:58 +02:00
ThaUnknown
41a95164e3 fix: dont disconnect wg2 peers 2022-08-13 22:40:41 +02:00
ThaUnknown
b1f2d87d74 fix: handle rate limiting&request errors correctly 2022-08-12 16:19:09 +02:00
ThaUnknown
e36445de70 chore: bump p2pcf 2022-08-07 14:39:49 +02:00
ThaUnknown
85cebd62ae fix: remove S01 from search
feat: open website on too many crashes
2022-08-06 13:08:13 +02:00
ThaUnknown
c039a3458c Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2022-08-06 01:32:01 +02:00
ThaUnknown
998cc14c15 fix: prevent crash loops 2022-08-06 01:31:56 +02:00
Cas
42435a96b3
chore: update FAQ 2022-08-06 01:22:34 +02:00
ThaUnknown
d123cdfbbb chore: update deps [fix single user install] 2022-08-06 00:39:29 +02:00
ThaUnknown
18dab17236 fix: i'm stupid 2022-08-05 18:43:23 +02:00
ThaUnknown
cd14f12fd1 chore: bump p2pcf
fix: anime list state toggling
fix: w2g GC
2022-08-05 18:21:43 +02:00
ThaUnknown
7139550a24 feat: w2g discord RPC 2022-08-05 13:18:04 +02:00
ThaUnknown
4365c76453 fix: anime completion, anime scoring 2022-08-04 20:56:44 +02:00
ThaUnknown
b0cec93211 test: empty version bump 2022-08-04 19:51:52 +02:00
ThaUnknown
e9f23154ec feat: PNPM builds 2022-08-04 19:39:38 +02:00
ThaUnknown
4566365f3c fix: remove linux arm [doesnt work anyways] 2022-08-04 14:16:18 +02:00
ThaUnknown
748d5f4ab5 chore: bump electron, hw accell HEVC decode 2022-08-04 14:11:11 +02:00
ThaUnknown
5996f4083d feat: allow to change source during batch playback
fix: play desired ep in batch
2022-08-03 22:31:48 +02:00
ThaUnknown
115cf5e56a feat: add bottleneck'ed rate limit retry
fix: anime with dates in their name being parsed incorrectly
2022-08-03 19:58:08 +02:00
ThaUnknown
f68f6a91a8 fix: trusted isn't a good indicator of quality anymore 2022-08-03 19:18:19 +02:00
ThaUnknown
bc2b3d5f4a fix: w2g disconnects, keybinds showing in miniplayer 2022-08-03 12:06:27 +02:00
ThaUnknown
e34d97bb24 fix: autoplay error when no best release is found 2022-08-02 15:52:49 +02:00
ThaUnknown
9b7975e75f fix: files with no media 2022-08-02 13:30:11 +02:00
ThaUnknown
7934d0df16 fix: no filemedia 2022-08-02 01:59:57 +02:00
ThaUnknown
a9fc3a6fa4 feat: seadex integration 2022-08-02 01:36:44 +02:00
ThaUnknown
b500a99b8e fix: playNext/playLast media, keybinds
feat: w2g joining
2022-08-01 21:02:29 +02:00
ThaUnknown
bf817e2da0 feat: w2g rewrite 2022-08-01 15:37:28 +02:00
ThaUnknown
4d49cf545f fix: episode exclude rx 2022-08-01 13:36:47 +02:00
ThaUnknown
c145127332 fix: allow OVA's for sequel tree marching 2022-08-01 13:08:46 +02:00
ThaUnknown
3542b09602 chore: drop rssbatch setting 2022-08-01 12:49:04 +02:00
ThaUnknown
057385aed6 feat: improved batch support and handling 2022-08-01 12:47:58 +02:00
ThaUnknown
000f39ced0 fix: remove @html from AL responses 2022-07-31 16:54:23 +02:00
ThaUnknown
872e5f8676 chore: restructure 2022-07-31 16:36:08 +02:00
ThaUnknown
d314ea56f6 fix: image input copy-paste 2022-07-30 21:29:23 +02:00
ThaUnknown
f99fbc06fc fix: stricter ep number regex 2022-07-29 23:15:57 +02:00
ThaUnknown
bc6ed3ac18 feat: more explicit image search 2022-07-29 19:54:15 +02:00
ThaUnknown
280f37cefe feat: fullscreen nyaa block 2022-07-29 18:57:29 +02:00
ThaUnknown
7055caf602 feat: custom watchlist 2022-07-28 15:24:05 +02:00
ThaUnknown
93d331ae54 fix: donator count [dont code when tired] 2022-07-27 00:21:10 +02:00
ThaUnknown
7267316895 feat: donation status, RPC buttons
fix: linting, subtitle track errors
2022-07-26 21:35:47 +02:00
ThaUnknown
c0254d749b bump ver 2022-07-15 16:44:17 +02:00
ThaUnknown
c8c7cabf18 fix: seeking issues, animation issues
feat: seekbar revamp
2022-07-15 16:42:54 +02:00
ThaUnknown
02bf9a9d60 feat: viewAnime improvements 2022-07-15 00:59:47 +02:00
ThaUnknown
f1c9761630 fix: update vite 2022-07-14 20:04:43 +02:00
ThaUnknown
aa37383449 fix: notifications dissapearing 2022-07-14 19:38:55 +02:00
ThaUnknown
23d5cb3b21 chore: purge some manually included deps 2022-07-11 19:27:28 +02:00
ThaUnknown
0ba4efb472 bump ver 2022-07-10 14:35:17 +02:00
ThaUnknown
10640285f9 fix: default font loading 2022-07-10 14:27:51 +02:00
ThaUnknown
27f023a0da fix: update subtitle renderer 2022-07-09 23:43:27 +02:00
ThaUnknown
00c243548a fix: wtf anilist 2022-07-06 01:19:58 +02:00
ThaUnknown
fc9f724d6f chore: bump ver 2022-07-06 00:29:24 +02:00
ThaUnknown
27ac5cf0e8 feat: viewAnime improvements
added recommendations
added friends anime status
added an option to show more/less relations and recommendations
improved reliability of quitting using ESC
improved autofocus on title search on home page
removed some unused CSS
2022-07-06 00:29:06 +02:00
ThaUnknown
ee530a5d9a chore: bump ver 2022-07-05 21:09:50 +02:00
ThaUnknown
b41cd95597 fix: asset build opts 2022-07-05 21:09:35 +02:00
ThaUnknown
28fceab1f4 fix: better protocol handling
feat: w2g protocol links
chore: update subs
2022-07-05 20:53:48 +02:00
Cas
8c2d36d176
Merge pull request #194 from Real-SeRyKi/master
feat: add sharing and opening in external browser
2022-07-05 16:26:51 +02:00
SeRyKi
13c25a7001 Fixed mistakes and squashed 2022-07-05 16:20:47 +02:00
ThaUnknown
390ef98b58 fix: subtitle renderer 2022-07-05 13:42:04 +02:00
ThaUnknown
67b44cdff0 fix: recover after crash 2022-07-05 13:19:42 +02:00
ThaUnknown
6db7491481 chore: update jassub 2022-07-05 13:15:00 +02:00
ThaUnknown
3627152124 fix: handle video playback errors
use dynamic server port
2022-07-05 13:06:36 +02:00
ThaUnknown
6d8fdee0b3 fix: migrate to jassub
our chromium ver doesn't support local font access yet, but the support is there once we update
2022-07-05 12:21:32 +02:00
ThaUnknown
ab7341e0c7 perf: custom CSS framework 2022-06-18 15:45:05 +02:00
ThaUnknown
0e38e0d727 chore: syntax fun 2022-06-13 00:02:14 +02:00
ThaUnknown
b02d0645f5 feat: multiple RSS feeds #164, fix search not resetting on empty 2022-06-10 18:33:54 +02:00
ThaUnknown
9a60b7aad2 fix: remove broken M1 builds 2022-06-10 14:13:55 +02:00
ThaUnknown
a6c48c0c37 feat: add looping and manual update check, and update detection notification 2022-06-10 02:53:35 +02:00
Cas
08661ed8c3
Update README.md 2022-06-10 01:10:08 +02:00
ThaUnknown
135a0caba1 feat: viewAnime improvements: better performance, scoring, relations, grey watched episodes fix #160 2022-06-10 01:03:30 +02:00
ThaUnknown
5f044564d2 fix: #189 looking for double digit episodes finds tripple digit episodes 2022-06-09 22:02:26 +02:00
ThaUnknown
b7c80afbc9 fix: edge case when a final ep from the wrong season was played, continue played EP out of bounds, a torrent got overwritten with auto-start torrent, anime with weird numbers was being found, anime for old DVD shows wasn't being found, duplicate torrents showed up
feat: more batches are now found
2022-06-09 19:15:48 +02:00
ThaUnknown
19cf481541 fix: arch ver on linux 2022-06-09 18:07:43 +02:00
ThaUnknown
cc20e35500 feat: add ARM support for Linux and MacOS 2022-06-09 17:42:16 +02:00
ThaUnknown
15e8ecf357 fix: try to reduce initial load lag 2022-06-07 15:34:04 +02:00
ThaUnknown
450c6d6311 fix: revent build changes 2022-06-06 00:42:11 +02:00
ThaUnknown
d5836df3ae chore: bump ver 2022-06-06 00:38:53 +02:00
ThaUnknown
06de52dd65 fix: npm config 2022-06-06 00:38:40 +02:00
ThaUnknown
05a68f2ecc fix: minor filename parsing improvements 2022-06-05 23:00:24 +02:00
ThaUnknown
a57491a1f5 feat: switch to PNPM for faster build times 2022-06-05 17:41:08 +02:00
ThaUnknown
1b8680b863 feat: fix stats for nerds
chore: update wiki links
2022-06-05 17:10:01 +02:00
ThaUnknown
8b544a6a26 fix: keybinds triggering when outside of player 2022-06-05 15:46:51 +02:00
ThaUnknown
9401c34a94 chore: update subtitle renderer 2022-06-05 15:40:27 +02:00
ThaUnknown
00474cdc3e feat: keybinds UI, video tracks selection, screenshot 2022-06-05 15:04:31 +02:00
ThaUnknown
1fa0d1437c fix: exclude ASW releases due to malformed metadata 2022-06-05 13:50:40 +02:00
Cas
9f99b4e235
Merge pull request #178 from Muril-o/177-fix
fix: #177 [Bug]: Select Folder button for torrent path not working
2022-05-31 19:15:44 +02:00
Muril-o
fe3aa1f7fd fix: ThaUnknown#177 2022-05-31 13:32:15 -03:00
Cas
dc2bad83c6
Merge pull request #176 from Muril-o/master
Added linux install instructions for maintained AUR
2022-05-29 19:05:48 +02:00
Muril-o
c76a1b982c Added linux install instructions for maintained AUR 2022-05-29 13:12:11 -03:00
ThaUnknown
2c2145de91 feat: improve miniplayer, add dragging and resizing 2022-05-21 14:34:15 +02:00
ThaUnknown
2b4e6992cb fix: improve batch handling 2022-05-19 23:42:25 +02:00
ThaUnknown
8969d293e4 fix: S2 text being removed from titles, player failing on no media, improve resolveFileMedia speed 2022-05-19 22:29:26 +02:00
ThaUnknown
26a1741aae feat: custom electron dist 2022-05-19 18:16:47 +02:00
ThaUnknown
fc5b91e027 fix: remove will-change from transform on search bars 2022-05-09 21:33:52 +02:00
ThaUnknown
84a1c11e99 fix: blurry card zoom 2022-05-09 01:05:57 +02:00
ThaUnknown
41e983b135 Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2022-05-07 00:22:42 +02:00
ThaUnknown
fd49d2b4d2 fix, feat: reduce UI size, change schedule to start from today, filter airing schedule, infinite scrolling resetting filters 2022-05-07 00:22:39 +02:00
Cas
bbbe2fc050
docs: update faq 2022-05-06 12:38:30 +02:00
ThaUnknown
789c4bd144 fix: home screen invalid genres 2022-05-05 23:45:41 +02:00
ThaUnknown
3ff4c5543c feat: filtering of custom lists 2022-05-05 21:28:45 +02:00
ThaUnknown
dddd06340d chore: bump version 2022-05-05 01:07:50 +02:00
ThaUnknown
a36ee4dbc9 feat: allow changing search parameters for preset values, improve performance on infinite scrolling [a lot] 2022-05-05 01:07:31 +02:00
ThaUnknown
7355b915ef fix: al entries not working on media&/files with no episode# 2022-05-04 13:51:20 +02:00
ThaUnknown
15c898b53d feat: sort user lists by last updated 2022-05-04 02:09:50 +02:00
ThaUnknown
59863dea65 bump ver 2022-05-02 19:44:14 +02:00
ThaUnknown
c723415b1a UI: add tag on cards which failed parsing, add times to schedule, add feedback on no audio, detect codec support 2022-05-02 19:44:02 +02:00
ThaUnknown
c6e7a84dbb remove dead code, exclude short titles which are likely to break elastisearch 2022-05-02 17:26:48 +02:00
ThaUnknown
26da1a4c3b fix torrent propagation in w2g 2022-04-30 18:37:01 +02:00
ThaUnknown
7030b5516e oops 2022-04-30 13:54:45 +02:00
ThaUnknown
b6901d9f24 add sukebi for adult 2022-04-30 13:50:37 +02:00
ThaUnknown
7f9b1d385b Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2022-04-24 21:53:19 +02:00
ThaUnknown
a5e0b33c46 fix #162 2022-04-24 21:53:17 +02:00
Cas
6fa4120fc3
Delete feature_request.md 2022-04-24 21:39:18 +02:00
Cas
9b6349f611
Create feature_request.yml 2022-04-24 21:39:07 +02:00
Cas
d3bf58241c
Delete bug_report.md 2022-04-24 21:36:00 +02:00
Cas
07b14caad9
Update bug_report.yml 2022-04-24 21:35:23 +02:00
Cas
d9d84a9795
Create bug_report.yml 2022-04-24 21:34:47 +02:00
Cas
26af701f98
Create config.yml 2022-04-24 21:21:17 +02:00
ThaUnknown
36d267be26 minor UI improvements 2022-04-24 02:25:58 +02:00
ThaUnknown
a11516e088 feat: move WT to worker, UI fixes, UI improvements 2022-04-24 02:03:28 +02:00
ThaUnknown
ec3dd4924f marginally reduce package size, improve file naming 2022-04-24 00:39:56 +02:00
ThaUnknown
1db850f58d fix w2g torrent emitting 2022-04-24 00:28:13 +02:00
ThaUnknown
1002ca8c58 update webtorrent [experimenta] 2022-04-22 14:10:25 +02:00
ThaUnknown
845df4cba7 update electron, bring offscreenrender back 2022-04-21 23:03:55 +02:00
ThaUnknown
0b0633c29e feedback on invalid code 2022-04-21 19:48:44 +02:00
ThaUnknown
95ce41592f fix: improve w2g 2022-04-21 19:30:43 +02:00
ThaUnknown
e16cc976b8 fix dates not being created properly 2022-04-21 15:31:37 +02:00
ThaUnknown
faa3b882af oops, #148 2022-04-20 14:07:13 +02:00
ThaUnknown
3f185bd254 fix #153 2022-04-20 13:58:58 +02:00
ThaUnknown
0814a77164 fix #148 2022-04-20 12:49:11 +02:00
ThaUnknown
56339fcffc fix #158 2022-04-20 12:41:18 +02:00
ThaUnknown
369c698a76 feat: add w2g
fix: #154
2022-04-19 00:09:26 +02:00
ThaUnknown
aba4083278 fix #149 2022-04-16 16:05:03 +02:00
ThaUnknown
96cf728459 faq 2022-04-16 01:37:59 +02:00
ThaUnknown
818d104801 fix #123 2022-04-16 01:13:24 +02:00
ThaUnknown
1f1f215532 #138 2022-04-16 00:48:51 +02:00
ThaUnknown
eeff47d38f change names 2022-04-16 00:09:44 +02:00
ThaUnknown
0ad24df38a bump ver 2022-04-16 00:04:30 +02:00
ThaUnknown
725affb036 fix: #135 2022-04-16 00:02:37 +02:00
ThaUnknown
7fbad528a4 faq 2022-04-15 21:35:57 +02:00
ThaUnknown
0670fdb150 fix: close buttons being off-center 2022-04-15 21:34:22 +02:00
ThaUnknown
cc22b2147d feat: nandesuka feed
fix: version reporting
minior cleanup
2022-04-15 21:21:55 +02:00
ThaUnknown
2465b31d58 Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2022-04-15 13:32:02 +02:00
ThaUnknown
8cfb28243d update readme 2022-04-15 13:32:01 +02:00
Cas
fc06a4decf
Merge pull request #144 from Muril-o/master
Fix app icon for linux and macOS
2022-04-14 22:58:30 +02:00
Muril-o
b4408b59ef Fix app icon for linux and macOS 2022-04-14 19:24:59 +00:00
ThaUnknown
b42144a559 feat: better handling of empty sections #141 2022-04-14 15:07:09 +02:00
ThaUnknown
1be5e79af4 feat: add version to settings menu 2022-04-14 00:45:26 +02:00
ThaUnknown
786df48338 macOS is great 2022-04-12 12:50:48 +02:00
Cas
0a7b52c3e7
Merge pull request #139 from Muril-o/master
Changed external anilist token to be sent through IPC from main to renderer
2022-04-12 11:47:47 +02:00
Cas
1c5ea8260e
remove redundant code 2022-04-12 11:43:02 +02:00
Cas
b5d953f833
fix exception on no token 2022-04-12 11:41:53 +02:00
Muril-o
34292c1fcc Changed external anilist token to be sent through IPC from main to renderer 2022-04-12 03:44:38 -03:00
ThaUnknown
2179c3b145 bump ver 2022-04-12 00:52:38 +02:00
ThaUnknown
71a3317907 Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2022-04-12 00:52:28 +02:00
ThaUnknown
03df7971a9 fix: exlude prequel from search for "part 2" shows 2022-04-12 00:52:26 +02:00
Cas
d1d47d40e6
Update README.md 2022-04-12 00:35:47 +02:00
Cas
0b8350b42d
still playing with the readme 2022-04-12 00:30:32 +02:00
ThaUnknown
0da954e7bb Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2022-04-12 00:24:09 +02:00
ThaUnknown
9322a577c8 update readme 2022-04-12 00:24:08 +02:00
Cas
d13dd7e723
Update README.md 2022-04-11 23:27:57 +02:00
ThaUnknown
79abedf128 improve rss lookup 2022-04-11 22:07:49 +02:00
ThaUnknown
d1982203ae fix: finally fix AL? 2022-04-11 21:37:10 +02:00
ThaUnknown
21bc239345 fix: al login, duplicate process handling, add more sections to home 2022-04-11 21:19:44 +02:00
ThaUnknown
6e5c15a808 fix: al login 2022-04-11 18:21:46 +02:00
ThaUnknown
a9b924ab52 fix: RSS url including illegal chars, closing modals with ESC and by clicking whitespace, disabled offscreenRendering on subtitles for PiP 2022-04-11 17:31:36 +02:00
ThaUnknown
0fe922146f fix: no items showing up in RSS 2022-04-11 16:05:19 +02:00
ThaUnknown
e1161067a4 fix: better progress bar alignment 2022-04-11 15:45:28 +02:00
ThaUnknown
aa16c10dcf feat: external AL login 2022-04-11 14:56:31 +02:00
ThaUnknown
739c24745b fix: s2 shows showing in s1 lookups 2022-04-11 14:10:07 +02:00
ThaUnknown
ee8bd6d237 feat: piece download progress 2022-04-11 13:46:48 +02:00
ThaUnknown
1a0adfc472 fix: setpositionstate error 2022-04-11 01:08:51 +02:00
ThaUnknown
61da6ae049 bump 2022-04-10 20:19:24 +02:00
ThaUnknown
5726a32710 fix: improve seasonal detection 2022-04-10 20:18:27 +02:00
ThaUnknown
1562375612 fix: remove name caching, handle fetch errors, paginate releases 2022-04-10 15:49:45 +02:00
ThaUnknown
f2bc177608 fix: reload on removed relations 2022-04-09 23:57:17 +02:00
ThaUnknown
2e91889559 fix: improve season parsing, better feedback on rate limit, search looking for null, multiple torrent event listeners, unneeded elevated install prompt 2022-04-09 23:55:28 +02:00
ThaUnknown
712abc89bb fix: icon 2022-04-09 14:38:02 +02:00
ThaUnknown
3294655d54 oops 2022-04-06 21:29:52 +02:00
ThaUnknown
881ca0f0e1 feat: add lookup for absolute episode numbering for nyaa 2022-04-06 21:26:56 +02:00
ThaUnknown
83637c7581 fix: marching forward working incorrectly 2022-04-06 20:37:01 +02:00
ThaUnknown
a0b1d4d60f fix: edge case when season resolving would get stuck in an infinite loop 2022-04-06 19:40:33 +02:00
ThaUnknown
264b267f57 fix: search clearing 2022-04-04 20:35:20 +02:00
ThaUnknown
ac26570117 fix cors issues, fix viewanime issues, add plan to watch button, add trailer button, fix video check completion, cleanup entries code 2022-04-04 16:51:56 +02:00
ThaUnknown
a3d4698d34 fix: releases breaking on finished anime 2022-04-04 10:56:51 +02:00
ThaUnknown
8e40e85b33 allow to change installation path 2022-04-02 18:59:50 +02:00
ThaUnknown
4176d016b3 fix: crash on boot 2022-04-02 18:05:26 +02:00
ThaUnknown
0d7ff4780f Merge branch 'master' of https://github.com/ThaUnknown/miru into master 2022-04-02 17:38:33 +02:00
ThaUnknown
95e8c8e6cb fix: webtorrent IPC, test version 2022-04-02 17:38:12 +02:00
Cas
02df93bb42
Merge pull request #121 from Waaiez/master
Create Github Actions
2022-03-30 01:00:18 +02:00
Waaiez Kinnear
2d3a5cebb6 Create Github Actions
Run action on every push
2022-03-30 00:56:41 +02:00
ThaUnknown
3827aa74b0 update docs 2022-03-27 21:34:43 +02:00
ThaUnknown
e166e79b01 fix popup saying undefined 2022-03-26 11:29:52 +01:00
ThaUnknown
dc813fcdf9 add parsing, improve embedded font handling 2022-03-24 19:30:16 +01:00
ThaUnknown
ea223d02d2 UX: feedback on no torrents found 2022-03-22 02:07:48 +01:00
ThaUnknown
da5ec3dbd5 better name/season resolver 2022-03-21 17:41:13 +01:00
ThaUnknown
c0e2a639cd fix: rpc 2022-03-21 00:11:27 +01:00
ThaUnknown
9263f32b07 add homepage 2022-03-20 18:10:45 +01:00
ThaUnknown
7e3cc2eb2c bump ver 2022-03-20 18:03:07 +01:00
ThaUnknown
0edba554e9 feat: detect nyaa block, re-add paste functionality 2022-03-20 18:02:53 +01:00
ThaUnknown
679bf856c6 feat: add discord RPC 2022-03-20 00:15:14 +01:00
ThaUnknown
239b8af705 bring license file back 2022-03-19 21:38:08 +01:00
ThaUnknown
45d2a7e8a3 fix: i'm dumb 2022-03-19 16:32:19 +01:00
ThaUnknown
501b351b98 fix: re-add search fields on presets 2022-03-19 03:02:23 +01:00
ThaUnknown
c6d5c0b4c9 feat: toasts, show errors for RSS fetch fails, show ratelimit errors, show resolving warnings, show low seeder warnings, fix viewanime progress 2022-03-19 02:35:30 +01:00
ThaUnknown
4d40b9c182 fix: OOB episode completion 2022-03-18 20:49:33 +01:00
ThaUnknown
c4d01569a6 fix: miniplayer layout shift, miniplayer hover darken 2022-03-18 19:16:25 +01:00
ThaUnknown
3420fafc3a better miniplayer 2022-03-18 18:35:03 +01:00
ThaUnknown
f763242755 feat: add airing schedule 2022-03-18 15:33:54 +01:00
ThaUnknown
574cc09860 feat: add pagination to all searches 2022-03-18 01:18:13 +01:00
ThaUnknown
bb8d8c5ad5 fix: fetch files over browser rather than node 2022-03-17 21:10:40 +01:00
ThaUnknown
dce49feee5 fix: clamp video player size 2022-03-17 21:01:05 +01:00
ThaUnknown
2af621ea99 manual patch for matroska-subtitles 2022-03-17 20:21:13 +01:00
ThaUnknown
25c4fa392d dont support 32 bit 2022-03-17 12:31:46 +01:00
Cas
6445f5010e
Merge pull request #110 from Muril-o/109-video-not-playing
Fix for video not playing due to user not being logged in anilist
2022-03-17 11:19:22 +01:00
Muril-o
370a61f5ec Fix for video not playing due to user not being logged in anilist 2022-03-17 06:59:39 -03:00
Cas
7f859f3b9f
Merge pull request #106 from Muril-o/e01-package-update
Updated and added additional parameters for building the app
2022-03-16 20:47:07 +01:00
Muril-o
2b80a2a348 Typo fix and version up 2022-03-16 13:16:33 -03:00
Muril-o
91e5f4ea21 Updated and added additional parameters for building the app 2022-03-16 13:11:37 -03:00
Cas
67a1332e09
Merge pull request #104 from Muril-o/101-anilist-login
Anilist logout issue fix
2022-03-15 23:28:15 +01:00
Muril-o
3f5a8a2529 Fixed anilist logout issue 2022-03-15 18:57:44 -03:00
ThaUnknown
4650ea99da fix AL logout 2022-03-15 20:39:09 +01:00
453 changed files with 29877 additions and 5777 deletions

1
.github/FUNDING.yml vendored
View file

@ -1,2 +1 @@
github: ThaUnknown
ko_fi: thaunknown_

View file

@ -1,31 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. Windows|Linux]
- Version [e.g. v0.1.0]
**Additional context**
Add any other context about the problem here.

65
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View file

@ -0,0 +1,65 @@
name: Bug report
description: Report a bug.
title: '[Bug]: '
labels:
- bug
body:
- type: checkboxes
id: '1'
attributes:
label: Preflight checklist
description: Make sure you completed this before creating an issue.
options:
- label: >-
I have searched the [issue
tracker](https://github.com/hayase-app/ui/issues) for a bug report
that matches the one I want to file, without success.
required: true
- label: >-
I have searched the [frequently asked
questions](https://hayase.watch/faq) for a solution to my problem,
for a solution that fixes this problem, without success.
required: true
- label: >-
I have checked that I'm using the [latest
stable](https://github.com/hayase-app/ui/releases/latest) version
of the app.
required: true
- type: input
id: '2'
attributes:
label: What app version are you using?
description: >-
The app version you are currently using, you can view this at the bottom
of the settings menu.
placeholder: v2.0.1
validations:
required: true
- type: dropdown
id: '3'
attributes:
label: What operating system version are you using?
options:
- Windows
- Linux
- MacOS
- Android
validations:
required: true
- type: textarea
id: '4'
attributes:
label: Expected Behavior
description: A clear and concise description of what you expected to happen.
- type: textarea
id: '5'
attributes:
label: Actual Behavior
description: A clear description of what actually happens.
validations:
required: true
- type: textarea
id: '6'
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem.

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1 @@
blank_issues_enabled: false

View file

@ -1,17 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or screenshots about the feature request here.

View file

@ -0,0 +1,43 @@
name: Feature Request
description: Suggest an idea for the app.
title: '[Feature Request]: '
labels:
- enhancement
body:
- type: checkboxes
id: '1'
attributes:
label: Preflight checklist
description: Make sure you completed this before creating an issue.
options:
- label: >-
I have searched the [issue
tracker](https://github.com/hayase-app/ui/issues) for a bug report
that matches the one I want to file, without success.
required: true
- label: >-
I have searched the [features
list](https://hayase.watch/features) for this feature,
and I couldn't find it.
required: true
- label: >-
I have checked that I'm using the [latest
stable](https://github.com/hayase-app/ui/releases/latest) version
of the app.
required: true
- type: textarea
id: '4'
attributes:
label: Problem Description
description: >-
Please add a clear and concise description of the problem you are
seeking to solve with this feature request.
validations:
required: true
- type: textarea
id: '5'
attributes:
label: Proposed Solution
description: Describe the solution you'd like in a clear and concise manner.
validations:
required: true

39
.github/workflows/check.yml vendored Normal file
View file

@ -0,0 +1,39 @@
name: Check
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
name: Install pnpm
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22.19
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Sync
run: pnpm run sync
- name: Lint
run: pnpm run lint
- name: Check GQL
run: pnpm run gql:check
- name: Check Svelte and TypeScript
run: pnpm run check

28
.gitignore vendored
View file

@ -1,10 +1,26 @@
# OS Specific
node_modules
# Output
.output
.vercel
/.svelte-kit
/build
# OS
.DS_Store
Thumbs.db
# Build output
dist/
# Env
.env
.env.*
!.env.example
!.env.test
ideas.todo
# Dependencies
node_modules/
# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
package-lock.json
*.mkv
*.webm
*src/routes/test/**

1
.npmrc Normal file
View file

@ -0,0 +1 @@
engine-strict=true

View file

@ -1,10 +0,0 @@
{
"useTabs": false,
"jsxSingleQuote": true,
"printWidth": 180,
"semi": false,
"singleQuote": true,
"svelteBracketNewLine": false,
"arrowParens": "avoid",
"trailingComma": "none"
}

13
.vscode/extensions.json vendored Normal file
View file

@ -0,0 +1,13 @@
{
"recommendations": [
"usernamehw.errorlens",
"dbaeumer.vscode-eslint",
"GraphQL.vscode-graphql-syntax",
"bierner.comment-tagged-templates",
"YoavBls.pretty-ts-errors",
"svelte.svelte-vscode", // 109.5.2 or older NOT NEWER
"ardenivanov.svelte-intellisense",
"Gruntfuggly.todo-tree",
"bradlc.vscode-tailwindcss"
]
}

39
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,39 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chromium",
"port": 8412,
"request": "launch",
"type": "chrome",
"url": "http://localhost:7344/",
"webRoot": "${workspaceFolder}/src",
"timeout": 60000,
"presentation": {
"hidden": true
}
},
{
"name": "Debug Renderer Process",
"port": 9222,
"request": "attach",
"type": "chrome",
"webRoot": "${workspaceFolder}/src",
"timeout": 60000,
"presentation": {
"hidden": false
}
}
],
"compounds": [
{
"name": "Attach",
"configurations": [
"Launch Chromium"
],
"presentation": {
"order": 1
}
}
]
}

43
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,43 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always"
},
"editor.formatOnSave": true,
"editor.linkedEditing": true,
"editor.tabSize": 2,
"eslint.format.enable": true,
"eslint.probe": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"svelte",
"html"
],
"eslint.useESLintClass": true,
"eslint.useFlatConfig": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"svelte",
"html"
],
"javascript.preferences.importModuleSpecifierEnding": "minimal",
"javascript.preferences.quoteStyle": "single",
"javascript.suggest.autoImports": true,
"javascript.updateImportsOnFileMove.enabled": "always",
"javascript.validate.enable": true,
"extensions.ignoreRecommendations": false,
"svelte.plugin.svelte.format.config.singleQuote": true,
"svelte.plugin.svelte.format.enable": false,
"typescript.enablePromptUseWorkspaceTsdk": true,
"typescript.experimental.expandableHover": true,
"typescript.preferences.importModuleSpecifierEnding": "minimal",
"typescript.preferences.quoteStyle": "single",
"typescript.suggest.autoImports": true,
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.updateImportsOnFileMove.enabled": "always",
"typescript.validate.enable": true
}

166
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,166 @@
# Contributing Guidelines
*Pull requests, bug reports, and all other forms of contribution are welcomed and highly encouraged!* :octocat:
### Contents
* [Opening an Issue](#inbox_tray-opening-an-issue)
* [Feature Requests](#love_letter-feature-requests)
* [Triaging Issues](#mag-triaging-issues)
* [Submitting Pull Requests](#repeat-submitting-pull-requests)
* [Writing Commit Messages](#memo-writing-commit-messages)
* [Code Review](#white_check_mark-code-review)
* [Coding Style](#nail_care-coding-style)
* [Certificate of Origin](#medal_sports-certificate-of-origin)
* [Credits](#pray-credits)
> **This guide serves to set clear expectations for everyone involved with the project so that we can improve it together while also creating a welcoming space for everyone to participate. Following these guidelines will help ensure a positive experience for contributors and maintainers.**
## :inbox\_tray: Opening an Issue
Before [creating an issue](https://help.github.com/en/github/managing-your-work-on-github/creating-an-issue), check if you are using the latest version of the project. If you are not up-to-date, see if updating fixes your issue first.
### :lock: Reporting Security Issues
Review our [Security Policy](./SECURITY.md). **Do not** file a public issue for security vulnerabilities.
### :beetle: Bug Reports and Other Issues
A great way to contribute to the project is to send a detailed issue when you encounter a problem. We always appreciate a well-written, thorough bug report. :v:
In short, since you are most likely a developer, **provide a ticket that you would like to receive**.
* **Review the documentation and [Support Guide](./SUPPORT.md)** before opening a new issue.
* **Do not open a duplicate issue!** Search through existing issues to see if your issue has previously been reported. If your issue exists, comment with any additional information you have. You may simply note "I have this problem too", which helps prioritize the most common problems and requests.
* **Prefer using [reactions](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/)**, not comments, if you simply want to "+1" an existing issue.
* **Fully complete the provided issue template.** The bug report template requests all the information we need to quickly and efficiently address your issue. Be clear, concise, and descriptive. Provide as much information as you can, including steps to reproduce, stack traces, compiler errors, library versions, OS versions, and screenshots (if applicable).
* **Use [GitHub-flavored Markdown](https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax).** Especially put code blocks and console outputs in backticks (\`\`\`). This improves readability.
## :love\_letter: Feature Requests
Feature requests are welcome! While we will consider all requests, we cannot guarantee your request will be accepted. We want to avoid [feature creep](https://en.wikipedia.org/wiki/Feature_creep). Your idea may be great, but also out-of-scope for the project. If accepted, we cannot make any commitments regarding the timeline for implementation and release. However, you are welcome to submit a pull request to help!
* **Do not open a duplicate feature request.** Search for existing feature requests first. If you find your feature (or one very similar) previously requested, comment on that issue.
* **Fully complete the provided issue template.** The feature request template asks for all necessary information for us to begin a productive conversation.
* Be precise about the proposed outcome of the feature and how it relates to existing features. Include implementation details if possible.
## :mag: Triaging Issues
You can triage issues which may include reproducing bug reports or asking for additional information, such as version numbers or reproduction instructions. Any help you can provide to quickly resolve an issue is very much appreciated!
## :repeat: Submitting Pull Requests
We **love** pull requests! Before [forking the repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) and [creating a pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests) for non-trivial changes, it is usually best to first open an issue to discuss the changes, or discuss your intended approach for solving the problem in the comments for an existing issue.
For most contributions, after your first pull request is accepted and merged, you will be [invited to the project](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/inviting-collaborators-to-a-personal-repository) and given **push access**. :tada:
*Note: All contributions will be licensed under the project's license.*
* **Smaller is better.** Submit **one** pull request per bug fix or feature. A pull request should contain isolated changes pertaining to a single bug fix or feature implementation. **Do not** refactor or reformat code that is unrelated to your change. It is better to **submit many small pull requests** rather than a single large one. Enormous pull requests will take enormous amounts of time to review, or may be rejected altogether.
* **Coordinate bigger changes.** For large and non-trivial changes, open an issue to discuss a strategy with the maintainers. Otherwise, you risk doing a lot of work for nothing!
* **Prioritize understanding over cleverness.** Write code clearly and concisely. Remember that source code usually gets written once and read often. Ensure the code is clear to the reader. The purpose and logic should be obvious to a reasonably skilled developer, otherwise you should add a comment that explains it.
* **Follow existing coding style and conventions.** Keep your code consistent with the style, formatting, and conventions in the rest of the code base. When possible, these will be enforced with a linter. Consistency makes it easier to review and modify in the future.
* **Include test coverage.** Add unit tests or UI tests when possible. Follow existing patterns for implementing tests.
* **Update the example project** if one exists to exercise any new functionality you have added.
* **Add documentation.** Document your changes with code doc comments or in existing guides.
* **Use the repo's default branch.** Branch from and [submit your pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) to the repo's default branch. Usually this is `main`, but it could be `dev`, `develop`, or `master`.
* **[Resolve any merge conflicts](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github)** that occur.
* **Promptly address any CI failures**. If your pull request fails to build or pass tests, please push another commit to fix it.
* When writing comments, use properly constructed sentences, including punctuation.
* Use spaces, not tabs.
## :memo: Writing Commit Messages
Please [write a great commit message](https://chris.beams.io/posts/git-commit/).
1. Separate subject from body with a blank line
2. Limit the subject line to 50 characters
3. Capitalize the subject line
4. Do not end the subject line with a period
5. Use the imperative mood in the subject line (example: "Fix networking issue")
6. Wrap the body at about 72 characters
7. Use the body to explain **why**, *not what and how* (the code shows that!)
8. If applicable, prefix the title with the relevant component name in a semantic way. (examples: "fix: typo", "feat: add avatar")
```
docs: Short summary of changes in 50 chars or less
Add a more detailed explanation here, if necessary. Possibly give
some background about the issue being fixed, etc. The body of the
commit message can be several paragraphs. Further paragraphs come
after blank lines and please do proper word-wrap.
Wrap it to about 72 characters or so. In some contexts,
the first line is treated as the subject of the commit and the
rest of the text as the body. The blank line separating the summary
from the body is critical (unless you omit the body entirely);
various tools like `log`, `shortlog` and `rebase` can get confused
if you run the two together.
Explain the problem that this commit is solving. Focus on why you
are making this change as opposed to how or what. The code explains
how or what. Reviewers and your future self can read the patch,
but might not understand why a particular solution was implemented.
Are there side effects or other unintuitive consequences of this
change? Here's the place to explain them.
- Bullet points are okay, too
- A hyphen or asterisk should be used for the bullet, preceded
by a single space, with blank lines in between
Note the fixed or relevant GitHub issues at the end:
Resolves: #123
See also: #456, #789
```
## :white\_check\_mark: Code Review
* **Review the code, not the author.** Look for and suggest improvements without disparaging or insulting the author. Provide actionable feedback and explain your reasoning.
* **You are not your code.** When your code is critiqued, questioned, or constructively criticized, remember that you are not your code. Do not take code review personally.
* **Always do your best.** No one writes bugs on purpose. Do your best, and learn from your mistakes.
* Kindly note any violations to the guidelines specified in this document.
## :nail\_care: Coding Style
Consistency is the most important. Following the existing style, formatting, and naming conventions of the file you are modifying and of the overall project. Failure to do so will result in a prolonged review process that has to focus on updating the superficial aspects of your code, rather than improving its functionality and performance.
For example, if all private properties are prefixed with an underscore `_`, then new ones you add should be prefixed in the same way. Or, if methods are named using camelcase, like `thisIsMyNewMethod`, then do not diverge from that by writing `this_is_my_new_method`. You get the idea. If in doubt, please ask or search the codebase for something similar.
When possible, style and format will be enforced with a linter.
## :medal\_sports: Certificate of Origin
*Developer's Certificate of Origin 1.1*
By making a contribution to this project, I certify that:
> 1. The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
> 2. The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
> 3. The contribution was provided directly to me by some other person who certified (1), (2) or (3) and I have not modified it.
> 4. I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the source license(s) involved.
## [No Brown M\&M's](https://en.wikipedia.org/wiki/Van_Halen#Contract_riders)
If you are reading this, bravo dear user and (hopefully) contributor for making it this far! You are awesome. :100:

47
LICENSE Normal file
View file

@ -0,0 +1,47 @@
Business Source License 1.1
Terms
The Licensor hereby grants you the right to copy, modify, create derivative
works, redistribute, and make non-production use of the Licensed Work. The
Licensor may make an Additional Use Grant, above, permitting limited
production use.
Effective on the Change Date, or the fourth anniversary of the first publicly
available distribution of a specific version of the Licensed Work under this
License, whichever comes first, the Licensor hereby grants you rights under
the terms of the Change License, and the rights granted in the paragraph
above terminate.
If your use of the Licensed Work does not comply with the requirements
currently in effect as described in this License, you must purchase a
commercial license from the Licensor, its affiliated entities, or authorized
resellers, or you must refrain from using the Licensed Work.
All copies of the original and modified Licensed Work, and derivative works
of the Licensed Work, are subject to this License. This License applies
separately for each version of the Licensed Work and the Change Date may vary
for each version of the Licensed Work released by Licensor.
You must conspicuously display this License on each original or modified copy
of the Licensed Work. If you receive the Licensed Work in original or
modified form from a third party, the terms and conditions set forth in this
License apply to your use of that work.
Any use of the Licensed Work in violation of this License will automatically
terminate your rights under this License for the current and all other
versions of the Licensed Work.
This License does not grant you any right in any trademark or logo of
Licensor or its affiliates (provided that you may use a trademark or logo of
Licensor as expressly required by this License).
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
TITLE.
Change Date: 2029-04-01
On the date above, in accordance with the Business Source License, use of this software will be governed by the open source license GPL-3.0.

162
README.md
View file

@ -1,18 +1,158 @@
# Miru
<p align="center">
<a href="https://github.com/hayase-app/ui">
<img src="./static/logo_white.svg" width="300">
</a>
</p>
<h1 align="center"><b>Hayase</b></h1>
Discord link: https://discord.gg/Z87Nh7c4Ac
<h4 align="center"><b>Stream anime torrents instantly, real-time with no waiting for downloads to finish! 🍿</b></h4>
Originally a joke project, turned out to be semi-viable.
<p align="center">
<a href="https://hayase.watch/#about">About</a>
<a href="https://hayase.watch/features/">Features</a>
<a href="https://hayase.watch/faq/">Frequently Asked Questions</a>
<a href="https://hayase.watch/download/">Download</a>
</p>
<p align="center">
<a href="https://discord.gg/Z87Nh7c4Ac">
<img src="https://img.shields.io/discord/953341991134064651?style=flat-square" alt="chat">
</a>
<a href="https://hayase.watch/download/">
<img alt="Download" src="https://img.shields.io/github/downloads/hayase-app/ui/total?style=flat-square">
</a>
</p>
A pure JS BitTorrent streaming environment, with a built-in list manager. Imagine qBit + Taiga + MPV, all in a single package, but streamed real-time.
https://github.com/user-attachments/assets/bbbe2966-b773-4ebb-9d69-08248ae77ae4
Unlike qBit's sequential, seeking into undownloaded data will prioritise downloading that data, instead of flat out closing MPV.
<p align="center">Formerly known as Miru.</p>
## Why Electron?
Electron has node.js integration, which can use TCP/UDP, that is the only reason. Browsers can't access TCP/UDP which means they can't access the global BT swarm.
> Can't you make this just use WebRTC?
## ✨ About
Yes. A BitTorrent implementation which uses WebRTC exists, but it's not yet adopted by any clients, and libtorrent [the library which qBit and others use] is still working/just added support for WebRTC, which means there's no swarm. This will hopefully change in the future.
**Hayase** is a modern app for streaming anime torrents in real-time, with no waiting for downloads to finish.
## Where codec support?
This uses the browser's built in video player, which uses a cut down version of FFMPEG, which lacks a support for a LOT of containers and codecs because of licensing. Since Electron is just Chromium IN THEORY it is possible to re-compile FFMPEG with support for more containers and codecs, but people seem to be going out of their way to make sure you can't find how to do that. PR pls?
It is meant to feel look, work and perform like a premium streaming service, but with all the benefits of both streaming and torrenting, like file downloads, higher download speeds, better video quality, instant access to new releases, and features you wont find on typical streaming sites.
## 🌟 Highlights
* 📚 **Anime list integration:** Sync with AniList, Kitsu, ~~MAL~~, or use local storage.
* ⚡ **Instant torrent streaming:** Watch as you download, with extension support for custom sources.
* 📴 **Offline viewing:** Enjoy already-downloaded torrents anytime.
* 🎬 **Advanced video player:** Full support for all subtitle formats, softcoded and external tracks, and more.
* 👥 **Social features:** Connect with friends, join discussions, and watch together.
***
## 🏆 Features
### 🎞️ Anime Management
* Effortlessly manage your anime list with support for AniList, Kitsu, ~~MAL~~, and local storage.
* Automatically track watched episodes.
* See what youre behind on, and discover sequels youve missed.
* Keep up to date and browse upcoming episodes with airing calendars.
* Edit entries (score, progress, status, favorite, etc.) even while offline.
* Search by image, name, genre, year, season, and more.
* View trailers, OP/ED themes, and detailed episode lists with thumbnails, descriptions and filler indicators.
<p align="center">
<img src='https://raw.githubusercontent.com/hayase-app/website/main/static/viewanime.webp' width='400px'></img>
</p>
### 🤝 Social & Community
* Instantly see which friends are following an anime or episode.
* See friends profiles and watch progress in the episodes list.
* Track your friends watch progress in real time.
* Join episode discussions and forums, even offline.
* Global app chat.
* Discord rich pressence.
* Host or join Watch Together lobbies with synced playback and chat.
### 🎥 Video Experience
* Full subtitle support.
* Softcoded, external and manually added subtitles.
* VTT, SSA, ASS, SUB, TXT formats.
* Subtitle display in PiP.
* Override default dialog styles.
* Override default fonts for Asian languages \[fix for bad torrents].
* Picture In Picture.
* PiP on lost visiblity.
* Pause on lost visibility.
* Specify preferred language for video and subtitle tracks.
* Remove video compression artifacts.
* Miniplayer.
* Media Session display.
* Media Keys support.
* Discord rich pressence.
* Seek and preview thumbnails.
* Autoplay next episode.
* Skip intro/outro, manually or automatically.
* Skip filler episodes automatically.
* Change playback rate.
* Browse playlist.
* Multi-track support for video, audio and subtitles.
* Editable keybinds for all player functions.
* Exponential volume \[better control at lower volumes].
* External player support.
<p align="center">
<img src='https://raw.githubusercontent.com/hayase-app/website/main/static/videoplayer.webp' width='400px'></img>
</p>
### 🧲 Torrents
* Stream torrents instantly, no waiting for full downloads.
* Download only what you need for playback.
* Choose your downloads folder and set speed/connection limits.
* Support for custom extensions, sources, and trackers.
* Specify download/upload speeds, ports and connections.
* Support for most popular BEP's.
* Persist torrents, cache progress, and rescan instantly.
* View detailed torrent and peer info.
* Batch downloads.
<p align="center">
<img src='https://raw.githubusercontent.com/hayase-app/website/main/static/modal.webp' width='400px'></img>
</p>
### ⚙️ Performance & Security
* Highly secure.
* Operates on a Zero Trust model.
* Protects data integrity and settings from external attacks.
* Protects from attacks via malicious torrent extensions.
* Uses up to date best security practices for native apps.
* Insanely performant.
* Fully hardware/GPU accelerated.
* GPU based shaders, animations and paints.
* Very low resource utilisation.
* Only loads code as required by user navigation.
* Unloads code not in use.
* Doesn't render unnecessary UI updates.
* Disables rendering when not visible.
* Doesn't render any UI when immersed in fullscreen video.
* Minimise to tray.
* In-app changelog.
* Custom themes.
<p align="center">
<img src='https://raw.githubusercontent.com/hayase-app/website/main/static/simple.webp' width='400px'></img>
</p>
## **Building and Development**
Requires `Node 20` or above and `pnpm`. VSCode is recommended.
```js
pnpm i // to install
pnpm run dev // to develop
pnpm run build // to build
pnpm run sync && pnpm run lint && pnpm run gql:check && pnpm run check // to test
```
***
<h2 align="center">
<b>Enjoy streaming anime the way it should be! 🍿</b>
</h2>

13
SECURITY.md Normal file
View file

@ -0,0 +1,13 @@
# Security Policy
If you discover a security issue, please bring it to our attention right away!
## Reporting a Vulnerability
Please **DO NOT** file a public issue to report a security vulberability, instead send your report privately to **casistaken@gmail.com**. This will help ensure that any vulnerabilities that are found can be [disclosed responsibly](https://en.wikipedia.org/wiki/Responsible_disclosure) to any affected parties.
## Supported Versions
Project versions that are currently being supported with security updates vary per project.
Please see specific project repositories for details.
If nothing is specified, only the latest major versions are supported.

31
SUPPORT.md Normal file
View file

@ -0,0 +1,31 @@
# Support and Help
Need help getting started or using a project? Here's how.
## How to get help
Generally, we do not use GitHub as a support forum. For any usage questions that are not specific to the project itself, please ask on [Stack Overflow](https://stackoverflow.com) instead. By doing so, you are more likely to quickly solve your problem, and you will allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others.
Please seek support in the following ways:
1. :book: **Read the documentation and other guides** for the project to see if you can figure it out on your own. These should be located in a root `docs/` directory. If there is an example project, explore that to learn how it works to see if you can answer your question.
2. :bulb: **Search for answers and ask questions on [Stack Overflow](https://stackoverflow.com).** This is the most appropriate place for debugging issues specific to your use of the project, or figuring out how to use the project in a specific way.
3. :memo: As a **last resort**, you may open an issue on GitHub to ask for help. However, please clearly explain what you are trying to do, and list what you have already attempted to solve the problem. Provide code samples, but **do not** attach your entire project for someone else to debug. Review our [contributing guidelines](./CONTRIBUTING.md).
## What NOT to do
Please **do not** do any the following:
1. :x: Do not reach out to the author or contributor on Twitter (or other social media) by tweeting or sending a direct message.
2. :x: Do not email the author or contributor.
3. :x: Do not open duplicate issues or litter an existing issue with +1's.
These are not appropriate avenues for seeking help or support with an open-source project. Please follow the guidelines in the previous section. Public questions get public answers, which benefits everyone in the community. ✌️
## Customer Support
I do not provide any sort of "customer support" for open-source projects. However, I am available for hire.

BIN
assets/Molot-webfont.woff Normal file

Binary file not shown.

5
assets/logo.svg Normal file
View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="430" height="430" viewBox="0 0 113.50625 113.50625" fill="currentColor">
<path d="M89.693749 72.830671v-19.84375l-18.520833-10.31875-14.552084-8.202083-33.072916 18.520833v19.84375l33.072916-18.520833ZM23.547916 47.695254l23.547916-13.229167L23.547916 21.23692Z" />
<path d="m23.547916 77.990044 33.072916 18.52084 33.072917-18.52084-18.520833-10.318746-14.552084 8.202083-14.552083-8.202083S23.547916 78.122337 23.547916 77.990044z" />
<path d="m56.620832 59.601503 10.054167 5.55625v.000001l-10.054167 5.55625-10.054166-5.55625v-.000001z"/>
</svg>

After

Width:  |  Height:  |  Size: 617 B

5
assets/logo_cropped.svg Normal file
View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="250" height="284.50003" viewBox="0 0 66.145833 75.273966" fill="currentColor">
<path d="M66.145833 51.593751v-19.84375c-11.042319-6.141466-22.077514-12.295645-33.072917-18.520833C22.048611 19.402779 11.024305 25.57639 0 31.750001v19.84375c11.024305-6.173611 22.048611-12.347222 33.072916-18.520833 11.024306 6.173611 22.048611 12.347222 33.072917 18.520833ZM0 26.458334c7.849305-4.409722 15.698611-8.819445 23.547916-13.229167C15.698611 8.819445 7.849305 4.409722 0 0v26.458334Z"/>
<path d="M0 56.753124c11.024305 6.173613 22.048611 12.347227 33.072916 18.52084 11.024306-6.173613 22.048611-12.347227 33.072917-18.52084L47.625 46.434378c-4.850695 2.734028-9.701389 5.468055-14.552084 8.202083-4.850694-2.734028-9.701389-5.468055-14.552083-8.202083C12.352694 49.88272 6.229007 53.417285 0 56.753124Z"/>
<path d="M33.072916 38.364583c3.351389 1.852084 6.70278 3.704166 10.054167 5.556251-3.35139 1.852082-6.702778 3.704167-10.054167 5.55625-3.351388-1.852084-6.702779-3.704166-10.054166-5.556251 3.35139-1.852082 6.702777-3.704167 10.054166-5.55625z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/twemoji.woff2 Normal file

Binary file not shown.

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>

View file

@ -1,30 +0,0 @@
const { notarize } = require('electron-notarize')
const path = require('path')
exports.default = async function notarizing (context) {
if (context.electronPlatformName !== 'darwin' || process.env.CSC_IDENTITY_AUTO_DISCOVERY === 'false') {
console.log('Skipping notarization')
return
}
console.log('Notarizing...')
const appBundleId = context.packager.appInfo.info._configuration.appId
const appName = context.packager.appInfo.productFilename
const appPath = path.normalize(path.join(context.appOutDir, `${appName}.app`))
const appleId = process.env.APPLE_ID
const appleIdPassword = process.env.APPLE_ID_PASSWORD
if (!appleId) {
console.warn('Not notarizing: Missing APPLE_ID environment variable')
return
}
if (!appleIdPassword) {
console.warn('Not notarizing: Missing APPLE_ID_PASSWORD environment variable')
return
}
return notarize({
appBundleId,
appPath,
appleId,
appleIdPassword
})
}

14
components.json Normal file
View file

@ -0,0 +1,14 @@
{
"$schema": "https://shadcn-svelte.com/schema.json",
"style": "new-york",
"tailwind": {
"config": "tailwind.config.ts",
"css": "src\\app.css",
"baseColor": "zinc"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils"
},
"typescript": true
}

27
eslint.config.js Normal file
View file

@ -0,0 +1,27 @@
import config from 'eslint-config-standard-universal'
import tseslint from 'typescript-eslint'
import svelteConfig from './svelte.config.js'
export default tseslint.config(
...config(),
{
languageOptions: {
parserOptions: {
tsconfigRootDir: import.meta.dirname,
svelteConfig
}
},
ignores: ['build/', '.svelte-kit/', 'node_modules/'],
rules: {
'@typescript-eslint/prefer-nullish-coalescing': [
'error',
{
ignoreConditionalTests: true,
ignoreMixedLogicalExpressions: false,
ignorePrimitives: true
}
]
}
}
)

View file

@ -0,0 +1,16 @@
import { writeFileSync } from 'node:fs'
import { getIntrospectedSchema, minifyIntrospectionQuery } from '@urql/introspection'
import { getIntrospectionQuery, type IntrospectionQuery } from 'graphql'
const res = await fetch('https://graphql.anilist.co', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
variables: {},
query: getIntrospectionQuery({ descriptions: false })
})
})
const { data } = (await res.json()) as { data: IntrospectionQuery }
const minified = minifyIntrospectionQuery(getIntrospectedSchema(data), { includeScalars: false, includeEnums: true, includeInputs: true, includeDirectives: true })
writeFileSync('./src/lib/modules/anilist/schema.json', JSON.stringify(minified))

View file

@ -1,70 +1,101 @@
{
"name": "Miru",
"version": "0.6.0",
"author": "ThaUnknown_",
"main": "src/index.js",
"scripts": {
"start": "SET NODE_ENV=development & concurrently \"npm run web:watch\" \"npm run electron:start\"",
"web:watch": "vite",
"electron:start": "electron src",
"build": "vite build && electron-builder",
"publish": "vite build && electron-builder -p always"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
"builtin-modules": "^3.2.0",
"concurrently": "^7.0.0",
"electron": "^16.0.10",
"electron-builder": "^22.14.13",
"electron-notarize": "^1.1.1",
"svelte": "^3.46.4",
"vite": "^2.8.6",
"vite-plugin-commonjs-externals": "^0.1.1"
},
"standard": {
"ignore": [
"bundle.js",
"bundle.map.js"
],
"env": "browser"
},
"build": {
"publish": [
{
"provider": "github",
"owner": "ThaUnknown",
"repo": "miru"
}
],
"afterSign": "./build/notarize.js",
"appId": "com.github.thaunknown.miru",
"productName": "Miru",
"files": [
"src/**/*"
],
"mac": {
"category": "public.app-category.video"
},
"win": {
"target": "nsis",
"icon": "src/renderer/public/logo.ico"
},
"linux": {
"category": "Video",
"target": "AppImage"
},
"nsis": {
"oneClick": false,
"installerIcon": "src/renderer/public/logo.ico",
"installerHeaderIcon": "src/renderer/public/logo.ico"
}
},
"dependencies": {
"@electron/remote": "^2.0.7",
"anitomyscript": "^2.0.4",
"electron-log": "^4.4.6",
"electron-updater": "^4.6.5",
"matroska-subtitles": "^3.3.2",
"webtorrent": "^1.5.0"
}
"name": "ui",
"version": "6.4.159",
"license": "BUSL-1.1",
"private": true,
"packageManager": "pnpm@9.15.5",
"scripts": {
"dev": "vite dev --open",
"build": "vite build && scopy ./build/index.html ./build/offline.html",
"preview": "vite preview",
"sync": "svelte-kit sync",
"check": "svelte-check --threshold error --tsconfig ./tsconfig.web.json",
"check:watch": "svelte-check -threshold error --tsconfig ./tsconfig.web.json --watch",
"test": "pnpm run sync && pnpm run lint && pnpm run gql:check && pnpm run check",
"lint": "eslint --quiet -c eslint.config.js",
"lint:fix": "eslint --quiet -c eslint.config.js --fix",
"gql:turbo": "node ./node_modules/gql.tada/bin/cli.js turbo -c ./tsconfig.web.json",
"gql:check": "node ./node_modules/gql.tada/bin/cli.js check -c ./tsconfig.web.json",
"gql:generate": "node --experimental-strip-types ./generateALIntrospection.ts"
},
"devDependencies": {
"@gql.tada/svelte-support": "^1.0.1",
"@sveltejs/adapter-static": "^3.0.9",
"@sveltejs/kit": "^2.37.0",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"@types/debug": "^4.1.12",
"@types/semver": "^7.7.0",
"@urql/introspection": "^1.2.1",
"autoprefixer": "^10.4.21",
"bits-ui": "^0.22.0",
"cmdk-sv": "^0.0.19",
"eslint-config-standard-universal": "^1.0.9",
"gql.tada": "^1.8.13",
"hayase-extensions": "github:hayase-app/extensions",
"jassub": "^1.8.6",
"jiti": "^2.5.1",
"ms": "^2.1.3",
"native": "github:hayase-app/native",
"rollup-plugin-license": "^3.6.0",
"simple-copy": "^2.2.1",
"svelte": "^4.2.19",
"svelte-check": "^4.3.1",
"svelte-radix": "^1.1.1",
"svelte-sonner": "^0.3.28",
"tailwindcss": "^3.4.17",
"typescript": "^5.9.2",
"vaul-svelte": "^0.3.2",
"vite": "^5.4.11",
"vite-plugin-devtools-json": "^1.0.0",
"vite-plugin-static-copy": "^3.1.2"
},
"type": "module",
"dependencies": {
"@cloudflare/speedtest": "^1.6.0",
"@dagrejs/dagre": "^1.1.5",
"@fontsource-variable/nunito": "^5.2.6",
"@fontsource/geist-mono": "^5.2.6",
"@prgm/sveltekit-progress-bar": "2.0.0",
"@thaunknown/web-irc": "^1.0.3",
"@urql/core": "^6.0.1",
"@urql/exchange-auth": "^3.0.0",
"@urql/exchange-graphcache": "^8.1.0",
"@urql/exchange-refocus": "^2.0.0",
"@urql/exchange-request-policy": "^2.0.0",
"@urql/exchange-retry": "^2.0.0",
"@urql/svelte": "^5.0.0",
"@xyflow/svelte": "^0.1.36",
"abslink": "^1.1.2",
"anitomyscript": "github:thaunknown/anitomyscript",
"bittorrent-tracker": "10.0.12",
"bottleneck": "^2.19.5",
"clsx": "^2.1.1",
"cobe": "0.6.3",
"date-fns": "^4.1.0",
"debug": "^4.4.1",
"doc999tor-fast-geoip": "^1.1.360",
"dompurify": "^3.2.6",
"events": "^3.3.0",
"idb-keyval": "^6.2.2",
"js-levenshtein": "^1.1.6",
"lucide-svelte": "^0.542.0",
"marked": "^16.2.1",
"overtype": "^1.2.3",
"p2pt": "github:ThaUnknown/p2pt#modernise",
"semver": "^7.7.2",
"simple-store-svelte": "^1.0.6",
"svelte-headless-table": "^0.18.3",
"svelte-keybinds": "^1.0.9",
"svelte-persisted-store": "^0.12.0",
"tailwind-merge": "^3.3.1",
"tailwind-variants": "^1.0.0",
"uint8-util": "^2.2.5",
"urql": "^5.0.1",
"video-deband": "^1.0.9",
"wonka": "^6.3.5",
"workbox-core": "^7.3.0",
"workbox-precaching": "^7.3.0",
"workbox-routing": "^7.3.0",
"workbox-strategies": "^7.3.0"
}
}

5835
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load diff

6
postcss.config.js Normal file
View file

@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
}

496
src/app.css Normal file
View file

@ -0,0 +1,496 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
color-scheme: only dark;
}
@layer base {
/* miniplayer thing, required to work with :hover */
.paused-show {
--padding-right: unset !important;
--padding-left: unset !important;
}
.custom-draggable {
-webkit-app-region: drag;
}
.custom-not-draggable {
-webkit-app-region: no-drag;
}
.font-mono {
font-family: "Geist Mono", ui-monospace, SFMono-Regular, Roboto Mono, Menlo, Monaco, Liberation Mono, DejaVu Sans Mono, Courier New, monospace !important;
}
.exclude-transition {
view-transition-class: disabled;
}
::view-transition-group(.disabled) {
animation-duration: 0s !important;
}
@supports not (overflow: clip) {
.overflow-clip {
overflow: hidden;
}
.overflow-x-clip {
overflow-x: hidden;
}
.overflow-y-clip {
overflow-y: hidden;
}
}
.text-contrast {
--accessible-color: calc(((((var(--red) * 299) + (var(--green) * 587) + (var(--blue) * 114)) / 1000) - 128) * -1000);
color: rgb(var(--accessible-color),
var(--accessible-color),
var(--accessible-color));
fill: rgb(var(--accessible-color),
var(--accessible-color),
var(--accessible-color));
}
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 72.2% 50.6%;
--destructive-foreground: 0 0% 98%;
--ring: 240 10% 3.9%;
--radius: 0.5rem;
--custom: #fff;
}
html.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--ring: 240 4.9% 83.9%;
--custom: #fff;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
/* @font-face {
font-family: 'molotregular';
src: url('/Molot-webfont-subset.woff') format('woff');
} */
@font-face {
font-family: "Twemoji";
src: url("/twemoji-subset.woff2") format("woff2");
}
html,
body {
height: 100vh !important;
width: 100%;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
scroll-behavior: smooth;
overscroll-behavior: none;
user-select: none;
font-family: 'Nunito Variable'
}
img,
a {
-webkit-user-drag: none;
}
#episodeListTarget:fullscreen {
user-select: none;
}
@keyframes load-in {
from {
transform: translate3d(0, 1.2rem, 0) scale(0.95);
}
to {
transform: none
}
}
@keyframes hearbeat {
from {
transform: translate3d(var(--tw-translate-x), var(--tw-translate-y), 0) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(1) scaleY(1);
}
to {
transform: translate3d(var(--tw-translate-x), var(--tw-translate-y), 0) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(0.85) scaleY(0.85);
}
}
.custom-bg {
/* this is very hacky, but removes jagged edges */
background: repeating-linear-gradient(40deg, #1114 0, #5554 1px, #5554 5px, #1114 6px, #1114 10px);
/* repeating-linear-gradient(40deg, #5554 0 5px, #1114 0 10px); */
}
*:focus-visible {
outline: none;
border-image: fill 0 linear-gradient(#8885, #8885);
}
*::-webkit-scrollbar {
display: none;
}
.details span+span::before {
content: '•';
padding: 0 .3rem;
font-size: .4rem;
align-self: center;
white-space: normal;
color: #737373 !important;
}
a[href],
button,
fieldset,
input,
optgroup,
option,
select,
textarea,
details,
[tabindex],
[contenteditable] {
&:active:not([disabled], [type='range'], .no-scale, [tabindex="-1"]) {
transition: all 0.1s ease-in-out;
transform: scale(0.98);
}
}
.scale-parent:has(.no-scale:active) {
transition: all 0.1s ease-in-out;
transform: scale(0.98);
}
.overflow-y-scroll,
.overflow-y-auto,
.overflow-x-scroll,
.overflow-x-auto,
.overflow-auto,
.overflow-scroll {
will-change: scroll-position;
}
.bg-url {
background-image: var(--bg);
}
.sr-only {
display: none !important;
}
.flex-center {
display: flex;
justify-content: center;
align-items: center;
}
.text-contrast-filter {
filter: invert(1) grayscale(1) brightness(1.2) contrast(9000);
mix-blend-mode: luminosity;
-webkit-font-smoothing: antialiased;
background-color: inherit;
background-clip: text;
color: transparent
}
.svelte-keybinds {
background: black !important;
}
.svelte-progress-bar {
height: 2px !important;
}
.svelte-progress-bar-leader {
height: 4px !important;
}
/* animated SVG icons */
.animated-icon:not(:hover):not(:focus-visible):not(:active) .target-animated-icon {
animation: none !important;
transform: translateX(0) translateX(0) translateZ(0) translate(0, 0) !important;
}
/* Backplate related things */
body {
perspective: 3000px;
}
#root:has(+ .backplate-spin) {
animation: idle-spin 120s linear infinite;
}
.backplate-spin {
animation: idle-spin-y-flip 120s linear infinite;
}
#root:has(+ .backplate-fly) {
animation: idle-fly 0.8s forwards cubic-bezier(0.22, 1, 0.36, 1);
}
#root {
transition: transform 0.5s;
transform: perspective(100vw) translate3d(0, 0, 0vw) rotateY(0deg) rotateX(0deg);
}
::view-transition-old(my-root),
::view-transition-new(my-root) {
animation-duration: 200ms;
animation-timing-function: ease-in-out;
}
::view-transition-old(my-root) {
animation-name: fade-out;
}
::view-transition-new(my-root) {
animation-name: fade-in;
}
@media (prefers-reduced-motion) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
/* @media (max-width: 768px) {
::view-transition-old(*),
::view-transition-new(*) {
animation-duration: 600ms !important;
animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1) !important;
}
::view-transition-old(*) {
animation-name: slide-out-left !important;
}
::view-transition-new(*) {
animation-name: slide-in-right !important;
}
} */
/* @keyframes slide-in-right {
from {
transform: translateX(40%);
}
to {
transform: translateX(0);
}
}
@keyframes slide-out-left {
from {
transform: translateX(0);
}
to {
transform: translateX(-10%);
}
} */
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1
}
}
@keyframes idle-fly {
0% {
transform: perspective(100vw) translate3d(0, 0, 0vw) rotateY(0deg) rotateX(0deg);
}
100% {
transform: perspective(100vw) translate3d(0, 0, -66vw) rotateY(0deg) rotateX(-15deg);
}
}
@keyframes idle-spin {
0% {
transform: perspective(100vw) translate3d(0, 0, -66vw) rotateY(0deg) rotateX(-15deg);
}
50% {
transform: perspective(100vw) translate3d(0, 0, -66vw) rotateY(180deg) rotateX(15deg);
}
100% {
transform: perspective(100vw) translate3d(0, 0, -66vw) rotateY(360deg) rotateX(-15deg);
}
}
@keyframes idle-spin-y-flip {
0% {
transform: perspective(100vw) translate3d(0, 0, -66vw) rotateY(-180deg) rotateX(15deg);
}
50% {
transform: perspective(100vw) translate3d(0, 0, -66vw) rotateY(0deg) rotateX(-15deg);
}
100% {
transform: perspective(100vw) translate3d(0, 0, -66vw) rotateY(180deg) rotateX(15deg);
}
}
@keyframes marquee {
from {
transform: translateX(-30%);
}
to {
transform: translateX(-130%);
}
}
@keyframes bg-grid-animate {
from {
background-position: 0 100%;
}
to {
background-position: 100% 0;
}
}
.animate-marquee {
animation: marquee 80s infinite linear;
}
.bg-striped {
background: repeating-linear-gradient(45deg,
#202020,
#202020 6px,
#2a2a2a 6px,
#2a2a2a 12px);
background-attachment: fixed;
background-size: 119px;
}
.bg-striped-muted {
background: repeating-linear-gradient(45deg,
#1e1e1e,
#1e1e1e 6px,
#161616 6px,
#161616 12px);
background-attachment: fixed;
background-size: 119px;
}
/* .font-molot {
font-family: 'molotregular';
} */
.font-twemoji {
font-family: 'Twemoji';
}
.backface-visible {
backface-visibility: visible;
}
.backface-hidden {
backface-visibility: hidden;
}
.preserve-3d {
transform-style: preserve-3d;
}

55
src/app.d.ts vendored Normal file
View file

@ -0,0 +1,55 @@
// See https://kit.svelte.dev/docs/types#app
import type { Search } from '$lib/modules/anilist/queries'
import type { VariablesOf } from 'gql.tada'
import type { CompositionEventHandler } from 'svelte/elements'
export interface Track {
selected: boolean
enabled: boolean
id: string
kind: string
label: string
language: string
}
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
interface PageState {
search?: VariablesOf<typeof Search>
image?: File | string
}
// interface Platform {}
}
interface HTMLMediaElement {
videoTracks?: Track[]
audioTracks?: Track[]
}
interface ScreenOrientation {
lock: (orientation: 'any' | 'natural' | 'landscape' | 'portrait' | 'portrait-primary' | 'portrait-secondary' | 'landscape-primary' | 'landscape-secondary') => Promise<void>
}
interface Navigator {
userAgentData?: {
getHighEntropyValues?: (keys: string[]) => Promise<Record<string, string>>
}
}
declare namespace svelteHTML {
interface HTMLAttributes<T> {
'on:navigate'?: CompositionEventHandler<T>
}
}
// declare module '*.svelte' {
// export default SvelteComponentTyped
// }
}
export {}

17
src/app.html Normal file
View file

@ -0,0 +1,17 @@
<!doctype html>
<html lang="en" class="dark bg-black" style="color-scheme: dark;">
<head>
<meta charset="utf-8" />
<title>Hayase</title>
<link rel="preconnect" href="https://graphql.anilist.co/">
<link rel="preconnect" href="https://www.youtube-nocookie.com">
<link rel="icon" href="%sveltekit.assets%/logo_white_fit.svg" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="off" class="!bg-black !relative" data-vaul-drawer-wrapper>
%sveltekit.body%
</body>
</html>

View file

@ -1,128 +0,0 @@
const { app, BrowserWindow, protocol } = require('electron')
const path = require('path')
const remote = require('@electron/remote/main')
const log = require('electron-log')
const { autoUpdater } = require('electron-updater')
autoUpdater.logger = log
autoUpdater.logger.transports.file.level = 'info'
remote.initialize()
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function UpsertKeyValue (obj, keyToChange, value) {
const keyToChangeLower = keyToChange.toLowerCase()
for (const key of Object.keys(obj)) {
if (key.toLowerCase() === keyToChangeLower) {
// Reassign old key
obj[key] = value
// Done
return
}
}
// Insert at end instead
obj[keyToChange] = value
}
function createWindow () {
autoUpdater.checkForUpdatesAndNotify()
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1600,
height: 900,
frame: false,
backgroundColor: '#191c20',
autoHideMenuBar: true,
experimentalFeatures: true,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableBlinkFeatures: 'AudioVideoTracks',
enableRemoteModule: true,
backgroundThrottling: false
},
icon: path.join(__dirname, '/renderer/public/logo.ico'),
show: false
})
mainWindow.setMenuBarVisibility(false)
remote.enable(mainWindow.webContents)
protocol.registerHttpProtocol('miru', (req, cb) => {
const token = req.url.slice(7)
if (process.env.NODE_ENV !== 'development ') {
mainWindow.loadURL(path.join(__dirname, '/renderer/dist/index.html' + token))
} else {
mainWindow.loadURL('http://localhost:3000/' + token)
}
})
// mainWindow.removeMenu()
mainWindow.webContents.session.webRequest.onBeforeSendHeaders(
(details, callback) => {
const { requestHeaders } = details
UpsertKeyValue(requestHeaders, 'Access-Control-Allow-Origin', ['*'])
callback({ requestHeaders })
}
)
mainWindow.webContents.session.webRequest.onHeadersReceived((details, callback) => {
const { responseHeaders } = details
UpsertKeyValue(responseHeaders, 'Access-Control-Allow-Origin', ['*'])
UpsertKeyValue(responseHeaders, 'Access-Control-Allow-Headers', ['*'])
callback({ responseHeaders })
})
// This block of code is intended for development purpose only.
// Delete this entire block of code when you are ready to package the application.
if (process.env.NODE_ENV !== 'development ') {
// Load production build
mainWindow.loadFile(path.join(__dirname, '/renderer/dist/index.html'))
} else {
// Load vite dev server page
console.log('Development mode')
mainWindow.loadURL('http://localhost:3000/')
mainWindow.webContents.openDevTools()
}
// Uncomment the following line of code when app is ready to be packaged.
// loadURL(mainWindow);
// Open the DevTools and also disable Electron Security Warning.
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = true
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
// Emitted when the window is ready to be shown
// This helps in showing the window gracefully.
mainWindow.once('ready-to-show', () => {
mainWindow.show()
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) createWindow()
})

View file

@ -0,0 +1,92 @@
<script lang='ts'>
import { activityState, idleState, isPlaying, lockedState } from '$lib/modules/idle'
import { settings } from '$lib/modules/settings'
import { sleep } from '$lib/utils'
let plate: HTMLDivElement
export let root: HTMLDivElement
let visibilityState: DocumentVisibilityState
let isAnimating = false
let isSpinning = false
let isFlying = false
let showBackplate = false
let timeout: number
// WE LOVE RACE CONDITIONS WOOOO YEAAH MY SANITY
async function start () {
if (isAnimating) return
isAnimating = true
isFlying = true
await sleep(800)
if (!isFlying) return
showBackplate = true
isSpinning = true
isFlying = false
}
async function reset () {
if (!isAnimating) return
root.style.transform = getComputedStyle(root).transform
plate.style.transform = getComputedStyle(plate).transform
isSpinning = isFlying = false
await sleep(10)
root.style.transform = plate.style.transform = ''
await sleep(490)
isAnimating = showBackplate = isSpinning = isFlying = false
}
$: active = $lockedState === 'locked' || visibilityState === 'hidden' || ($idleState === 'active' && $activityState === 'active') || $isPlaying
function checkIdleState (active: boolean, idleAnimation: boolean) {
clearTimeout(timeout)
if (!idleAnimation || active) return reset()
timeout = setTimeout(start, 120_000)
}
$: checkIdleState(active, $settings.idleAnimation)
// MOLOT font was commented out in app.css since this feature was shelved
</script>
<svelte:document bind:visibilityState />
<div class='preserve-3d absolute w-full h-full overflow-clip flip backface-hidden backplate bg-black flex-col justify-center pointer-events-none hidden'
bind:this={plate}
class:!flex={showBackplate}
class:backplate-fly={isFlying}
class:backplate-spin={isSpinning}>
{#each Array.from({ length: 6 }) as _, i (i)}
<div class='flex flex-row w-full font-molot font-bold leading-[0.8] ml-[--ml-offset] -rotate-12 text-white mt-64' style:--ml-offset='calc((-1 * {(i) * 600}px) - 10vw)'>
{#each Array.from({ length: 4 }) as _, i (i)}
<div>
<div class='bg-striped'>
<div class='text-[24rem] tracking-wide animate-marquee bg-black mix-blend-multiply'>
HAYASE.06&nbsp;
</div>
</div>
<div class='bg-striped-muted'>
<div class='flex pl-1 animate-marquee bg-black mix-blend-multiply'>
<div class='rounded py-2 px-3 mt-1 mb-[2.5px] mr-2 ml-1 text-black bg-white flex items-center leading-[0.9]'>
TORRENTING<br />MADE<br />SIMPLE
</div>
<div class='text-[5.44rem] bg-striped-muted tracking-wider'>
MAGNET://SIMPLICITY TOPS EVERYTHING
</div>
</div>
</div>
</div>
{/each}
</div>
{/each}
</div>
<style>
.backplate {
transition: transform 0.5s;
transform: perspective(100vw) translate3d(0, 0, 0vw) rotateY(180deg) rotateX(0deg);
}
</style>

View file

@ -0,0 +1,111 @@
<script lang='ts'>
import { PencilLine } from './icons/animated'
import { Button } from '$lib/components/ui/button'
import * as Dialog from '$lib/components/ui/dialog'
import { Input } from '$lib/components/ui/input'
import * as Select from '$lib/components/ui/select'
import { banner, cover, title, type Media } from '$lib/modules/anilist'
import { list, progress as _progress, score as _score, repeat as _repeat, authAggregator, lists } from '$lib/modules/auth'
import { dragScroll } from '$lib/modules/navigate'
import { breakpoints } from '$lib/utils'
export let media: Media
const STATUS_LABELS = {
CURRENT: 'Watching',
PLANNING: 'Plan to Watch',
COMPLETED: 'Completed',
PAUSED: 'Paused',
DROPPED: 'Dropped',
REPEATING: 'Re-Watching'
}
let status = { value: list(media) ?? 'CURRENT', label: STATUS_LABELS[list(media) ?? 'CURRENT'] }
let score = { value: Number(_score(media) ?? 0), label: '' + (_score(media) ?? 0) }
let progress = _progress(media) ?? 0
let repeat = _repeat(media) ?? 0
function deleteEntry () {
authAggregator.delete(media)
}
function saveEntry () {
authAggregator.entry({ id: media.id, score: Number(score.value) * 10, repeat: Number(repeat), progress: Number(progress), status: status.value, lists: lists(media)?.filter(({ enabled }) => enabled).map(({ name }) => name) })
}
</script>
<Dialog.Root portal='#root'>
<Dialog.Trigger let:builder asChild>
<Button size='icon' class='rounded-l-none bg-custom-400 select:!bg-custom-700 shrink-0 text-contrast animated-icon' builders={[builder]}>
<PencilLine class='size-4' />
</Button>
</Dialog.Trigger>
<Dialog.Content class='flex justify-center max-h-[80%] max-w-3xl p-0'>
<div class='flex flex-col sm:flex-row w-full overflow-y-auto' use:dragScroll>
<div class='relative w-full h-[150px] sm:w-[260px] sm:h-[400px] shrink-0'>
<img alt='images' loading='lazy' decoding='async' class='object-cover w-full h-full sm:rounded-l-lg overflow-clip' style:background={media.coverImage?.color ?? '#000'} src={$breakpoints.sm ? cover(media) : banner(media)} />
</div>
<form class='flex flex-col w-full rounded-r-lg h-full'>
<div class='pt-4 px-5 w-full'>
<h3 class='text-xl leading-6 font-semibold z-30 text-white sm:line-clamp-1 line-clamp-2'>{title(media)}</h3>
</div>
<div class='px-5 py-3 grid grid-cols-1 sm:grid-cols-2 gap-5 w-full'>
<div class='mt-1 flex flex-col'>
<div class='font-bold text-muted-foreground text-sm mb-2'>Status</div>
<Select.Root bind:selected={status}>
<Select.Trigger>
<Select.Value placeholder='Status' />
</Select.Trigger>
<Select.Content sameWidth={true}>
<Select.Item value='CURRENT'>Watching</Select.Item>
<Select.Item value='PLANNING'>Plan to Watch</Select.Item>
<Select.Item value='COMPLETED'>Completed</Select.Item>
<Select.Item value='PAUSED'>Paused</Select.Item>
<Select.Item value='DROPPED'>Dropped</Select.Item>
<Select.Item value='REPEATING'>Re-Watching</Select.Item>
</Select.Content>
</Select.Root>
</div>
<div class='mt-1 flex flex-col'>
<div class='font-bold text-muted-foreground text-sm mb-2'>Score</div>
<Select.Root bind:selected={score}>
<Select.Trigger>
<Select.Value placeholder='Score' />
</Select.Trigger>
<Select.Content sameWidth={true}>
<Select.Item value='0' />
<Select.Item value='1' />
<Select.Item value='2' />
<Select.Item value='3' />
<Select.Item value='4' />
<Select.Item value='5' />
<Select.Item value='6' />
<Select.Item value='7' />
<Select.Item value='8' />
<Select.Item value='9' />
<Select.Item value='10' />
</Select.Content>
</Select.Root>
</div>
<div class='mt-1 flex flex-col'>
<div class='font-bold text-muted-foreground text-sm mb-2'>Progress</div>
<Input type='number' inputmode='numeric' pattern='[0-9]*.?[0-9]*' min='0' max='Infinity' bind:value={progress} />
</div>
<div class='mt-1 flex flex-col'>
<div class='font-bold text-muted-foreground text-sm mb-2'>Rewatched Times</div>
<Input type='number' inputmode='numeric' pattern='[0-9]*.?[0-9]*' min='0' max='Infinity' bind:value={repeat} />
</div>
</div>
<div class='px-4 py-3 gap-3 mt-auto flex flex-col sm:flex-row-reverse sm:px-6'>
<Dialog.Close let:builder asChild>
<Button on:click={saveEntry} builders={[builder]}>Save Changes</Button>
<Button variant='secondary' builders={[builder]}>Cancel</Button>
<Button variant='destructive' on:click={deleteEntry} builders={[builder]}>Delete</Button>
</Dialog.Close>
</div>
</form>
</div>
</Dialog.Content>
</Dialog.Root>

View file

@ -0,0 +1,140 @@
<script lang='ts'>
import Play from 'lucide-svelte/icons/play'
import Pagination from './Pagination.svelte'
import { ChevronLeft, ChevronRight } from './icons/animated'
import { Button } from './ui/button'
import { Load } from './ui/img'
import { playEp } from './ui/player/mediahandler.svelte'
import { Profile } from './ui/profile'
import type { EpisodesResponse } from '$lib/modules/anizip/types'
import { episodes as _episodes, notes, type Media } from '$lib/modules/anilist'
import { authAggregator, list, progress } from '$lib/modules/auth'
import { makeEpisodeList } from '$lib/modules/extensions'
import { click, dragScroll } from '$lib/modules/navigate'
import { liveAnimeProgress } from '$lib/modules/watchProgress'
import { breakpoints, cn, since } from '$lib/utils'
export let eps: EpisodesResponse | null
export let media: Media
$: episodeCount = _episodes(media) ?? eps?.episodeCount ?? 0
$: episodeList = media && makeEpisodeList(media, eps)
const perPage = 16
function getPage (page: number, list = episodeList) {
return list.slice((page - 1) * perPage, page * perPage)
}
$: completed = list(media) === 'COMPLETED'
$: _progress = completed ? 0 : progress(media) ?? 0
$: currentPage = Math.floor((!completed ? _progress : 0) / perPage) + 1
function play (episode: number) {
$playEp(media, episode)
}
export let following = authAggregator.following(media.id)
$: followerEntries = $following?.data?.Page?.mediaList?.filter(e => e?.user?.id !== authAggregator.id()) ?? []
$: watchProgress = liveAnimeProgress(media.id)
</script>
<Pagination count={episodeCount} {perPage} bind:currentPage let:pages let:hasNext let:hasPrev let:range let:setPage siblingCount={1}>
<div class='overflow-y-auto pt-3 -ml-14 pl-14 -mr-3 pr-3 pointer-events-none -mb-3 pb-3' use:dragScroll>
<div class='grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,minmax(500px,1fr))] place-items-center gap-x-4 gap-y-7 justify-center align-middle pointer-events-auto'>
{#each getPage(currentPage, episodeList) as { episode, image, title, summary, airingAt, airdate, filler, length } (episode)}
{@const watched = _progress >= episode && !completed}
{@const target = _progress + 1 === episode}
<div class={!target ? 'px-3 w-full' : 'contents'}>
<div use:click={() => play(episode)}
class={cn(
'select:scale-[1.05] select:shadow-lg scale-100 transition-[transform,box-shadow] duration-200 shrink-0 ease-out focus-visible:ring-ring focus-visible:ring-1 rounded-md bg-neutral-950 text-secondary-foreground select:bg-neutral-900 flex w-full max-h-28 cursor-pointer relative overflow-hidden group',
target && 'ring-custom ring-1',
filler && '!ring-yellow-400 ring-1'
)}>
{#if image}
<div class='w-52 shrink-0 relative'>
<Load src={image} class={cn('object-cover h-full w-full', watched && 'opacity-20')} />
{#if length ?? media.duration}
<div class='absolute bottom-1 left-1 bg-neutral-900/80 text-secondary-foreground text-[9.6px] px-1 py-0.5 rounded'>
{length ?? media.duration}m
</div>
{/if}
<div class='absolute flex items-center justify-center w-full h-full bg-black group-select:bg-opacity-50 bg-opacity-0 duration-200 text-white transition-[background] ease-out top-0'>
<Play class='size-6 scale-75 opacity-0 group-select:opacity-100 group-select:scale-100 duration-200 transition-[transform,opacity] ease-out' fill='currentColor' />
</div>
</div>
{/if}
<div class='flex-grow py-3 px-4 flex flex-col'>
<div class='font-bold mb-2 line-clamp-1 shrink-0 text-[12.8px]'>
{episode}. {title?.en ?? 'Episode ' + episode}
</div>
{#if watched || completed}
<div class='mb-2 h-0.5 overflow-hidden w-full bg-custom shrink-0' />
{:else if $watchProgress?.episode === episode}
<div class='w-full bg-neutral-800 mb-2'>
<div class='h-0.5 overflow-hidden bg-custom shrink-0' style:width={$watchProgress.progress + '%'} />
</div>
{/if}
<div class='text-[9.6px] text-muted-foreground overflow-hidden'>
{notes(summary ?? '')}
</div>
<div class='flex w-full justify-between mt-auto'>
{#if airingAt ?? airdate}
<div class='text-[9.6px] pt-2'>
{since(new Date(airingAt ?? airdate ?? 0))}
</div>
{/if}
<div class='-space-x-1 ml-auto inline-flex pt-1 pr-0.5'>
{#each followerEntries.filter(e => e?.progress === episode) as followerEntry, i (followerEntry?.user?.id ?? i)}
{#if followerEntry?.user}
<Profile user={followerEntry.user} class='ring-2 ring-neutral-950 size-4 bg-neutral-950' />
{/if}
{/each}
</div>
</div>
{#if filler}
<div class='rounded-tl bg-yellow-400 py-1 px-2 text-primary-foreground absolute bottom-0 right-0 text-[9.6px] font-bold'>Filler</div>
{/if}
</div>
</div>
</div>
{/each}
</div>
</div>
<div class='flex flex-row items-center justify-between w-full py-3'>
<p class='text-center text-[13px] text-muted-foreground hidden md:block'>
Showing <span class='font-bold'>{range.start + 1}</span> to <span class='font-bold'>{range.end}</span> of <span class='font-bold'>{episodeCount}</span> episodes
</p>
<div class='w-full md:w-auto gap-2 flex items-center'>
<Button size='icon' variant='ghost' class='animated-icon' on:click={() => setPage(currentPage - 1)} disabled={!hasPrev}>
<ChevronLeft class='size-4' />
</Button>
{#if $breakpoints.md}
{#each pages as { page, type } (page)}
{#if type === 'ellipsis'}
<span class='h-9 w-9 text-center'>...</span>
{:else}
<Button size='icon' variant={page === currentPage ? 'outline' : 'ghost'} on:click={() => setPage(page)}>
{page}
</Button>
{/if}
{/each}
{:else}
<p class='text-center text-[13px] text-muted-foreground w-full block md:hidden'>
Showing <span class='font-bold'>{range.start + 1}</span> to <span class='font-bold'>{range.end}</span> of <span class='font-bold'>{episodeCount}</span> episodes
</p>
{/if}
<Button size='icon' variant='ghost' class='animated-icon' on:click={() => setPage(currentPage + 1)} disabled={!hasNext}>
<ChevronRight class='size-4' />
</Button>
</div>
</div>
</Pagination>

View file

@ -0,0 +1,38 @@
<script lang='ts' context='module'>
import type { ComponentType, SvelteComponent } from 'svelte'
const keep = new Map<string, { component: SvelteComponent, node: HTMLElement}>()
export function register (id: string, Component: ComponentType) {
if (keep.has(id)) throw new Error(`KeepAlive: duplicate id ${id}`)
const wrapper = document.createDocumentFragment() as unknown as HTMLElement
const instance = new Component({ target: wrapper })
keep.set(id, { component: instance, node: wrapper.children[0] as HTMLElement })
}
export function unregister (id: string) {
const entry = keep.get(id)
if (entry) {
entry.component.$destroy()
entry.node.remove()
keep.delete(id)
}
}
</script>
<script lang='ts'>
import type { HTMLAttributes } from 'svelte/elements'
export let id: string
type $$Props = HTMLAttributes<HTMLDivElement> & { id: string }
function mount (node: HTMLDivElement) {
const entry = keep.get(id)
if (entry) node.appendChild(entry.node)
}
</script>
<div use:mount {...$$restProps} />

View file

@ -0,0 +1,53 @@
<script lang='ts'>
import CloudOff from 'lucide-svelte/icons/cloud-off'
import online from '$lib/modules/online'
let hideFirst = false
$: if (!$online && !hideFirst) {
hideFirst = true
}
</script>
{#if $online && hideFirst}
<div class='bg-green-600 text-white justify-center items-center flex flex-row online overflow-hidden relative z-40 px-4 shrink-0'>
Back online
</div>
{:else if !$online}
<div class='bg-neutral-950 text-white justify-center items-center flex flex-row top-0 offline overflow-hidden relative z-40 px-4 shrink-0'>
<CloudOff size={16} class='me-2' />
Offline
</div>
{/if}
<style>
.online {
animation: hide 300ms forwards 2s;
}
@keyframes hide {
from {
height: 24px;
}
to {
height: 0;
padding-top: 0;
padding-bottom: 0;
}
}
.offline {
height: 0;
padding-top: 0;
padding-bottom: 0;
animation: show 300ms forwards 2s;
}
@keyframes show {
from {
height: 0;
}
to {
height: 24px;
padding-top: 2px;
padding-bottom: 2px;
}
}
</style>

View file

@ -0,0 +1,53 @@
<script lang='ts'>
export let currentPage = 1
export let count = 0
export let perPage = 15
export let siblingCount = 1
let pages: Array<{
page: number
type: string
}> = []
$: {
const edgeSize = 4 * siblingCount
const totalPages = Math.ceil(count / perPage)
const startPage = Math.max(1, totalPages - currentPage < edgeSize ? totalPages - edgeSize : currentPage - siblingCount)
const endPage = Math.min(totalPages, currentPage < edgeSize ? 1 + edgeSize : currentPage + siblingCount)
const paginationItems = []
if (startPage > 1) {
paginationItems.push({ page: 1, type: 'page' })
if (startPage > 2) {
paginationItems.push({ page: startPage - 1, type: 'ellipsis' })
}
}
for (let i = startPage; i <= endPage; i++) {
paginationItems.push({ page: i, type: 'page' })
}
if (endPage < totalPages) {
if (endPage < totalPages - 1) {
paginationItems.push({ page: endPage + 1, type: 'ellipsis' })
}
paginationItems.push({ page: totalPages, type: 'page' })
}
pages = paginationItems
}
$: range = {
start: (currentPage - 1) * perPage,
end: Math.min(currentPage * perPage, count)
}
$: hasNext = currentPage < Math.ceil(count / perPage)
$: hasPrev = currentPage > 1
function setPage (page: number) {
currentPage = Math.min(Math.max(1, page), Math.ceil(count / perPage))
}
</script>
<slot {pages} {range} {hasNext} {hasPrev} {setPage} />

View file

@ -0,0 +1,335 @@
<script lang='ts' context='module'>
import BadgeCheck from 'lucide-svelte/icons/badge-check'
import Download from 'svelte-radix/Download.svelte'
import File from 'svelte-radix/File.svelte'
import MagnifyingGlass from 'svelte-radix/MagnifyingGlass.svelte'
import { SingleCombo } from './ui/combobox'
import { Input } from './ui/input'
import type { AnitomyResult } from 'anitomyscript'
import type { TorrentResult } from 'hayase-extensions'
import * as Dialog from '$lib/components/ui/dialog'
import { title } from '$lib/modules/anilist'
import { extensions } from '$lib/modules/extensions/extensions'
import { click, dragScroll } from '$lib/modules/navigate'
import { settings, videoResolutions } from '$lib/modules/settings'
import { cn, colors, fastPrettyBytes, since } from '$lib/utils'
const termMapping: Record<string, {text: string, color: string}> = {}
termMapping['5.1'] = termMapping['5.1CH'] = { text: '5.1', color: '#f67255' }
termMapping['TRUEHD5.1'] = { text: 'TrueHD 5.1', color: '#f67255' }
termMapping.AAC = termMapping.AACX2 = termMapping.AACX3 = termMapping.AACX4 = { text: 'AAC', color: '#f67255' }
termMapping.AC3 = { text: 'AC3', color: '#f67255' }
termMapping.EAC3 = termMapping['E-AC-3'] = { text: 'EAC3', color: '#f67255' }
termMapping.FLAC = termMapping.FLACX2 = termMapping.FLACX3 = termMapping.FLACX4 = { text: 'FLAC', color: '#f67255' }
termMapping.VORBIS = { text: 'Vorbis', color: '#f67255' }
termMapping.DUALAUDIO = termMapping['DUAL AUDIO'] = { text: 'Dual Audio', color: '#ffcb3b' }
termMapping['10BIT'] = termMapping['10BITS'] = termMapping['10-BIT'] = termMapping['10-BITS'] = termMapping.HI10 = termMapping.HI10P = { text: '10 Bit', color: '#0c8ce9' }
termMapping.HI444 = termMapping.HI444P = termMapping.HI444PP = { text: 'HI444', color: '#0c8ce9' }
termMapping.HEVC = termMapping.H265 = termMapping['H.265'] = termMapping.X265 = { text: 'HEVC', color: '#0c8ce9' }
termMapping.AV1 = { text: 'AV1', color: '#0c8ce9' }
termMapping.BD = termMapping.BDRIP = termMapping.BLURAY = termMapping['BLU-RAY'] = { text: 'BD', color: '#ab1b31' }
termMapping.DVD5 = termMapping.DVD9 = termMapping['DVD-R2J'] = termMapping.DVDRIP = termMapping.DVD = termMapping['DVD-RIP'] = termMapping.R2DVD = termMapping.R2J = termMapping.R2JDVD = termMapping.R2JDVDRIP = { text: 'DVD', color: '#ab1b31' }
termMapping.MULTISUB = termMapping['MULTI-SUB'] = termMapping['MULTI SUB'] = termMapping.MULTISUBS = termMapping['MULTI-SUBS'] = termMapping['MULTI SUBS'] = { text: 'Multi Sub', color: '#ffcb3b' }
// termMapping.HDTV = termMapping.HDTVRIP = termMapping.TVRIP = termMapping['TV-RIP'] = { text: 'TV', color: '#ab1b31' }
// termMapping.WEBCAST = termMapping.WEBRIP = { text: 'WEB', color: '#ab1b31' }
function sanitiseTerms ({ video_term: video, audio_term: audio, video_resolution: resolution, source, subtitles }: AnitomyResult) {
const terms = [...new Set([...video ?? [], ...audio ?? [], ...source ?? [], ...subtitles ?? []].map(term => termMapping[term.toUpperCase() ?? '']).filter(t => t))] as Array<{text: string, color: string}>
if (resolution.length) terms.unshift({ text: resolution[0]!, color: '#c6ec58' })
return terms
}
function simplifyFilename ({ video_term: video, audio_term: audio, video_resolution: resolution, file_name: name, release_group: group, file_checksum: checksum }: AnitomyResult) {
let simpleName = name[0]!
if (group.length) simpleName = simpleName.replace(group[0]!, '')
if (resolution.length) simpleName = simpleName.replace(resolution[0]!, '')
if (checksum.length) simpleName = simpleName.replace(checksum[0]!, '')
for (const term of video ?? []) simpleName = simpleName.replace(term, '')
for (const term of audio ?? []) simpleName = simpleName.replace(term, '')
return simpleName.replace(/[[{(]\s*[\]})]/g, '').replace(/\s+/g, ' ').trim()
}
function getGroup ({ release_group: group, file_name: name }: AnitomyResult) {
return group[0] && group[0].length < 20 ? group[0] : /^(?!\[[^\]]*\]).*-(\w+)(?=\s\(|\.\w+$|$)/.exec(name[0] ?? '')?.[1] ?? 'No Group'
}
</script>
<script lang='ts'>
import Folder from 'lucide-svelte/icons/folder'
import { getContext } from 'svelte'
import ProgressButton from './ui/button/progress-button.svelte'
import { Banner } from './ui/img'
import { beforeNavigate, goto } from '$app/navigation'
import { searchStore } from '$lib'
import { saved } from '$lib/modules/extensions'
import { server } from '$lib/modules/torrent'
$: open = !!$searchStore?.media
$: searchResult = !!$searchStore?.media && extensions.getResultsFromExtensions({ media: $searchStore.media, episode: $searchStore.episode, resolution: $settings.searchQuality })
function close (state = false) {
if (!state) {
searchStore.set(undefined)
open = false
inputText = ''
}
}
let inputText = ''
function play (result: Pick<TorrentResult, 'hash'>) {
server.play(result.hash, $searchStore!.media, $searchStore!.episode)
goto('/app/player/')
close()
}
async function playBest () {
if (!searchResult) return
const best = filterAndSortResults((await searchResult).results, inputText, await $downloaded)[0]
if (best) play(best)
}
function filterAndSortResults (results: Array<TorrentResult & { parseObject: AnitomyResult, extension: Set<string> }>, searchText: string, downloaded: Set<string>) {
const preference = $settings.lookupPreference
return results
.filter(({ title }) => title.toLowerCase().includes(searchText.toLowerCase()))
.sort((a, b) => {
// pre-emtively sort by deal breaker conditions
// the higher the rank the worse the result... don't ask
function getRank (res: typeof results[0]) {
if (res.accuracy === 'low') return 3
if (downloaded.has(res.hash)) return 0
if (res.seeders <= 15) return 2
if ((res.type === 'best' || res.type === 'alt') && preference === 'quality') return 0
return 1
}
const rankA = getRank(a)
const rankB = getRank(b)
if (rankA !== rankB) return rankA - rankB
if (rankA === 1) {
const scoreA = a.accuracy === 'high' ? 1 : 0
const scoreB = b.accuracy === 'high' ? 1 : 0
const diff = scoreB - scoreA
if (diff !== 0) return diff
// sort by preference, quality is sorted in rank, so quality and seeders is both as seeders here.
if (preference === 'size') return a.size - b.size
return b.seeders - a.seeders
}
return 0
})
}
let animating = false
async function startAnimation (searchRes: typeof searchResult) {
if (!$settings.searchAutoSelect) return
animating = false
const results = await searchRes
if (searchRes === searchResult && results && results.results.length) animating = true
}
function stopAnimation () {
animating = false
}
const torrentRx = /(^magnet:){1}|(^[A-F\d]{8,40}$){1}|(.*\.torrent$){1}/i
function findTorrentIdentifiers (hash: string) {
if (torrentRx.test(hash)) {
play({ hash })
}
}
$: findTorrentIdentifiers(inputText)
$: searchResult && startAnimation(searchResult)
const downloaded = server.downloaded
const stop = getContext<() => void>('stop-progress-bar')
beforeNavigate(({ cancel }) => {
if (open) {
cancel()
close()
stop()
}
})
$: ({ r, g, b } = colors($searchStore?.media.coverImage?.color ?? undefined))
</script>
<Dialog.Root bind:open onOpenChange={close} portal='#episodeListTarget'>
<Dialog.Content class='bg-black h-full max-w-5xl w-full max-h-[calc(100%-1rem)] border-b-0 !rounded-b-none mt-2 p-0 items-center flex-col flex lg:rounded-t-xl overflow-clip z-[100] gap-0'>
<!-- this hacky thing is required for dialog root focus trap... pitiful -->
<div class='size-0' tabindex='0' />
{#if $searchStore}
<div class='absolute top-0 left-0 w-full h-full max-h-36 overflow-hidden flex items-end'>
<Banner media={$searchStore.media} class='object-cover w-full h-full absolute bottom-[0.5px] left-0 -z-10 opacity-40' />
<div class='w-full h-[70%] bg-gradient-to-t from-black/80 to-transparent' />
</div>
<div class='gap-4 w-full relative h-full flex flex-col pt-8' style:--custom={$searchStore.media.coverImage?.color ?? '#fff'} style:--red={r} style:--green={g} style:--blue={b}>
<div class='px-4 sm:px-6 space-y-4'>
<div class='font-weight-bold text-2xl font-bold text-ellipsis text-nowrap overflow-hidden'>{title($searchStore.media)}</div>
<div class='flex items-center relative scale-parent'>
<Input
class='pl-9 bg-background select:bg-accent select:text-accent-foreground shadow-sm no-scale placeholder:opacity-50'
placeholder='Filter by text, or paste a magnet link or torrent file here to specify a torrent manually'
bind:value={inputText} />
<MagnifyingGlass class='h-4 w-4 shrink-0 opacity-50 absolute left-3 text-muted-foreground z-10 pointer-events-none' />
</div>
<div class='flex items-center gap-4 justify-around flex-wrap'>
<div class='flex items-center space-x-2 grow'>
<span>Episode</span>
<Input type='number' inputmode='numeric' pattern='[0-9]*' min='0' max='65536' bind:value={$searchStore.episode} class='w-32 shrink-0 bg-background grow' />
</div>
<div class='flex items-center space-x-2 grow'>
<span>Resolution</span>
<SingleCombo bind:value={$settings.searchQuality} items={videoResolutions} portal='#episodeListTarget' class='w-32 shrink-0 grow border-border border' />
</div>
</div>
<ProgressButton
onclick={playBest}
size='default'
class='w-full font-bold bg-custom select:bg-custom-600 text-contrast'
bind:animating>
Auto Select Torrent
</ProgressButton>
</div>
<div class='h-full overflow-y-auto px-4 sm:px-6 pt-2' role='menu' tabindex='-1' on:keydown={stopAnimation} on:focusin={stopAnimation} on:pointerenter={stopAnimation} on:pointermove={stopAnimation} use:dragScroll style:--custom={$searchStore.media.coverImage?.color ?? '#fff'} style:--red={r} style:--green={g} style:--blue={b}>
{#await Promise.all([searchResult, $downloaded])}
{#each Array.from({ length: 12 }) as _, i (i)}
<div class='p-3 h-[106px] flex cursor-pointer mb-2 relative rounded-md overflow-hidden bg-neutral-950 flex-col justify-between [content-visibility:auto] [contain-intrinsic-height:auto_106px]'>
<div class='h-4 w-40 bg-primary/5 animate-pulse rounded mt-2' />
<div class='bg-primary/5 animate-pulse rounded h-2 w-28 mt-1' />
<div class='flex justify-between mb-1'>
<div class='flex gap-2'>
<div class='mt-2 bg-primary/5 animate-pulse rounded h-2 w-20' />
<div class='mt-2 bg-primary/5 animate-pulse rounded h-2 w-20' />
</div>
<div class='mt-2 bg-primary/5 animate-pulse rounded h-2 w-20' />
</div>
</div>
{/each}
{:then [search, downloaded]}
{@const media = $searchStore.media}
{#if search && media}
{@const { results, errors } = search}
{#each filterAndSortResults(results, inputText, downloaded) as result (result.hash)}
<div class='p-3 flex cursor-pointer mb-2 relative rounded-md overflow-hidden bg-neutral-950 group/card select:ring-1 select:ring-custom select:bg-neutral-900 select:scale-[1.02] select:shadow-lg scale-100 transition-all [content-visibility:auto] [contain-intrinsic-height:auto_106px]' class:opacity-40={result.accuracy === 'low'} use:click={() => play(result)} title={result.parseObject.file_name[0]}>
<div class='size-20 relative shrink-0 flex items-center justify-center text-xs px-1 text-wrap break-all font-bold text-center overflow-clip'>
{#if result.accuracy === 'high' || result.accuracy === 'medium'}
<BadgeCheck class={cn('absolute top-0 left-0 mix-blend-difference', result.accuracy === 'high' ? 'text-[#53da33]' : 'text-muted-foreground/20')} fill='currentColor' color='#000' size='1.2rem' />
{/if}
{#if downloaded.has(result.hash)}
<Download class='text-[#53da33] size-12 opacity-80' stroke-width='0.5' color='currentColor' stroke='currentColor' />
{:else if result.type}
<Folder class='text-yellow-300 size-12 opacity-80' fill='currentColor' />
{:else}
<File class='text-muted-foreground size-12 opacity-80' />
{/if}
</div>
<div class='flex pl-2 flex-col justify-between w-full h-20 relative min-w-0 text-[.7rem]'>
<div class='flex w-full items-center'>
<div class='text-xl font-bold text-nowrap group-select/card:text-custom transition-colors'>{getGroup(result.parseObject)}</div>
<div class='ml-auto flex gap-2 self-start'>
{#each result.extension as id (id)}
{#if $saved[id]}
<img src={$saved[id].icon} alt={id} class='size-4' title='Provided by {id}' decoding='async' loading='lazy' />
{/if}
{/each}
</div>
</div>
<div class='text-muted-foreground text-ellipsis text-nowrap overflow-hidden'>{simplifyFilename(result.parseObject)}</div>
<div class='flex flex-row leading-none'>
<div class='details text-light flex'>
{#if result.type === 'best'}
<span class='rounded px-3 py-1 mr-0.5 border text-nowrap flex items-center' style='background: #1d2d1e; border-color: #53da33 !important; color: #53da33'>
Best Release
</span>
{:else if result.type === 'alt'}
<span class='rounded px-3 py-1 mr-0.5 border text-nowrap flex items-center' style='background: #391d20; border-color: #c52d2d !important; color: #c52d2d'>
Alt Release
</span>
{:else if result.type === 'batch'}
<span class='rounded px-3 py-1 mr-0.5 border text-nowrap flex items-center' style='background: #1d2031; border-color: #2d5ec5 !important; color: #2d5ec5'>
Batch
</span>
{/if}
<span class={cn('text-nowrap flex items-center', result.seeders > 20 ? 'text-green-600' : result.seeders < 5 ? 'text-red-600' : 'text-yellow-600')}>{result.seeders} Seeders</span>
<span class='text-nowrap flex items-center text-white/80'>{fastPrettyBytes(result.size)}</span>
<span class='text-nowrap flex items-center text-white/80'>{since(new Date(result.date))}</span>
</div>
<div class='flex ml-auto flex-row-reverse'>
{#each sanitiseTerms(result.parseObject) as { text, color }, i (i)}
<div class='rounded px-3 py-1 ml-2 text-nowrap font-bold flex items-center' style:background={color}>
<div class='text-contrast-filter'>
{text}
</div>
</div>
{/each}
</div>
</div>
</div>
</div>
{:else}
<div class='p-5 flex items-center justify-center w-full h-80'>
<div>
<div class='mb-3 font-bold text-4xl text-center '>
Ooops!
</div>
<div class='text-lg text-center text-muted-foreground'>
No results found.<br />Try specifying a torrent manually by pasting a magnet link or torrent file into the filter bar.
</div>
</div>
</div>
{/each}
{#each errors as error, i (i)}
<div class='p-5 flex items-center justify-center w-full h-80'>
<div>
<div class='mb-1 font-bold text-2xl text-center '>
Extensions {error.extension} encountered an error
</div>
<div class='text-md text-center text-muted-foreground whitespace-pre-wrap'>
{error.error.stack}
</div>
</div>
</div>
{/each}
{/if}
{:catch error}
<div class='p-5 flex items-center justify-center w-full h-80'>
<div>
<div class='mb-3 font-bold text-4xl text-center '>
Ooops!
</div>
<div class='text-lg text-center text-muted-foreground whitespace-pre-wrap'>
{error.message}
</div>
</div>
</div>
{/await}
</div>
</div>
{/if}
</Dialog.Content>
</Dialog.Root>
<style>
.banner {
background: linear-gradient(90deg, #000 32%, rgba(0, 0, 0, 0.9) 100%);
}
.banner-2 {
background: linear-gradient(#000d 0%, #000d 90%, #000 100%);
}
</style>

View file

@ -0,0 +1,20 @@
<script lang='ts'>
import { Label } from '$lib/components/ui/label'
import { cn } from '$lib/utils'
export let title = ''
export let description = ''
const id = Math.trunc(Math.random() * Number.MAX_SAFE_INTEGER).toString() + title
let className = ''
export { className as class }
</script>
<div class={cn('flex flex-col md:flex-row md:items-center justify-between bg-neutral-950 rounded-md px-6 py-4 gap-3', className)}>
<Label for={id} class='space-1 block leading-[unset] grow'>
<div class='font-bold'>{title}</div>
<div class='text-muted-foreground text-xs whitespace-pre-wrap block'>{description}</div>
</Label>
<slot {id} />
</div>

View file

@ -0,0 +1,34 @@
<script lang='ts'>
import { cubicInOut } from 'svelte/easing'
import { crossfade } from 'svelte/transition'
import { Button } from './ui/button'
import { page } from '$app/stores'
import { cn } from '$lib/utils.js'
let className: string | undefined | null = ''
export let items: Array<{ href: string, title: string }>
export { className as class }
const [send, receive] = crossfade({
duration: 150,
easing: cubicInOut
})
const key = 'active-settings-tab'
</script>
<nav class={cn('md:flex grid grid-cols-2 md:flex-row lg:flex-col gap-y-1 gap-x-2 pb-2 sm:pb-0', className)}>
{#each items as { href, title }, i (i)}
{@const isActive = $page.url.pathname === href}
<Button {href} variant='ghost' data-sveltekit-noscroll class='relative font-semibold justify-start last:odd:col-span-2'>
{#if isActive}
<div class='bg-white absolute inset-0 rounded-md' in:send={{ key }} out:receive={{ key }} />
{/if}
<div class='relative text-white transition-colors duration-300' class:!text-black={isActive}>
{title}
</div>
</Button>
{/each}
</nav>

View file

@ -0,0 +1,69 @@
<script lang='ts'>
import dompurify from 'dompurify'
import { marked } from 'marked'
marked.setOptions({
gfm: true,
breaks: true,
pedantic: false
})
export let html = ''
let root: ShadowRoot | undefined
const style = new CSSStyleSheet()
style.replaceSync(/* css */`
p, details {
margin-block-start: .5em;
margin-block-end: .5em;
}
img, video {
max-width: 100%;
-webkit-user-drag: none;
}
summary {
font-weight: bold;
cursor: pointer;
list-style: none;
background: #0003;
display: inline-block;
padding: 0.4em 0.8em;
border-radius: 0.5em;
margin-block-end: .5em;
}
`)
function sanitize (html: string) {
return dompurify.sanitize(html, { ALLOWED_TAGS: ['a', 'b', 'blockquote', 'br', 'center', 'del', 'div', 'em', 'font', 'h1', 'h2', 'h3', 'h4', 'h5', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'code', 'span', 'strike', 'strong', 'ul', 'details', 'summary'], ALLOWED_ATTR: ['align', 'height', 'href', 'src', 'target', 'width', 'rel'] })
}
// i mean holy shit anilist, could you have made it any harder on yourself
function shadow (node: HTMLDivElement, html: string) {
root ??= node.attachShadow({ mode: 'closed' })
root.adoptedStyleSheets = [style]
// eslint-disable-next-line no-useless-escape
html = html.replace(/(http)(:([\/|.|\w|\s|-])*\.(?:jpg|.jpeg|gif|png|mp4|webm))/gi, '$1s$2')
.replace(/img\s?(\d+%?)?\s?\((.[\S]+)\)/gi, "<img width='$1' src='$2'>")
.replace(/(^|>| )@([A-Za-z0-9]+)/gm, "$1<a href='#'>@$2</a>")
.replace(/youtube\s?\([^]*?([-_0-9A-Za-z]{10,15})[^]*?\)/gi, 'youtube ($1)')
// eslint-disable-next-line no-useless-escape
.replace(/webm\s?\(h?([A-Za-z0-9-._~:\/?#\[\]@!$&()*+,;=%]+)\)/gi, 'webmv(`$1`)')
.replace(/~{3}([^]*?)~{3}/gm, '+++$1+++')
.replace(/~!([^]*?)!~/gm, '<details><summary>Spoiler, click to view</summary>$1</details>')
html = sanitize(marked.parse(html, { async: false }))
.replace(/\+{3}([^]*?)\+{3}/gm, '<center>$1</center>')
.replace(/youtube\s?\(([-_0-9A-Za-z]{10,15})\)/gi, `<iframe style='width: 500px; height: 200px; max-width: 100%; border: none;'title='youtube-embed' allow='autoplay' allowfullscreen
src='https://www.youtube-nocookie.com/embed/$1?enablejsapi=1&autoplay=0&controls=1&mute=0&disablekb=1&loop=1&playlist=$1&cc_lang_pref=ja' />`)
// eslint-disable-next-line no-useless-escape
.replace(/webmv\s?\(<code>([A-Za-z0-9-._~:\/?#\[\]@!$&()*+,;=%]+)<\/code>\)/gi, "<video muted loop controls><source src='h$1' type='video/webm'>Your browser does not support the video tag.</video>")
// t = t.replace(/(?:<a href="https?:\/\/anilist.co\/(anime|manga)\/)([0-9]+).*?>(?:https?:\/\/anilist.co\/(?:anime|manga)\/[0-9]+).*?<\/a>/gm, '<span class="media-embed" data-media-type="$1" data-media-id="$2"></span>')
root.innerHTML = html
}
let className: string | undefined | null
export { className as class }
</script>
<div use:shadow={html} class={className} />

View file

@ -0,0 +1,33 @@
<script lang='ts'>
import { tv, type VariantProps } from 'tailwind-variants'
import type { HTMLAttributes } from 'svelte/elements'
import { cn } from '$lib/utils'
const dotvariants = tv({
base: 'inline-flex w-[0.55rem] h-[0.55rem] me-1 bg-blue-600 rounded-full',
variants: {
variant: {
CURRENT: 'bg-[rgb(61,180,242)]',
PLANNING: 'bg-[rgb(247,154,99)]',
COMPLETED: 'bg-[rgb(123,213,85)]',
PAUSED: 'bg-[rgb(250,122,122)]',
REPEATING: 'bg-[#3baeea]',
DROPPED: 'bg-[rgb(232,93,117)]'
}
},
defaultVariants: {
variant: 'CURRENT'
}
})
export let variant: VariantProps<typeof dotvariants>['variant'] = 'CURRENT'
type $$Props = HTMLAttributes<HTMLSpanElement> & { variant: VariantProps<typeof dotvariants>['variant']}
let className: $$Props['class'] = ''
export { className as class }
</script>
<span class={cn(dotvariants({ variant }), className)} />

View file

@ -0,0 +1,11 @@
<svg xmlns='http://www.w3.org/2000/svg' width='41' height='30' fill='none' viewBox='0 0 41 30' {...$$props}>
<g clip-path='url(#clip0_312_151)'>
<path fill='#00A8FF' d='M27.825 21.773V2.977c0-1.077-.613-1.672-1.725-1.672h-3.795c-1.111 0-1.725.595-1.725 1.672v8.927c0 .251 2.5 1.418 2.565 1.665 1.904 7.21.414 12.982-1.392 13.251 2.952.142 3.277 1.517 1.078.578.337-3.848 1.65-3.84 5.422-.142.032.032.774 1.539.82 1.539h8.91c1.113 0 1.726-.594 1.726-1.672v-3.677c0-1.078-.614-1.672-1.725-1.672H27.825z' />
<path fill='#fff' d='M12.07 1.306l-9.966 27.49h7.743l1.687-4.756h8.433l1.649 4.755h7.705l-9.929-27.49H12.07zm1.227 16.642l2.415-7.615 2.645 7.615h-5.06z' />
</g>
<defs>
<clipPath id='clip0_312_151'>
<path fill='#fff' d='M0 0H40V29H0z' transform='translate(.957 .5)' />
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 831 B

View file

@ -0,0 +1,13 @@
<script lang='ts'>
import Icon from 'lucide-svelte/dist/Icon.svelte'
import type { SvelteHTMLElements, SVGAttributes } from 'svelte/elements'
type Attrs = SVGAttributes<SVGSVGElement>
const iconNode: Array<[elementName: keyof SvelteHTMLElements, attrs: Attrs]> = [['path', { d: 'M240-44q-48.5 0-82.25-33.75T124-160q0-48.5 33.75-82.25T240-276q14 0 24.25 2.25t21.25 7.25L353-351q-25.5-29-34.25-63.25T314-482.5L216-515q-17 23.5-41 37.25T120-464q-48.5 0-82.25-33.75T4-580q0-48.5 33.75-82.25T120-696q48.5 0 82.25 33.75T236-580v5.5l97.5 34q16.5-31 47.25-54t68.25-30V-728q-39.5-12.5-62.25-43T364-840q0-48.5 33.75-82.25T480-956q48.5 0 82.25 33.75T596-840q0 38.5-23.25 69T511-728v103.5q37.5 7 68 30t47.5 54l97.5-34v-5.5q0-48.5 33.75-82.25T840-696q48.5 0 82.25 33.75T956-580q0 48.5-33.75 82.25T840-464q-31 0-55.5-13.75T744-515l-98 32.5q4 34.5-5 68.25T607-351l67.5 84q11-5 21.25-7t24.25-2q48.5 0 82.25 33.75T836-160q0 48.5-33.75 82.25T720-44q-48.5 0-82.25-33.75T604-160q0-19.5 5.75-36.25T626-228l-67-84.5q-36.5 20-79.25 20.25T400.5-312.5L334-228q10.5 15 16.25 31.75T356-160q0 48.5-33.75 82.25T240-44ZM120-539q17 0 29-12t12-29q0-17-12-29t-29-12q-17 0-29 12t-12 29q0 17 12 29t29 12Zm120 420q17 0 29-12t12-29q0-17-12-29t-29-12q-17 0-29 12t-12 29q0 17 12 29t29 12Zm240-680q17 0 29-12t12-29q0-17-12-29t-29-12q-17 0-29 12t-12 29q0 17 12 29t29 12Zm0 431.5q38.5 0 65.5-27t27-65.5q0-38.5-27-65.5t-65.5-27q-38.5 0-65.5 27t-27 65.5q0 38.5 27 65.5t65.5 27ZM720-119q17 0 29-12t12-29q0-17-12-29t-29-12q-17 0-29 12t-12 29q0 17 12 29t29 12Zm120-420q17 0 29-12t12-29q0-17-12-29t-29-12q-17 0-29 12t-12 29q0 17 12 29t29 12ZM480-840ZM120-580Zm360 120Zm360-120ZM240-160Zm480 0Z' }]]
</script>
<Icon name='hub' {...$$props} {iconNode} viewBox='0 -960 960 960'>
<slot />
</Icon>

View file

@ -0,0 +1,8 @@
<svg width='224' height='224' viewBox='0 0 224 224' {...$$props}>
<g fill='none' fill-rule='evenodd'>
<g fill='#E75E45'>
<path d='M152.7 48.5c-6.8-2.5-14.1-4.1-21.8-4.4-12.7-.6-24.8 2.2-35.4 7.6-.6.3-1.3.6-2 1v36.4c0 .5 0 2.4-.3 4-.7 3.7-2.9 7-6 9.1-2.6 1.8-5.6 2.6-8.8 2.5-.6 0-1.3-.1-1.9-.2-1.6-.3-3.3-.9-3.8-1.1-1.4-.5-21.8-8.4-31.6-12.2-1.2-.5-2.2-.9-3-1.2-11.7 9.9-24 21.7-35.5 35.6-.1.1-.6.7-.7.8-1.5 2.1-1.6 5.1 0 7.4 1.2 1.7 3.1 2.7 5 2.8 1.3.1 2.7-.3 3.9-1.1.1-.1.2-.2.4-.3 12.2-8.8 25.6-15.9 39.8-21.6 1-.5 2.2-.8 3.3-.7 1.6.1 3.1.7 4.3 1.9 2.3 2.3 2.4 6 .5 8.5-.8 1.2-1.5 2.4-2.2 3.6-7.6 12.4-13.7 25.9-18.3 40-.1.4-.2.7-.3 1.1v.1c-.4 1.7-.1 3.5 1 5 1.2 1.7 3.1 2.7 5.1 2.8 1.4.1 2.7-.3 3.9-1.1.5-.4 1-.8 1.4-1.3.1-.2.3-.4.4-.6 5-7.1 10.5-13.8 16.4-20 26.3-28.2 61.2-48.1 100.3-55.9.3-.1.6-.1.9-.1 2.2.1 3.9 2 3.8 4.2-.1 1.9-1.4 3.3-3.2 3.7-36.3 7.7-101.7 50.8-78.8 113.4.4 1 .7 1.6 1.2 2.5 1.2 1.7 3.1 2.7 5 2.8 1.1 0 4.2-.3 6.1-3.7 3.7-7 10.7-14.8 30.9-23.2 56.3-23.3 65.6-56.6 66.6-77.7v-1.2c.9-31.4-18.6-58.8-46.6-69.2zm-56.5 165C91 198 91.5 183 97.6 168.7c11.7 18.9 32.1 20.5 32.1 20.5-20.9 8.7-29.1 17.3-33.5 24.3z' />
<path d='M1.1 50.6c.1.2.3.4.4.5 5.3 7.2 11.3 13.5 17.8 19.1.1.1.2.1.2.2 4.2 3.6 12.2 8.8 18 10.9 0 0 36.1 13.9 38 14.7.7.3 1.7.6 2.2.7 1.6.3 3.3 0 4.8-1s2.4-2.5 2.7-4.1c.1-.6.2-1.6.2-2.3V48.5c.1-6.2-1.9-15.6-3.7-20.8 0-.1-.1-.2-.1-.3-2.8-8.1-6.6-16-11.4-23.5l-.3-.6-.1-.1c-2-2.8-6-3.5-8.9-1.5-.5.3-.8.7-1.2 1.1-.3.4-.5.7-.8 1.1-6.4 9.3-9 20.6-7.3 31.7-3.3 1.7-6.8 4-7.2 4.3-.4.3-3.9 2.7-6.6 5.2-9.7-5.5-21.3-7.2-32.2-4.6-.4.1-.9.2-1.3.3-.5.2-1 .4-1.4.7-2.9 2-3.7 5.9-1.8 8.9v.2zm63.5-40.1c3.4 5.7 6.3 11.6 8.6 17.8-4.6.8-9.1 2-13.5 3.6-.6-7.5 1.1-14.9 4.9-21.4zM31.5 51.3c-3.2 3.5-5.9 7.3-8.3 11.3-4.9-4.3-9.4-9.2-13.5-14.4 7.5-1.3 15-.2 21.8 3.1z' />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1 @@
<svg name='logo' {...$$props} on:click xml:space='preserve' viewBox='0 0 66.145833 66.145833'><path fill='currentColor' d='M.00000117 61.5156237V4.6302097l66.145831 37.041664v19.84375l-47.624995-26.72291v16.40416zm66.145831-30.42707-23.547916-13.229174 23.547916-13.22917Z' /></svg>

After

Width:  |  Height:  |  Size: 283 B

View file

@ -0,0 +1,18 @@
<script lang='ts'>
import Icon from 'lucide-svelte/dist/Icon.svelte'
import type { SvelteHTMLElements, SVGAttributes } from 'svelte/elements'
type Attrs = SVGAttributes<SVGSVGElement>
import { cn } from '$lib/utils'
const iconNode: Array<[elementName: keyof SvelteHTMLElements, attrs: Attrs]> = [['path', { fill: 'currentColor', d: 'M8.273 7.247v8.423l-2.103-.003v-5.216l-2.03 2.404l-1.989-2.458l-.02 5.285H.001L0 7.247h2.203l1.865 2.545l2.015-2.546zm8.628 2.069l.025 6.335h-2.365l-.008-2.871h-2.8c.07.499.21 1.266.417 1.779c.155.381.298.751.583 1.128l-1.705 1.125c-.349-.636-.622-1.337-.878-2.082a9.3 9.3 0 0 1-.507-2.179c-.085-.75-.097-1.471.107-2.212a3.9 3.9 0 0 1 1.161-1.866c.313-.293.749-.5 1.1-.687s.743-.264 1.107-.359a7.4 7.4 0 0 1 1.191-.183c.398-.034 1.107-.066 2.39-.028l.545 1.749H14.51c-.593.008-.878.001-1.341.209a2.24 2.24 0 0 0-1.278 1.92l2.663.033l.038-1.81zm3.992-2.099v6.627l3.107.032l-.43 1.775h-4.807V7.187z' }]]
let className = ''
export { className as class }
</script>
<Icon name='myanimelist' class={cn(className, 'bg-[#3557a5] rounded px-[2px] text-white')} color='none' {...$$restProps} {iconNode} strokeWidth='1' viewBox='0 0 24 24'>
<slot />
</Icon>

View file

@ -0,0 +1,12 @@
<script lang='ts'>
import Icon from 'lucide-svelte/dist/Icon.svelte'
import type { SvelteHTMLElements, SVGAttributes } from 'svelte/elements'
type Attrs = SVGAttributes<SVGSVGElement>
const iconNode: Array<[elementName: keyof SvelteHTMLElements, attrs: Attrs]> = [['path', { d: 'M8 4.5v5H3m-1-6 6 6m13 0v-3c0-1.16-.84-2-2-2h-7m-9 9v2c0 1.05.95 2 2 2h3' }], ['rect', { width: '10', height: '7', x: '12', y: '13', rx: '2', fill: 'currentColor' }]]
</script>
<Icon name='picture-in-picture' {...$$props} {iconNode}>
<slot />
</Icon>

View file

@ -0,0 +1,12 @@
<script lang='ts'>
import Icon from 'lucide-svelte/dist/Icon.svelte'
import type { SvelteHTMLElements, SVGAttributes } from 'svelte/elements'
type Attrs = SVGAttributes<SVGSVGElement>
const iconNode: Array<[elementName: keyof SvelteHTMLElements, attrs: Attrs]> = [['path', { d: 'M21 9V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10c0 1.1.9 2 2 2h4' }], ['rect', { width: '10', height: '7', x: '12', y: '13', rx: '2', fill: 'currentColor' }]]
</script>
<Icon name='picture-in-picture-exit' {...$$props} {iconNode}>
<slot />
</Icon>

View file

@ -0,0 +1,14 @@
<script lang='ts'>
import Icon from 'lucide-svelte/dist/Icon.svelte'
import type { SvelteHTMLElements, SVGAttributes } from 'svelte/elements'
type Attrs = SVGAttributes<SVGSVGElement>
const iconNode: Array<[elementName: keyof SvelteHTMLElements, attrs: Attrs]> = [
['path', { 'fill-rule': 'evenodd', 'clip-rule': 'evenodd', d: 'M22.99 11.7773C22.9219 10.8388 22.4205 9.92777 21.4859 9.39398L7.48782 1.39936C5.48785 0.25713 3 1.70127 3 4.00443V19.9937C3 22.2968 5.48785 23.741 7.48781 22.5988L21.4859 14.6041C22.4205 14.0703 22.9219 13.1593 22.99 12.2208C23.0226 12.0751 23.0226 11.9231 22.99 11.7773Z' }]
]
</script>
<Icon name='play' {...$$props} {iconNode} viewBox='0 0 24 24' strokeWidth='0'>
<slot />
</Icon>

View file

@ -0,0 +1,15 @@
<script lang='ts'>
import Icon from 'lucide-svelte/dist/Icon.svelte'
import type { SvelteHTMLElements, SVGAttributes } from 'svelte/elements'
type Attrs = SVGAttributes<SVGSVGElement>
const iconNode: Array<[elementName: keyof SvelteHTMLElements, attrs: Attrs]> = [
['path', { fill: 'none', d: 'M0 0h24v24H0z' }],
['path', { d: 'M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 12h4v2H4v-2zm10 6H4v-2h10v2zm6 0h-4v-2h4v2zm0-4H10v-2h10v2z' }]
]
</script>
<Icon name='subtitles' {...$$props} {iconNode} viewBox='0 0 24 24' strokeWidth='0'>
<slot />
</Icon>

View file

@ -0,0 +1,43 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible [transform-origin:center] target-animated-icon')}
{...$$restProps}
>
<path
d='M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z'
/><circle cx='12' cy='12' r='4' />
</svg>
<style>
.target-animated-icon {
animation: screw-rotate 1s ease 3;
}
@keyframes screw-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
</style>

View file

@ -0,0 +1,47 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size: number | string = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible target-animated-icon')}
{...$$restProps}
>
<path d='m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z' />
</svg>
<style>
.target-animated-icon {
animation: primaryAnimation 0.5s ease-in-out;
}
@keyframes primaryAnimation {
0% {
transform: scale(1) rotate(0deg);
}
20% {
transform: scale(1.05) rotate(-7deg);
}
40% {
transform: scale(1.05) rotate(7deg);
}
100% {
transform: scale(1) rotate(0deg);
}
}
</style>

View file

@ -0,0 +1,68 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
const DOTS = [
{ cx: 8, cy: 14 },
{ cx: 12, cy: 14 },
{ cx: 16, cy: 14 },
{ cx: 8, cy: 18 },
{ cx: 12, cy: 18 },
{ cx: 16, cy: 18 }
]
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path d='M8 2v4' />
<path d='M16 2v4' />
<rect width='18' height='18' x='3' y='4' rx='2' />
<path d='M3 10h18' />
{#each DOTS as dot, index (index)}
<circle
cx={dot.cx}
cy={dot.cy}
r='1'
fill={color}
stroke='none'
class='target-animated-icon'
style='animation-delay: {index * 0.17}s'
/>
{/each}
</svg>
<style>
.target-animated-icon {
animation: pulse 0.8s;
}
@keyframes pulse {
0% {
opacity: 1;
}
50% {
opacity: 0.3;
}
100% {
opacity: 1;
}
}
</style>

View file

@ -0,0 +1,33 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size: number | string = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path d='m15 18-6-6 6-6' class='target-animated-icon' />
</svg>
<style>
.target-animated-icon {
transition: transform 0.2s ease-in;
transform: translateX(-3px);
}
</style>

View file

@ -0,0 +1,33 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size: number | string = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path d='m9 18 6-6-6-6' class='target-animated-icon' />
</svg>
<style>
.target-animated-icon {
transition: transform 0.2s ease-in;
transform: translateX(3px);
}
</style>

View file

@ -0,0 +1,76 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<g class='target-animated-icon clapperboard-outer'>
<g class='target-animated-icon clapperboard-inner'>
<path d='M20.2 6 3 11l-.9-2.4c-.3-1.1.3-2.2 1.3-2.5l13.5-4c1.1-.3 2.2.3 2.5 1.3Z' />
<path d='m6.2 5.3 3.1 3.9' />
<path d='m12.4 3.4 3.1 4' />
</g>
<path d='M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z' />
</g>
</svg>
<style>
.clapperboard-outer {
transform-origin: 4px 20px;
}
.clapperboard-inner {
transform-origin: 3px 11px;
}
.target-animated-icon {
animation: clapperboardOuter 0.8s ease-in-out;
}
.target-animated-icon {
animation: clapperboardInner 0.4s ease-in-out;
}
@keyframes clapperboardOuter {
0%,
50% {
transform: rotate(-10deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes clapperboardInner {
0% {
transform: rotate(0deg);
}
30% {
transform: rotate(-10deg);
}
60% {
transform: rotate(16deg);
}
100% {
transform: rotate(0deg);
}
}
</style>

View file

@ -0,0 +1,37 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4' />
<g>
<polyline points='7 10 12 15 17 10' class='target-animated-icon' />
<line x1='12' x2='12' y1='15' y2='3' class='target-animated-icon' />
</g>
</svg>
<style>
.target-animated-icon {
transform: translateY(2px);
transition: transform 0.3s cubic-bezier(0.68, -0.6, 0.32, 1.6);
}
</style>

View file

@ -0,0 +1,50 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible target-animated-icon')}
{...$$restProps}
>
<path d='M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z' />
<path d='M14 2v4a2 2 0 0 0 2 2h4' />
<circle cx='10' cy='12' r='2' />
<path d='m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22' />
</svg>
<style>
.target-animated-icon {
animation: primaryAnimation 0.5s ease-in-out;
}
@keyframes primaryAnimation {
0% {
transform: scale(1) rotate(0deg);
}
20% {
transform: scale(1.05) rotate(-7deg);
}
40% {
transform: scale(1.05) rotate(7deg);
}
100% {
transform: scale(1) rotate(0deg);
}
}
</style>

View file

@ -0,0 +1,43 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path
d='M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v.5'
/>
<g class='target-animated-icon'>
<path d='M12 10v4h4' />
<path d='m12 14 1.535-1.605a5 5 0 0 1 8 1.5' />
<path d='M22 22v-4h-4' />
<path d='m22 18-1.535 1.605a5 5 0 0 1-8-1.5' />
</g>
</svg>
<style>
.target-animated-icon {
transform-origin: center;
transform-box: fill-box;
transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
transform: rotate(-50deg);
}
</style>

View file

@ -0,0 +1,60 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size: number | string = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path
d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'
class='target-animated-icon'
/>
</svg>
<style>
.target-animated-icon {
transform-origin: center;
animation: heartBeat 1.2s ease-in-out;
}
@keyframes heartBeat {
0% {
transform: scale(1);
}
16.67% {
transform: scale(1.1);
}
33.33% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
66.67% {
transform: scale(1);
}
83.33% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
</style>

View file

@ -0,0 +1,52 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path
d='M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'
/>
<path d='M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8' class='target-animated-icon' />
</svg>
<style>
.target-animated-icon {
stroke-dasharray: 22;
stroke-dashoffset: 0;
animation: doorAnimation 0.6s ease-out forwards;
}
@keyframes doorAnimation {
0% {
stroke-dashoffset: 22;
opacity: 0;
}
15% {
stroke-dashoffset: 22;
opacity: 0;
}
100% {
stroke-dashoffset: 0;
opacity: 1;
}
}
</style>

View file

@ -0,0 +1,19 @@
export { default as Home } from './home.svelte'
export { default as Search } from './search.svelte'
export { default as Calendar } from './calendar.svelte'
export { default as Users } from './users.svelte'
export { default as Download } from './download.svelte'
export { default as Bolt } from './bolt.svelte'
export { default as LogIn } from './login.svelte'
export { default as Messages } from './messages.svelte'
export { default as PencilLine } from './pencilline.svelte'
export { default as Heart } from './heart.svelte'
export { default as Bookmark } from './bookmark.svelte'
export { default as Clapperboard } from './clapperboard.svelte'
export { default as ChevronRight } from './chevronright.svelte'
export { default as ChevronLeft } from './chevronleft.svelte'
export { default as Trash } from './trash.svelte'
export { default as FileImage } from './fileimage.svelte'
export { default as Minimize } from './minimize.svelte'
export { default as Maximize } from './maximize.svelte'
export { default as FolderSync } from './foldersync.svelte'

View file

@ -0,0 +1,37 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible -rotate-90')}
{...$$restProps}
>
<path d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4' />
<g>
<polyline points='7 10 12 15 17 10' class='target-animated-icon' />
<line x1='12' x2='12' y1='15' y2='3' class='target-animated-icon' />
</g>
</svg>
<style>
.target-animated-icon {
transform: translateY(2px);
transition: transform 0.3s cubic-bezier(0.68, -0.6, 0.32, 1.6);
}
</style>

View file

@ -0,0 +1,55 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size: string | number = 24
export let strokeWidth: string | number = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path d='M8 3H5a2 2 0 0 0-2 2v3' class='top-left target-animated-icon' />
<path d='M21 8V5a2 2 0 0 0-2-2h-3' class='top-right target-animated-icon' />
<path d='M3 16v3a2 2 0 0 0 2 2h3' class='bottom-left target-animated-icon' />
<path d='M16 21h3a2 2 0 0 0 2-2v-3' class='bottom-right target-animated-icon' />
</svg>
<style>
path {
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.bottom-right {
transform: translate(2px, 2px);
}
.bottom-left {
transform: translate(-2px, 2px);
}
.top-right {
transform: translate(2px, -2px);
}
.top-left {
transform: translate(-2px, -2px);
}
svg {
overflow: visible;
}
</style>

View file

@ -0,0 +1,48 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible target-animated-icon')}
{...$$restProps}
>
<path d='M14 9a2 2 0 0 1-2 2H6l-4 4V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2z' />
<path d='M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1' />
</svg>
<style>
.target-animated-icon {
animation: primaryAnimation 0.5s ease-in-out;
}
@keyframes primaryAnimation {
0% {
transform: scale(1) rotate(0deg);
}
20% {
transform: scale(1.05) rotate(-7deg);
}
40% {
transform: scale(1.05) rotate(7deg);
}
100% {
transform: scale(1) rotate(0deg);
}
}
</style>

View file

@ -0,0 +1,51 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size: string | number = 24
export let strokeWidth: string | number = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path d='M8 3v3a2 2 0 0 1-2 2H3' class='top-left target-animated-icon' />
<path d='M21 8h-3a2 2 0 0 1-2-2V3' class='top-right target-animated-icon' />
<path d='M3 16h3a2 2 0 0 1 2 2v3' class='bottom-left target-animated-icon' />
<path d='M16 21v-3a2 2 0 0 1 2-2h3' class='bottom-right target-animated-icon' />
</svg>
<style>
path {
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.bottom-right {
transform: translate(-1px, -1px);
}
.top-left {
transform: translate(1px, 1px);
}
.bottom-left {
transform: translate(1px, -1px);
}
.top-right {
transform: translate(-1px, 1px);
}
</style>

View file

@ -0,0 +1,51 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path d='M12 20h9' />
<path
d='M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z'
class='target-animated-icon'
/>
<path d='m15 5 3 3' class='target-animated-icon' />
</svg>
<style>
.target-animated-icon {
transform-origin: 16.376px 3.622px;
animation: penWiggle 0.5s ease-in-out 2;
}
@keyframes penWiggle {
0%,
100% {
transform: rotate(0deg) translate(0px, 0px);
}
25% {
transform: rotate(-0.5deg) translate(-1px, 1.5px);
}
75% {
transform: rotate(0.5deg) translate(1.5px, -1px);
}
}
</style>

View file

@ -0,0 +1,46 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible target-animated-icon')}
{...$$restProps}
>
<circle cx='11' cy='11' r='8' />
<path d='m21 21-4.3-4.3' />
</svg>
<style>
.target-animated-icon {
animation: search-bounce 1s ease-in-out;
}
@keyframes search-bounce {
0%,
100% {
transform: translateX(0) translateY(0);
}
25% {
transform: translateX(0) translateY(-4px);
}
50% {
transform: translateX(-3px) translateY(0);
}
}
</style>

View file

@ -0,0 +1,41 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible [transform-origin:center]')}
{...$$restProps}
>
<g class='target-animated-icon'>
<path d='M3 6h18' />
<path d='M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2' />
</g>
<path d='M19 8v12c0 1-1 2-2 2H7c-1 0-2-1-2-2V8' class='target-animated-icon' />
</svg>
<style>
g.target-animated-icon {
transform: translateY(-1px);
transition: transform 0.2s ease-in;
}
path.target-animated-icon {
transform: translateY(1px);
transition: transform 0.2s ease-in;
}
</style>

View file

@ -0,0 +1,47 @@
<script lang='ts'>
import { cn } from '$lib/utils'
export let color = 'currentColor'
export let size = 24
export let strokeWidth = 2
let className = ''
export { className as class }
</script>
<svg
xmlns='http://www.w3.org/2000/svg'
width={size}
height={size}
viewBox='0 0 24 24'
fill='none'
stroke={color}
stroke-width={strokeWidth}
stroke-linecap='round'
stroke-linejoin='round'
class={cn(className, 'overflow-visible')}
{...$$restProps}
>
<path d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2' />
<circle cx='9' cy='7' r='4' />
<path d='M22 21v-2a4 4 0 0 0-3-3.87' class='target-animated-icon' />
<path d='M16 3.13a4 4 0 0 1 0 7.75' class='target-animated-icon' />
</svg>
<style>
.target-animated-icon {
animation: users-slide 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
}
@keyframes users-slide {
0% {
transform: translateX(0);
}
50% {
transform: translateX(-6px);
}
100% {
transform: translateX(0);
}
}
</style>

View file

@ -0,0 +1,17 @@
<script lang='ts'>
import { Avatar as AvatarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils.js'
type $$Props = AvatarPrimitive.FallbackProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<AvatarPrimitive.Fallback
class={cn('bg-muted flex h-full w-full items-center justify-center rounded-full', className)}
{...$$restProps}
>
<slot />
</AvatarPrimitive.Fallback>

View file

@ -0,0 +1,19 @@
<script lang='ts'>
import { Avatar as AvatarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils.js'
type $$Props = AvatarPrimitive.ImageProps & { alt: string | undefined | null, src: string | undefined | null }
let className: $$Props['class'] = undefined
export let src: $$Props['src']
export let alt: $$Props['alt']
export { className as class }
</script>
<AvatarPrimitive.Image
{src}
{alt}
class={cn('aspect-square h-full w-full object-cover', className)}
{...$$restProps}
/>

View file

@ -0,0 +1,19 @@
<script lang='ts'>
import { Avatar as AvatarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils.js'
type $$Props = AvatarPrimitive.Props
let className: $$Props['class'] = undefined
export let delayMs: $$Props['delayMs'] = 0
export { className as class }
</script>
<AvatarPrimitive.Root
{delayMs}
class={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', className)}
{...$$restProps}
>
<slot />
</AvatarPrimitive.Root>

View file

@ -0,0 +1,13 @@
import Fallback from './avatar-fallback.svelte'
import Image from './avatar-image.svelte'
import Root from './avatar.svelte'
export {
Root,
Image,
Fallback,
//
Root as Avatar,
Image as AvatarImage,
Fallback as AvatarFallback
}

View file

@ -0,0 +1,19 @@
<script lang='ts'>
import { type Variant, badgeVariants } from './index.js'
import { cn } from '$lib/utils.js'
let className: string | undefined | null = ''
export let href: string | undefined = ''
export let variant: Variant = 'default'
export { className as class }
</script>
<svelte:element
this={href ? 'a' : 'span'}
{href}
class={cn(badgeVariants({ variant, className }))}
{...$$restProps}
>
<slot />
</svelte:element>

View file

@ -0,0 +1,22 @@
import { type VariantProps, tv } from 'tailwind-variants'
export { default as Badge } from './badge.svelte'
export const badgeVariants = tv({
base: 'focus:ring-ring inline-flex select-none items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2',
variants: {
variant: {
default: 'bg-primary text-primary-foreground border-transparent shadow',
secondary: 'bg-secondary text-secondary-foreground border-transparent',
destructive: 'bg-destructive text-destructive-foreground border-transparent shadow',
outline: 'text-foreground',
success: 'bg-[#21b959] text-primary-foreground border-transparent shadow',
warning: 'bg-[#eab308] text-primary-foreground border-transparent shadow',
error: 'bg-[#bf2c2c] text-primary-foreground border-transparent shadow'
}
},
defaultVariants: {
variant: 'default'
}
})
export type Variant = VariantProps<typeof badgeVariants>['variant']

View file

@ -0,0 +1,49 @@
<script lang='ts' context='module'>
import { writable } from 'simple-store-svelte'
import type { Media } from '$lib/modules/anilist'
import { cn } from '$lib/utils'
export const bannerSrc = writable<Media | null>(null)
export const hideBanner = writable(false)
</script>
<script lang='ts'>
import { Banner } from '../img'
import type { HTMLAttributes } from 'svelte/elements'
type $$Props = HTMLAttributes<HTMLImageElement>
let className: $$Props['class'] = ''
export { className as class } // TODO: needs nice animations, should update to coverimage on mobile width
</script>
{#if $bannerSrc}
<div class={cn('object-cover w-screen absolute top-0 left-0 h-full overflow-hidden pointer-events-none bg-black banner', className)}>
{#key $bannerSrc.id}
<Banner media={$bannerSrc} class='min-w-[100vw] w-screen h-[23rem] object-cover {$hideBanner ? 'opacity-10' : 'opacity-100'} transition-opacity duration-500 banner-gr relative' />
{/key}
</div>
{/if}
<style>
:global(div.banner-gr::after) {
content: '';
position: absolute;
left: 0 ; bottom: 0;
width: 100%;
height: 300px;
background: linear-gradient(1turn, rgb(3, 3, 3) 8.98%, rgba(0, 0, 0, 0) 100%);
}
.banner::after {
content: '';
position: absolute;
left: 0 ; top: 0;
width: 100%; height: 23rem;
z-index: 0;
background: rgba(0, 0, 0, .4);
}
</style>

View file

@ -0,0 +1,50 @@
<script lang='ts' context='module'>
import { client, currentSeason, currentYear } from '$lib/modules/anilist'
const query = client.search({ sort: ['POPULARITY_DESC'], perPage: 15, season: currentSeason, seasonYear: currentYear, statusNot: ['NOT_YET_RELEASED'] }, true)
query.subscribe(() => undefined) // this is hacky as shit, but prevents query from re-running
</script>
<script lang='ts'>
import { onDestroy } from 'svelte'
import { get } from 'svelte/store'
import FullBanner from './full-banner.svelte'
import SkeletonBanner from './skeleton-banner.svelte'
onDestroy(() => {
query.pause()
})
if (get(query.isPaused$)) query.resume()
</script>
<div class='w-full h-[400px] relative'>
<!-- really shit and hacky way of fixing scroll position jumping when banner changes height -->
<div class='absolute top-0 transparent h-full opacity-0'>.</div>
{#if $query.fetching}
<SkeletonBanner />
{/if}
{#if $query.error}
<div class='p-5 flex items-center justify-center w-full h-72'>
<div>
<div class='mb-1 font-bold text-4xl text-center '>
Ooops!
</div>
<div class='text-lg text-center text-muted-foreground'>
Looks like something went wrong!
</div>
<div class='text-lg text-center text-muted-foreground'>
{$query.error.message}
</div>
</div>
</div>
{/if}
{#if $query.data}
{#if $query.data.Page?.media}
<FullBanner mediaList={$query.data.Page.media} />
{:else}
<SkeletonBanner />
{/if}
{/if}
</div>

View file

@ -0,0 +1,138 @@
<script lang='ts'>
import { onDestroy } from 'svelte'
import { BookmarkButton, FavoriteButton, PlayButton } from '../button/extra'
import { bannerSrc } from './banner-image.svelte'
import { desc, duration, format, season, title, type Media } from '$lib/modules/anilist'
import { of } from '$lib/modules/auth'
import { click } from '$lib/modules/navigate'
export let mediaList: Array<Media | null>
function shuffle <T extends unknown[]> (array: T): T {
let currentIndex = array.length
let randomIndex
while (currentIndex > 0) {
randomIndex = Math.floor(Math.random() * currentIndex--);
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]
}
return array
}
function shuffleAndFilter (media: Array<Media | null>) {
return shuffle(media).filter(media => media?.bannerImage ?? media?.trailer?.id).slice(0, 5) as Media[]
}
const shuffled = shuffleAndFilter(mediaList)
// TODO: this assertion is incorrect!
let current = shuffled[0]!
const initial = bannerSrc.value
$: bannerSrc.value = current
onDestroy(() => {
bannerSrc.value = initial
})
function currentIndex () {
return shuffled.indexOf(current)
}
function schedule (index: number) {
return setTimeout(() => {
current = shuffled[index % shuffled.length]!
timeout = schedule(index + 1)
}, 15000)
}
let timeout = schedule(currentIndex() + 1)
function setCurrent (media: Media) {
if (current === media) return
clearTimeout(timeout)
current = media
timeout = schedule(currentIndex() + 1)
}
function tabindex (node: HTMLElement) {
node.tabIndex = -1
}
</script>
<div class='pl-5 pb-5 justify-end flex flex-col h-full max-w-full'>
{#key current}
<a class='text-white font-black text-4xl line-clamp-1 w-[900px] max-w-full leading-tight fade-in hover:text-neutral-300 hover:underline cursor-pointer' href='/app/anime/{current.id}'>
{title(current)}
</a>
<div class='details text-white capitalize pt-3 pb-2 flex w-[600px] max-w-full text-xs fade-in'>
<span class='text-nowrap flex items-center'>
{format(current)}
</span>
<span class='text-nowrap flex items-center'>
{of(current) ?? duration(current) ?? 'N/A'}
</span>
<span class='text-nowrap flex items-center'>
{season(current)}
</span>
</div>
<div class='text-muted-foreground line-clamp-2 w-[600px] max-w-full text-sm fade-in'>
{desc(current)}
</div>
<div class='details text-white text-capitalize py-3 flex w-[600px] max-w-full text-xs fade-in'>
{#each current.genres ?? [] as genre (genre)}
<span class='text-nowrap flex items-center'>
{genre}
</span>
{/each}
</div>
<div class='flex flex-row pb-2 w-[230px] max-w-full'>
<PlayButton media={current} class='grow' />
<FavoriteButton media={current} class='ml-2' />
<BookmarkButton media={current} class='ml-2' />
</div>
{/key}
<div class='flex'>
{#each shuffled as media (media.id)}
{@const active = current === media}
<div class='pt-2 pb-1' class:cursor-pointer={!active} use:click={() => setCurrent(media)} use:tabindex>
<div class='bg-neutral-800 mr-2 progress-badge overflow-clip rounded' class:active style='height: 4px;' style:width={active ? '3rem' : '1.5rem'}>
<div class='progress-content h-full transform-gpu w-full' class:bg-white={active} />
</div>
</div>
{/each}
</div>
</div>
<style>
.progress-badge {
transition: width .7s ease;
}
.progress-badge.active .progress-content {
animation: fill 15s linear;
}
@keyframes fill {
from {
transform: translate3d(-100%, var(--tw-translate-y), 0);
}
to {
transform: translate3d(0%, var(--tw-translate-y), 0);
}
}
.details span + span::before {
content: '•';
padding: 0 .5rem;
font-size: .6rem;
align-self: center;
white-space: normal;
color: #737373 !important;
}
.fade-in {
animation: fade-in ease .8s;
}
</style>

View file

@ -0,0 +1,3 @@
export { default as BannerImage } from './banner-image.svelte'
export { default as Banner } from './banner.svelte'
export * from './banner-image.svelte'

View file

@ -0,0 +1,11 @@
<div class='pl-5 pb-5 justify-end flex flex-col h-full max-w-full'>
<div class='bg-primary/5 animate-pulse rounded w-[500px] h-6 mb-1' />
<div class='my-5 h-1.5 w-[250px] bg-primary/5 animate-pulse rounded' />
<div class='h-2.5 w-[450px] bg-primary/5 animate-pulse rounded mb-2' />
<div class='h-2.5 w-[350px] bg-primary/5 animate-pulse rounded mb-2' />
<div class='h-2.5 w-[300px] bg-primary/5 animate-pulse rounded mb-2' />
<div class='h-2.5 w-[250px] bg-primary/5 animate-pulse rounded mb-2' />
<div class='my-3 h-1.5 w-[150px] bg-primary/5 animate-pulse rounded' />
<div class='mb-4 h-6 w-[160px] bg-primary/5 animate-pulse rounded' />
<div class='mb-3' />
</div>

View file

@ -0,0 +1,32 @@
<script lang='ts'>
import type { Media } from '$lib/modules/anilist'
import { Bookmark } from '$lib/components/icons/animated'
import { Button, iconSizes, type Props } from '$lib/components/ui/button'
import { list, authAggregator, lists } from '$lib/modules/auth'
import { clickwrap, keywrap } from '$lib/modules/navigate'
import { cn } from '$lib/utils'
type $$Props = Props & { media: Media }
let className: $$Props['class'] = ''
export { className as class }
export let media: Media
export let size: NonNullable<$$Props['size']> = 'icon-sm'
export let variant: NonNullable<$$Props['variant']> = 'ghost'
async function toggleBookmark () {
if (!list(media)) {
await authAggregator.entry({ id: media.id, status: 'PLANNING', lists: lists(media)?.filter(({ enabled }) => enabled).map(({ name }) => name) })
} else {
await authAggregator.delete(media)
}
++key
}
let key = 1
</script>
<Button {size} {variant} class={cn(className, 'animated-icon')} on:click={clickwrap(toggleBookmark)} on:keydown={keywrap(toggleBookmark)}>
<Bookmark fill={key && list(media) ? 'currentColor' : 'transparent'} size={iconSizes[size]} />
</Button>

View file

@ -0,0 +1,26 @@
<script lang='ts'>
import { Button as ButtonPrimitive } from 'bits-ui'
import { type Props, buttonVariants } from './index.js'
import { cn } from '$lib/utils.js'
type $$Props = Props
let className: $$Props['class'] = ''
export let variant: $$Props['variant'] = 'default'
export let size: $$Props['size'] = 'default'
export let builders: $$Props['builders'] = []
export { className as class }
</script>
<ButtonPrimitive.Root
{builders}
class={cn(buttonVariants({ variant, size, className }))}
type='button'
{...$$restProps}
on:click
on:pointerdown
on:keydown>
<slot />
</ButtonPrimitive.Root>

View file

@ -0,0 +1,11 @@
import Bookmark from './bookmark.svelte'
import Favorite from './favorite.svelte'
import Play from './play.svelte'
import Transition from './transition.svelte'
export {
Play as PlayButton,
Favorite as FavoriteButton,
Bookmark as BookmarkButton,
Transition as TransitionButton
}

View file

@ -0,0 +1,28 @@
<script lang='ts'>
import type { Media } from '$lib/modules/anilist'
import { Heart } from '$lib/components/icons/animated'
import { Button, iconSizes, type Props } from '$lib/components/ui/button'
import { authAggregator, fav } from '$lib/modules/auth'
import { clickwrap, keywrap } from '$lib/modules/navigate'
import { cn } from '$lib/utils'
type $$Props = Props & { media: Media }
let className: $$Props['class'] = ''
export { className as class }
export let media: Media
export let size: NonNullable<$$Props['size']> = 'icon-sm'
export let variant: NonNullable<$$Props['variant']> = 'ghost'
let key = 1
async function toggleFav () {
await authAggregator.toggleFav(media.id)
++key
}
</script>
<Button {size} {variant} class={cn(className, 'animated-icon')} on:click={clickwrap(toggleFav)} on:keydown={keywrap(toggleFav)} on:click={() => ++key}>
<Heart fill={key && fav(media) ? 'currentColor' : 'transparent'} size={iconSizes[size]} />
</Button>

View file

@ -0,0 +1,61 @@
import { type VariantProps, tv } from 'tailwind-variants'
import Root from './button.svelte'
import type { Button as ButtonPrimitive } from 'bits-ui'
const buttonVariants = tv({
base: 'bg-transparent focus-visible:ring-ring inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50',
variants: {
variant: {
default: 'bg-primary text-primary-foreground select:bg-neutral-500 shadow',
destructive: 'bg-destructive text-destructive-foreground select:bg-destructive/90 shadow-sm',
outline: 'border-input bg-background select:bg-accent select:text-accent-foreground border shadow-sm',
secondary: 'bg-secondary text-secondary-foreground select:bg-secondary/70 shadow-sm',
ghost: 'select:bg-secondary-foreground/30 select:text-accent-foreground',
link: 'text-primary underline-offset-4 select:underline'
},
size: {
default: 'h-9 px-4 py-2',
sm: 'h-8 rounded-md px-3 text-xs',
xs: 'h-[1.6rem] rounded-sm px-2 text-xs',
lg: 'h-10 rounded-md px-8',
icon: 'h-9 w-9',
'icon-sm': 'h-[1.6rem] w-[1.6rem] rounded-sm text-xs'
}
},
defaultVariants: {
variant: 'default',
size: 'default'
}
})
const iconSizes = {
xs: '0.6rem',
sm: '0.7rem',
default: '0.8rem',
lg: '1.2rem',
icon: '1rem',
'icon-sm': '0.7rem'
}
type Variant = VariantProps<typeof buttonVariants>['variant']
type Size = VariantProps<typeof buttonVariants>['size']
type Props = ButtonPrimitive.Props & {
variant?: Variant
size?: Size
}
type Events = ButtonPrimitive.Events
export {
Root,
type Props,
type Events,
Root as Button,
type Props as ButtonProps,
type Events as ButtonEvents,
buttonVariants,
iconSizes
}

View file

@ -0,0 +1,35 @@
<script lang='ts'>
import Play from 'lucide-svelte/icons/play'
import { playEp } from '../player/mediahandler.svelte'
import type { Media } from '$lib/modules/anilist'
import { Button, iconSizes, type Props } from '$lib/components/ui/button'
import { list, progress } from '$lib/modules/auth'
import { clickwrap, keywrap } from '$lib/modules/navigate'
import { cn } from '$lib/utils'
type $$Props = Props & { media: Media }
let className: $$Props['class'] = ''
export { className as class }
export let media: Media
export let size: NonNullable<$$Props['size']> = 'xs'
function play () {
const episode = (progress(media) ?? 0) + 1
$playEp(media, episode)
}
</script>
<Button class={cn(className, 'font-bold flex items-center justify-center')} {size} on:click={clickwrap(play)} on:keydown={keywrap(play)}>
<Play fill='currentColor' class='mr-2' size={iconSizes[size]} />
{@const status = list(media)}
{#if status === 'COMPLETED'}
Rewatch
{:else if status === 'CURRENT' || status === 'REPEATING' || status === 'PAUSED'}
Continue
{:else}
Watch Now
{/if}
</Button>

View file

@ -0,0 +1,61 @@
<script lang='ts'>
import { Button as ButtonPrimitive } from 'bits-ui'
import { type Props, buttonVariants } from './index.js'
import { cn } from '$lib/utils.js'
type $$Props = Props & { duration?: number, autoStart?: boolean, onclick: () => void, animating?: boolean }
export let duration = 5000 // timeout duration in ms
export let autoStart = false
export let variant: Props['variant'] = 'default'
export let size: NonNullable<$$Props['size']> = 'xs'
export let onclick: () => void
let className: $$Props['class'] = ''
export { className as class }
export let animating = false
function startAnimation () {
animating = true
}
function stopAnimation () {
animating = false
}
if (autoStart) startAnimation()
function handleAnimationEnd () {
animating = false
onclick()
}
</script>
<ButtonPrimitive.Root
class={cn(
'relative overflow-hidden',
buttonVariants({ variant, size, className })
)}
type='button'
on:click={stopAnimation}
on:click={onclick}>
<slot />
<div
class='absolute inset-0 bg-black/20 pointer-events-none translate-x-full'
class:animate-progress={animating}
style='animation-duration: {duration}ms;'
on:animationend={handleAnimationEnd} />
</ButtonPrimitive.Root>
<style>
@keyframes progressBar {
from { transform: translateX(0%); }
to { transform: translateX(100%); }
}
.animate-progress {
animation: progressBar linear forwards;
}
</style>

View file

@ -0,0 +1,39 @@
<script lang='ts'>
import { Button, type Props } from '$lib/components/ui/button'
import { clickwrap, keywrap } from '$lib/modules/navigate'
import { cn, scaleBlurFade } from '$lib/utils'
type $$Props = Props & { duration?: number }
export let duration: $$Props['duration'] = 300
let className: $$Props['class'] = ''
export { className as class }
let toggled = false
let timeout: ReturnType<typeof setTimeout>
export let size: NonNullable<$$Props['size']> = 'icon-sm'
export let variant: NonNullable<$$Props['variant']> = 'ghost'
function handleClick () {
if (toggled) return
toggled = true
clearTimeout(timeout)
timeout = setTimeout(() => {
toggled = false
}, duration! + 500)
}
</script>
<Button {size} {variant} class={cn(className, 'relative')} on:click={clickwrap(handleClick)} on:click on:keydown={keywrap(handleClick)}>
{#if toggled}
<div class='absolute inset-0 flex items-center justify-center' transition:scaleBlurFade={{ duration }}>
<slot name='transition' />
</div>
{:else}
<div class='absolute inset-0 flex items-center justify-center' transition:scaleBlurFade={{ duration }}>
<slot name='base' />
</div>
{/if}
</Button>

View file

@ -0,0 +1,110 @@
<script lang='ts'>
import Volume2 from 'lucide-svelte/icons/volume-2'
import VolumeX from 'lucide-svelte/icons/volume-x'
import { createEventDispatcher, onDestroy } from 'svelte'
import { click } from '$lib/modules/navigate'
export let id: string
const dispatch = createEventDispatcher<{hide: boolean}>()
function ytMessage (e: MessageEvent) {
if (e.origin !== 'https://www.youtube-nocookie.com') return
clearInterval(timeout)
const json = JSON.parse(e.data as string) as { event: string, info: {videoData: {isPlayable: boolean}, playerState?: number} }
if (json.event === 'onReady') ytCall('setVolume', '[30]')
if (json.event === 'initialDelivery' && !json.info.videoData.isPlayable) {
dispatch('hide', true)
}
if (json.event === 'infoDelivery' && json.info.playerState === 1) {
hide = false
dispatch('hide', false)
}
}
let muted = true
function toggleMute () {
if (muted) {
ytCall('unMute')
} else {
ytCall('mute')
}
muted = !muted
}
let hide = true
let frame: HTMLIFrameElement
function ytCall (action: string, arg: string | null = null) {
frame.contentWindow?.postMessage('{"event":"command", "func":"' + action + '", "args":' + arg + '}', '*')
}
let timeout: ReturnType<typeof setInterval>
function initFrame () {
timeout = setInterval(() => {
frame.contentWindow?.postMessage('{"event":"listening","id":1,"channel":"widget"}', '*')
}, 100)
frame.contentWindow?.postMessage('{"event":"listening","id":1,"channel":"widget"}', '*')
}
onDestroy(() => {
clearInterval(timeout)
})
</script>
<svelte:window on:message={ytMessage} />
<!-- indivious is nice because its faster, but not reliable -->
<!-- <video src={`https://inv.tux.pizza/latest_version?id=${media.trailer.id}&itag=18`}
class='w-full h-full position-absolute left-0'
class:d-none={hide}
playsinline
preload='none'
loop
use:volume
bind:muted
on:loadeddata={() => { hide = false }}
autoplay /> -->
<div class='h-full w-full overflow-clip absolute top-0 rounded-t'>
<div class='absolute z-10 top-0 right-0 p-3' class:hide use:click={toggleMute}>
{#if muted}
<VolumeX size='1rem' fill='currentColor' class='pointer-events-none' />
{:else}
<Volume2 size='1rem' fill='currentColor' class='pointer-events-none' />
{/if}
</div>
<iframe
class='w-full border-0 absolute left-0 h-[calc(100%+200px)] top-1/2 transform-gpu -translate-y-1/2 pointer-events-none'
class:hide
title='trailer'
allow='autoplay'
allowfullscreen
bind:this={frame}
on:load={initFrame}
src='https://www.youtube-nocookie.com/embed/{id}?enablejsapi=1&autoplay=1&controls=0&mute=1&disablekb=1&loop=1&playlist={id}&cc_lang_pref=ja'
/>
</div>
<div class='h-full w-full overflow-clip absolute top-0 rounded-t blur-2xl saturate-200 -z-10 pointer-events-none'>
<iframe
class='w-full border-0 absolute left-0 h-[calc(100%+200px)] top-1/2 transform-gpu -translate-y-1/2'
class:hide
title='trailer'
allow='autoplay'
allowfullscreen
src='https://www.youtube-nocookie.com/embed/{id}?autoplay=1&controls=0&mute=1&disablekb=1&loop=1&playlist={id}&cc_lang_pref=ja'
/>
</div>
<style>
.absolute {
transition: opacity 0.3s;
}
.absolute.hide {
opacity: 0;
}
</style>

View file

@ -0,0 +1,77 @@
<script lang='ts'>
import CalendarDays from 'lucide-svelte/icons/calendar-days'
import Tv from 'lucide-svelte/icons/tv'
import StatusDot from '../../StatusDot.svelte'
import { Load } from '../img'
import PreviewCard from './preview.svelte'
import type { Media } from '$lib/modules/anilist/types'
import type { TraceAnime } from '$lib/utils'
import { goto } from '$app/navigation'
import { coverMedium, format, title } from '$lib/modules/anilist/util'
import { list } from '$lib/modules/auth'
import { hover } from '$lib/modules/navigate'
export let media: Media
export let trace: TraceAnime | undefined
let hidden = true
function onclick () {
goto(`/app/anime/${media.id}`)
}
function onhover (state: boolean) {
hidden = !state
}
$: status = list(media)
</script>
<div class='text-white p-4 cursor-pointer shrink-0 relative pointer-events-auto' class:z-40={!hidden} use:hover={[onclick, onhover]}>
{#if !hidden}
<PreviewCard {media} {trace} />
{/if}
<div class='item w-[16rem] flex flex-col'>
<div class='h-[9rem]'>
<Load src={trace?.image ?? coverMedium(media)} alt='cover' class='object-cover w-full h-full rounded' color={media.coverImage?.color} />
</div>
<div class='flex justify-between pt-3 gap-2'>
<div class='font-black text-[.8rem] line-clamp-2'>
{#if status}
<StatusDot variant={status} />
{/if}
{title(media)}
</div>
{#if trace}
<div class='text-xs font-medium flex-shrink-0 text-right'>
<div class='pt-[1px]'>
Episode {trace.episode}
</div>
<div class='text-neutral-500 mt-0.5'>
{Math.round(trace.similarity * 100)}%
</div>
</div>
{/if}
</div>
<div class='flex text-neutral-500 mt-auto pt-2 justify-between'>
<div class='flex text-xs font-medium'>
<CalendarDays class='w-[1rem] h-[1rem] mr-1 -ml-0.5' />
{media.seasonYear ?? 'TBA'}
</div>
<div class='flex text-xs font-medium'>
{format(media)}
<Tv class='w-[1rem] h-[1rem] ml-1 -mr-0.5' />
</div>
</div>
</div>
</div>
<style>
.item {
animation: 0.3s ease 0s 1 load-in;
}
</style>

View file

@ -0,0 +1,6 @@
export { default as SmallCard } from './small.svelte'
export { default as SkeletonCard } from './skeleton.svelte'
export { default as SkeletonTraceCard } from './skeletontrace.svelte'
export { default as QueryCard } from './query.svelte'
export { default as EpisodeCard } from './episode.svelte'
export { default as TraceCards } from './trace.svelte'

View file

@ -0,0 +1,94 @@
<script lang='ts'>
import { BookmarkButton, FavoriteButton, PlayButton } from '../button/extra'
import { Banner } from '../img'
import Load from '../img/load.svelte'
import YoutubeIframe from './YoutubeIframe.svelte'
import Videoframe from './videoframe.svelte'
import { desc, duration, format, season, title, type Media } from '$lib/modules/anilist'
import { of } from '$lib/modules/auth'
import { SUPPORTS } from '$lib/modules/settings'
import { cn, type TraceAnime } from '$lib/utils'
export let media: Media
export let trace: TraceAnime | undefined = undefined
let hideFrame: boolean | null = null
function hide (e: CustomEvent<boolean>) {
hideFrame = e.detail
}
</script>
<div class='!absolute w-[17.5rem] h-80 left-1/2 right-1/2 top-0 bottom-0 m-auto bg-neutral-950 z-30 rounded cursor-pointer absolute-container'>
<div class='h-[45%] banner relative bg-black rounded-t'>
{#if trace}
{#if !SUPPORTS.isUnderPowered}
<Load src={trace.image} alt={media.title?.english} class={cn('object-cover w-full h-full blur-2xl saturate-200 absolute -z-10', hideFrame === false && 'hidden')} />
{/if}
<Load src={trace.image} alt={media.title?.english} class='object-cover w-full h-full rounded-t' />
<Videoframe src={trace.video} on:hide={hide} />
{:else}
{#if !SUPPORTS.isUnderPowered}
<Banner {media} class={cn('object-cover w-full h-full blur-2xl saturate-200 absolute -z-10', hideFrame === false && 'hidden')} />
{/if}
<Banner {media} class='object-cover w-full h-full rounded-t' />
{#if media.trailer?.id && !hideFrame && !SUPPORTS.isUnderPowered}
<YoutubeIframe id={media.trailer.id} on:hide={hide} />
{/if}
{/if}
</div>
<div class='w-full px-4 bg-neutral-950'>
<div class='text-lg font-bold truncate inline-block w-full text-white pt-2' title={title(media)}>
{title(media)}
</div>
<div class='flex flex-row'>
<PlayButton {media} class='grow' />
<FavoriteButton {media} class='ml-2' />
<BookmarkButton {media} class='ml-2' />
</div>
<div class='details text-white capitalize pt-3 pb-2 flex text-[11px] overflow-clip text-ellipsis text-nowrap'>
<span class='text-nowrap flex items-center'>
{format(media)}
</span>
<span class='text-nowrap flex items-center'>
{of(media) ?? duration(media) ?? 'N/A' }
</span>
<span class='text-nowrap flex items-center'>
{season(media)}
</span>
{#if media.averageScore}
<span class='text-nowrap flex items-center text-ellipsis'>
{media.averageScore}%
</span>
{/if}
</div>
<div class='w-full h-full overflow-clip text-[.7rem] text-muted-foreground line-clamp-4'>
{desc(media)}
</div>
</div>
</div>
<style>
.banner::after {
content: '';
position: absolute;
left: 0 ; bottom: 0;
/* when clicking, translate fucks up the position, and video might leak down 1 or 2 pixels, stickig under the gradient, look bad */
margin-bottom: -2px;
width: 100%; height: 100% ;
background: linear-gradient(180deg, #0000 0%, #0a0a0a00 80%, #0a0a0ae3 95%, #0a0a0a 100%);
}
.absolute-container {
animation: 0.3s ease 0s 1 load-in;
transform: translate3d(-50%, 0, 0) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(1) scaleY(1);
opacity: 1;
}
@keyframes load-in {
from {
opacity: 0;
transform: translate3d(-50%, 1.2rem, 0) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(0.95) scaleY(0.95);
}
}
</style>

View file

@ -0,0 +1,71 @@
<script lang='ts'>
import type { client } from '$lib/modules/anilist'
import { SkeletonCard, SmallCard } from '$lib/components/ui/cards'
export let query: ReturnType<typeof client.search>
$: paused = query.isPaused$
function deferredLoad (element: HTMLDivElement) {
const observer = new IntersectionObserver(([entry]) => {
if (entry?.isIntersecting) {
query.resume()
observer.unobserve(element)
}
}, { threshold: 0 })
observer.observe(element)
return { destroy () { observer.unobserve(element) } }
}
</script>
{#if $paused}
<div class='w-0 h-0' use:deferredLoad />
{/if}
{#if $query.fetching}
{#each Array.from({ length: 50 }) as _, i (i)}
<SkeletonCard />
{/each}
{:else if $query.error}
<div class='p-5 flex items-center justify-center w-full h-80'>
<div>
<div class='mb-1 font-bold text-4xl text-center '>
Ooops!
</div>
<div class='text-lg text-center text-muted-foreground'>
Looks like something went wrong!
</div>
<div class='text-lg text-center text-muted-foreground'>
{$query.error.message}
</div>
</div>
</div>
{:else if $query.data}
{#if $query.data.Page?.media}
{#each $query.data.Page.media as media, i (media?.id ?? '#' + i)}
{#if media}
<SmallCard {media} />
{/if}
{:else}
<div class='p-5 flex items-center justify-center w-full h-80'>
<div>
<div class='mb-1 font-bold text-4xl text-center '>
Ooops!
</div>
<div class='text-lg text-center text-muted-foreground'>
Looks like there's nothing here.
</div>
</div>
</div>
{/each}
{:else}
{#each Array.from({ length: 50 }) as _, i (i)}
<SkeletonCard />
{/each}
{/if}
{:else}
{#each Array.from({ length: 50 }) as _, i (i)}
<SkeletonCard animate={false} />
{/each}
{/if}

View file

@ -0,0 +1,18 @@
<script lang='ts'>
export let animate = true
</script>
<div class='p-4 shrink-0'>
<div class='item w-[9.5rem] flex flex-col'>
<div class='h-[13.5rem] w-full bg-primary/5 rounded' class:animate-pulse={animate} />
<div class='mt-4 bg-primary/5 rounded h-2 w-28' class:animate-pulse={animate} />
<div class='mt-2 bg-primary/5 rounded h-2 w-20' class:animate-pulse={animate} />
</div>
</div>
<style>
.item {
animation: 0.3s ease 0s 1 load-in;
aspect-ratio: 152/290;
}
</style>

View file

@ -0,0 +1,17 @@
<script lang='ts'>
export let animate = true
</script>
<div class='p-4 shrink-0'>
<div class='item w-[16rem] flex flex-col'>
<div class='h-[9rem] w-full bg-primary/5 rounded' class:animate-pulse={animate} />
<div class='mt-4 bg-primary/5 rounded h-2 w-28' class:animate-pulse={animate} />
<div class='mt-2 bg-primary/5 rounded h-2 w-20' class:animate-pulse={animate} />
</div>
</div>
<style>
.item {
animation: 0.3s ease 0s 1 load-in;
}
</style>

Some files were not shown because too many files have changed in this diff Show more