From 02bf9a9d6012452ba36aeca4e97fdd7c3a91b16b Mon Sep 17 00:00:00 2001 From: ThaUnknown <6506529+ThaUnknown@users.noreply.github.com> Date: Fri, 15 Jul 2022 00:59:47 +0200 Subject: [PATCH] feat: viewAnime improvements --- package.json | 4 +- src/renderer/src/lib/Sidebar.svelte | 2 +- src/renderer/src/lib/Toasts.svelte | 2 +- src/renderer/src/lib/ViewAnime.svelte | 309 +++--------------- .../src/lib/ViewAnime/Controls.svelte | 164 ++++++++++ src/renderer/src/lib/ViewAnime/Details.svelte | 73 +++++ .../src/lib/ViewAnime/Following.svelte | 54 +++ .../src/lib/ViewAnime/ToggleList.svelte | 24 ++ src/renderer/src/modules/anilist.js | 2 +- 9 files changed, 357 insertions(+), 277 deletions(-) create mode 100644 src/renderer/src/lib/ViewAnime/Controls.svelte create mode 100644 src/renderer/src/lib/ViewAnime/Details.svelte create mode 100644 src/renderer/src/lib/ViewAnime/Following.svelte create mode 100644 src/renderer/src/lib/ViewAnime/ToggleList.svelte diff --git a/package.json b/package.json index 023fd20..9f81d81 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Miru", - "version": "2.9.5", + "version": "2.9.6", "author": "ThaUnknown_ ", "main": "src/index.js", "homepage": "https://github.com/ThaUnknown/miru#readme", @@ -122,7 +122,7 @@ "matroska-subtitles": "github:ThaUnknown/matroska-subtitles#patch", "mime": "^3.0.0", "pump": "^3.0.0", - "quartermoon": "^1.2.0", + "quartermoon": "^1.2.1", "range-parser": "^1.2.1", "svelte-keybinds": "^1.0.4", "svelte-miniplayer": "^1.0.2", diff --git a/src/renderer/src/lib/Sidebar.svelte b/src/renderer/src/lib/Sidebar.svelte index 1aa63e2..9f28239 100644 --- a/src/renderer/src/lib/Sidebar.svelte +++ b/src/renderer/src/lib/Sidebar.svelte @@ -61,7 +61,7 @@ location.hash = '' location.reload() } else { - window.IPC.emit('open', 'https://anilist.co/api/v2/oauth/authorize?client_id=4254&response_type=token') //Change redirect_url to miru://auth + window.IPC.emit('open', 'https://anilist.co/api/v2/oauth/authorize?client_id=4254&response_type=token') // Change redirect_url to miru://auth if (platformMap[window.version.platform] === 'Linux') { addToast({ text: "If your linux distribution doesn't support custom protocol handlers, you can simply paste the full URL into the app.", diff --git a/src/renderer/src/lib/Toasts.svelte b/src/renderer/src/lib/Toasts.svelte index 11b6c62..14fd46c 100644 --- a/src/renderer/src/lib/Toasts.svelte +++ b/src/renderer/src/lib/Toasts.svelte @@ -37,7 +37,7 @@ .alert { display: block !important; animation: 0.3s ease 0s 1 fly-in; - right: 0 !important; + right: 0; } @keyframes fly-in { diff --git a/src/renderer/src/lib/ViewAnime.svelte b/src/renderer/src/lib/ViewAnime.svelte index 0500582..6017fd5 100644 --- a/src/renderer/src/lib/ViewAnime.svelte +++ b/src/renderer/src/lib/ViewAnime.svelte @@ -3,124 +3,24 @@ import { alRequest } from '@/modules/anilist.js' import { getMediaMaxEp } from '@/modules/anime.js' import { getContext } from 'svelte' - import { alToken } from '@/lib/pages/Settings.svelte' - import { countdown } from '@/modules/util.js' - import { addToast } from './Toasts.svelte' + import Details from './ViewAnime/Details.svelte' + import Following from './ViewAnime/Following.svelte' + import Controls from './ViewAnime/Controls.svelte' + import ToggleList from './ViewAnime/ToggleList.svelte' const view = getContext('view') + const trailer = getContext('trailer') function close () { $view = null } - $: console.log(media) $: media = $view let modal $: media && modal?.focus() $: !$trailer && modal?.focus() - let following = null - async function updateFollowing (media) { - if (media) { - following = null - following = (await alRequest({ method: 'Following', id: media.id })).data?.Page?.mediaList - } - } - $: updateFollowing(media) $: maxPlayEp = getMediaMaxEp($view || {}, true) function checkClose ({ keyCode }) { if (keyCode === 27) close() } - const statusMap = { - CURRENT: 'Watching', - PLANNING: 'Planning', - COMPLETED: 'Completed', - DROPPED: 'Dropped', - PAUSED: 'Paused', - REPEATING: 'Re-Watching' - } - const detailsMap = [ - { property: 'episode', label: 'Airing', icon: 'schedule', custom: 'property' }, - { property: 'genres', label: 'Genres', icon: 'theater_comedy' }, - { property: 'season', label: 'Season', icon: 'spa', custom: 'property' }, - { property: 'episodes', label: 'Episodes', icon: 'theaters', custom: 'property' }, - { property: 'duration', label: 'Duration', icon: 'timer', custom: 'property' }, - { property: 'format', label: 'Format', icon: 'monitor' }, - { property: 'status', label: 'Status', icon: 'live_tv' }, - { property: 'nodes', label: 'Studio', icon: 'business' }, - { property: 'source', label: 'Source', icon: 'source' }, - { property: 'averageScore', label: 'Rating', icon: 'trending_up', custom: 'property' }, - { property: 'english', label: 'English', icon: 'title' }, - { property: 'romaji', label: 'Romaji', icon: 'translate' }, - { property: 'native', label: 'Native', icon: '語', custom: 'icon' } - ] - function getCustomProperty (detail, media) { - if (detail.property === 'episodes') { - if (media.mediaListEntry?.progress) { - return `Watched ${media.mediaListEntry.progress} of ${getMediaMaxEp(media)}` - } - return `${getMediaMaxEp(media)} Episodes` - } else if (detail.property === 'averageScore') { - return media.averageScore + '%' - } else if (detail.property === 'duration') { - return `${media.duration} minutes` - } else if (detail.property === 'season') { - return [media.season?.toLowerCase(), media.seasonYear].filter(f => f).join(' ') - } else if (detail.property === 'episode') { - return `Ep ${media.nextAiringEpisode.episode}: ${countdown(media.nextAiringEpisode.timeUntilAiring)}` - } else { - return media[detail.property] - } - } - function getProperty (property, media) { - if (property === 'episode') { - return media.nextAiringEpisode?.episode - } else if (property === 'english' || property === 'romaji' || property === 'native') { - return media.title[property] - } - return media[property] - } - async function addToList (media) { - if (media.mediaListEntry?.status !== 'CURRENT' && media.mediaListEntry?.status !== 'COMPLETED') { - const variables = { - method: media.mediaListEntry?.status !== 'PLANNING' ? 'Entry' : 'Delete', - id: media.mediaListEntry?.status !== 'PLANNING' ? media.id : media.mediaListEntry.id, - status: 'PLANNING' - } - await alRequest(variables) - $view = (await alRequest({ method: 'SearchIDSingle', id: media.id })).data.Media - } - } - async function score (media, score) { - const variables = { - method: 'Entry', - id: media.id, - score: score * 10 - } - await alRequest(variables) - $view = (await alRequest({ method: 'SearchIDSingle', id: media.id })).data.Media - } - const trailer = getContext('trailer') - function viewTrailer (media) { - $trailer = media.trailer.id - } - function copyToClipboard (text) { - navigator.clipboard.writeText(text) - addToast({ - title: 'Copied to clipboard', - text: 'Copied share URL to clipboard', - type: 'primary', - duration: '5000' - }) - } - function openInBrowser (url) { - window.IPC.emit('open', url) - } - let showMoreRelations = false - function toggleRelations () { - showMoreRelations = !showMoreRelations - } - let showMoreRecommendations = false - function toggleRecommendations () { - showMoreRecommendations = !showMoreRecommendations - } -
-
- - {#if alToken} - {#if media.mediaListEntry?.status !== 'CURRENT' && media.mediaListEntry?.status !== 'COMPLETED'} - - {/if} -
-
- hotel_class -
- -
- {/if} - {#if media.trailer} - - {/if} -
- - -
-
-
+ @@ -245,21 +86,13 @@
{@html media.description}
- {#if media.relations?.edges?.filter(({ node }) => node.type === 'ANIME').length} - -

Relations

-
{showMoreRelations ? 'Show Less' : 'Show More'}
-
-
- {#each media.relations?.edges.filter(({ node }) => node.type === 'ANIME').slice(0, showMoreRelations ? 100 : 4) as { relationType, node }} -
{ $view = null; $view = (await alRequest({ method: 'SearchIDSingle', id: node.id })).data.Media }}> - cover -
{relationType.replace(/_/g, ' ').toLowerCase()}
-
{node.title.userPreferred}
-
- {/each} + node.type === 'ANIME')} let:item> +
{ $view = null; $view = (await alRequest({ method: 'SearchIDSingle', id: item.node.id })).data.Media }}> + cover +
{item.relationType.replace(/_/g, ' ').toLowerCase()}
+
{item.node.title.userPreferred}
- {/if} +
{#if maxPlayEp} @@ -283,60 +116,16 @@
{/if} - {#if media.recommendations?.edges?.length} - -

Recommendations

-
{showMoreRecommendations ? 'Show Less' : 'Show More'}
-
-
- {#each media.recommendations.edges.filter(edge => edge.node.mediaRecommendation).slice(0, showMoreRecommendations ? 100 : 4) as { node }} -
{ $view = null; $view = (await alRequest({ method: 'SearchIDSingle', id: node.mediaRecommendation.id })).data.Media }}> - cover -
{node.mediaRecommendation.title.userPreferred}
-
- {/each} + edge.node.mediaRecommendation)} let:item> +
{ $view = null; $view = (await alRequest({ method: 'SearchIDSingle', id: item.node.mediaRecommendation.id })).data.Media }}> + cover +
{item.node.mediaRecommendation.title.userPreferred}
- {/if} +
-

Details

-
- {#each detailsMap as detail} - {@const property = getProperty(detail.property, media)} - {#if property} -
-
- {detail.icon} -
-
-
- {#if detail.custom === 'property'} - {@html getCustomProperty(detail, media)} - {:else if property.constructor === Array} - {property === 'nodes' ? property[0] && property[0].name : property.join(', ').replace(/_/g, ' ').toLowerCase()} - {:else} - {property.toString().replace(/_/g, ' ').toLowerCase()} - {/if} -
-
-
-
- {/if} - {/each} -
- {#if following?.length} -

Following

-
- {#each following as friend} -
- avatar - {friend.user.name} - {statusMap[friend.status]} - window.IPC.emit('open', 'https://anilist.co/user/' + friend.user.name)}> open_in_new -
- {/each} -
- {/if} +
+
@@ -345,34 +134,12 @@ diff --git a/src/renderer/src/lib/ViewAnime/Controls.svelte b/src/renderer/src/lib/ViewAnime/Controls.svelte new file mode 100644 index 0000000..dd8ab24 --- /dev/null +++ b/src/renderer/src/lib/ViewAnime/Controls.svelte @@ -0,0 +1,164 @@ + + +
+
+ + {#if alToken} + +
+
+ hotel_class +
+ +
+ {/if} + {#if media.trailer} + + {/if} +
+ + +
+
+
+ + \ No newline at end of file diff --git a/src/renderer/src/lib/ViewAnime/Details.svelte b/src/renderer/src/lib/ViewAnime/Details.svelte new file mode 100644 index 0000000..638d889 --- /dev/null +++ b/src/renderer/src/lib/ViewAnime/Details.svelte @@ -0,0 +1,73 @@ + + +

Details

+
+ {#each detailsMap as detail} + {@const property = getProperty(detail.property, media)} + {#if property} +
+
+ {detail.icon} +
+
+
+ {#if detail.custom === 'property'} + {@html getCustomProperty(detail, media)} + {:else if property.constructor === Array} + {property === 'nodes' ? property[0] && property[0].name : property.join(', ').replace(/_/g, ' ').toLowerCase()} + {:else} + {property.toString().replace(/_/g, ' ').toLowerCase()} + {/if} +
+
+
+
+ {/if} + {/each} +
\ No newline at end of file diff --git a/src/renderer/src/lib/ViewAnime/Following.svelte b/src/renderer/src/lib/ViewAnime/Following.svelte new file mode 100644 index 0000000..443d75a --- /dev/null +++ b/src/renderer/src/lib/ViewAnime/Following.svelte @@ -0,0 +1,54 @@ + + + +{#if following?.length && alToken} +

Following

+
+ {#each following as friend} +
+ avatar + {friend.user.name} + {statusMap[friend.status]} + window.IPC.emit('open', 'https://anilist.co/user/' + friend.user.name)}> open_in_new +
+ {/each} +
+{/if} + + \ No newline at end of file diff --git a/src/renderer/src/lib/ViewAnime/ToggleList.svelte b/src/renderer/src/lib/ViewAnime/ToggleList.svelte new file mode 100644 index 0000000..02a58c2 --- /dev/null +++ b/src/renderer/src/lib/ViewAnime/ToggleList.svelte @@ -0,0 +1,24 @@ + +{#if list?.length} + +

Relations

+
{showMore ? 'Show Less' : 'Show More'}
+
+
+ {#each list.slice(0, showMore ? 100 : 4) as item} + + {/each} +
+{/if} + + \ No newline at end of file diff --git a/src/renderer/src/modules/anilist.js b/src/renderer/src/modules/anilist.js index a70299d..ac7aa1a 100644 --- a/src/renderer/src/modules/anilist.js +++ b/src/renderer/src/modules/anilist.js @@ -111,7 +111,7 @@ export function alEntry (filemedia) { } if (videoEpisode === mediaEpisode) { variables.status = 'COMPLETED' - if (media.mediaListEntry?.status === 'COMPLETED') variables.repeat = media.mediaListEntry.repeat + 1 + if (media.mediaListEntry?.status === 'COMPLETED' || media.mediaListEntry.status === 'REPEATING') variables.repeat = media.mediaListEntry.repeat + 1 } alRequest(variables) }