mirror of
https://github.com/ThaUnknown/miru.git
synced 2026-04-21 01:12:07 +00:00
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
This commit is contained in:
parent
1aecac107b
commit
f19dbdb400
7 changed files with 99 additions and 78 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Miru",
|
||||
"version": "3.9.2",
|
||||
"version": "3.9.3",
|
||||
"author": "ThaUnknown_ <ThaUnknown@users.noreply.github.com>",
|
||||
"description": "Stream anime torrents, real-time with no waiting for downloads.",
|
||||
"main": "src/index.js",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,15 @@
|
|||
}
|
||||
export let length = 5
|
||||
export let tabable = false
|
||||
|
||||
const statusColorMap = {
|
||||
CURRENT: 'rgb(61,180,242)',
|
||||
PLANNING: 'rgb(247,154,99)',
|
||||
COMPLETED: 'rgb(123,213,85)',
|
||||
PAUSED: 'rgb(250,122,122)',
|
||||
REPEAT: '#3baeea',
|
||||
DROPPED: 'rgb(232,93,117)'
|
||||
}
|
||||
</script>
|
||||
|
||||
{#await cards}
|
||||
|
|
@ -52,6 +61,9 @@
|
|||
<div class='col-8 h-full card-grid'>
|
||||
<div class='px-15 py-10 bg-very-dark'>
|
||||
<h5 class='m-0 text-capitalize font-weight-bold'>
|
||||
{#if card.media.mediaListEntry?.status}
|
||||
<div style:--statusColor={statusColorMap[card.media.mediaListEntry.status]} class='list-status-circle d-inline-flex overflow-hidden mr-5' title={card.media.mediaListEntry.status} />
|
||||
{/if}
|
||||
{#if card.failed}
|
||||
<span class='badge badge-secondary'>Uncertain</span>
|
||||
{/if}
|
||||
|
|
@ -86,11 +98,13 @@
|
|||
<div class='overflow-y-auto px-15 pb-5 bg-very-dark card-desc pre-wrap'>
|
||||
{card.media.description?.replace(/<[^>]*>/g, '') || ''}
|
||||
</div>
|
||||
<div class='px-15 pb-10 pt-5 genres'>
|
||||
{#each card.media.genres as genre}
|
||||
<span class='badge badge-pill badge-color text-dark mt-5 mr-5 font-weight-bold'>{genre}</span>
|
||||
{/each}
|
||||
</div>
|
||||
{#if card.media.genres.length}
|
||||
<div class='px-15 pb-10 pt-5 genres'>
|
||||
{#each card.media.genres.slice(0, 3) as genre}
|
||||
<span class='badge badge-pill badge-color text-dark mt-5 mr-5 font-weight-bold'>{genre}</span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -185,4 +199,10 @@
|
|||
.day-row {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.list-status-circle {
|
||||
background: var(--statusColor);
|
||||
height: 1.1rem;
|
||||
width: 1.1rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -359,32 +359,31 @@
|
|||
</script>
|
||||
|
||||
<div class='d-flex h-full flex-column overflow-y-scroll root' on:scroll={infiniteScroll} bind:this={container}>
|
||||
<div class='h-full py-10'>
|
||||
<Search bind:media bind:search={$search} bind:current {loadCurrent} />
|
||||
{#if media.length}
|
||||
<Gallery {media} />
|
||||
{:else}
|
||||
<div class='container'>
|
||||
{#if $progress < 30}
|
||||
We're ${30 - $progress} short of our monthly goal! That's only {Math.ceil((30 - $progress) / 5)} people donating $5.00!
|
||||
{:else}
|
||||
We've reached the donation goal for this month! \o/
|
||||
{/if}
|
||||
<div class='progress-group py-5'>
|
||||
<div class='progress'>
|
||||
<div class='progress-bar progress-bar-animated' role='progressbar' style='width: {$progress / 30 * 100}%;' />
|
||||
</div>
|
||||
<span class='progress-group-label'>${$progress} / $30.00</span>
|
||||
<Search bind:media bind:search={$search} bind:current {loadCurrent} />
|
||||
<hr />
|
||||
{#if media.length}
|
||||
<Gallery {media} />
|
||||
{:else}
|
||||
<div class='container'>
|
||||
{#if $progress < 30}
|
||||
We're ${30 - $progress} short of our monthly goal! That's only {Math.ceil((30 - $progress) / 5)} people donating $5.00!
|
||||
{:else}
|
||||
We've reached the donation goal for this month! \o/
|
||||
{/if}
|
||||
<div class='progress-group py-5'>
|
||||
<div class='progress'>
|
||||
<div class='progress-bar progress-bar-animated' role='progressbar' style='width: {$progress / 30 * 100}%;' />
|
||||
</div>
|
||||
<button class='btn btn-primary' type='button' on:click={() => { window.IPC.emit('open', 'https://github.com/sponsors/ThaUnknown/') }}>Donate</button>
|
||||
<span class='progress-group-label'>${$progress} / $30.00</span>
|
||||
</div>
|
||||
<div>
|
||||
{#each Object.entries(sections) as [key, opts] (key)}
|
||||
{#if !opts.hide}
|
||||
<Section opts={{ ...opts, onclick: () => (current = key) }} />
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<button class='btn btn-primary' type='button' on:click={() => { window.IPC.emit('open', 'https://github.com/sponsors/ThaUnknown/') }}>Donate</button>
|
||||
</div>
|
||||
<div>
|
||||
{#each Object.entries(sections) as [key, opts] (key)}
|
||||
{#if !opts.hide}
|
||||
<Section opts={{ ...opts, onclick: () => (current = key) }} />
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<div class='container-fluid row p-20' on:input={input}>
|
||||
<div class='container-fluid row p-20 position-sticky top-0 search-container z-40' on:input={input}>
|
||||
<div class='col-lg col-4 p-10 d-flex flex-column justify-content-end'>
|
||||
<div class='pb-10 font-size-24 font-weight-semi-bold d-flex'>
|
||||
<div class='material-icons mr-10 font-size-30'>title</div>
|
||||
|
|
@ -217,4 +217,7 @@
|
|||
.font-size-30 {
|
||||
font-size: 3rem !important;
|
||||
}
|
||||
.search-container {
|
||||
background: var(--dm-base-body-bg-color);;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -215,6 +215,8 @@
|
|||
|
||||
[data-toggle='tooltip']:not([data-target-breakpoint])::before,
|
||||
[data-toggle='tooltip']:not([data-target-breakpoint])::before {
|
||||
visibility: visible !important;
|
||||
pointer-events: none;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
transition: opacity 0.3s cubic-bezier(0.25, 0.8, 0.25, 1), top 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
|
|
@ -224,8 +226,7 @@
|
|||
box-shadow: var(--dm-shadow) !important;
|
||||
}
|
||||
|
||||
[data-toggle='tooltip']:not([data-target-breakpoint]):hover::before,
|
||||
[data-toggle='tooltip']:not([data-target-breakpoint]):focus::before {
|
||||
[data-toggle='tooltip']:not([data-target-breakpoint]):hover::before {
|
||||
opacity: 1;
|
||||
top: 50%;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@
|
|||
export let title = 'Relations'
|
||||
</script>
|
||||
{#if list?.length}
|
||||
<span class='d-flex align-items-end pointer text-decoration-none mt-20 pt-20' on:click={toggleList}>
|
||||
<span class='d-flex align-items-end pointer text-decoration-none pt-20' on:click={toggleList}>
|
||||
<h1 class='font-weight-bold text-white'>{title}</h1>
|
||||
{#if list.length > 4}
|
||||
<h6 class='ml-auto font-size-12 more text-muted'>{showMore ? 'Show Less' : 'Show More'}</h6>
|
||||
{/if}
|
||||
</span>
|
||||
<div class='d-flex text-capitalize flex-wrap pt-20 justify-center'>
|
||||
<div class='d-flex text-capitalize flex-wrap card m-0'>
|
||||
{#each list.slice(0, showMore ? 100 : 4) as item}
|
||||
<slot {item} />
|
||||
{/each}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@
|
|||
<div class='col-md-3 col-4 d-flex h-full justify-content-end flex-column pb-15 align-items-center'>
|
||||
<img class='contain-img rounded mw-full mh-full shadow' alt='cover' src={media.coverImage?.extraLarge || media.coverImage?.medium} />
|
||||
</div>
|
||||
<div class='col-md-9 col-8 row align-content-end pl-20'>
|
||||
<div class='col-md-8 col-12 d-flex justify-content-end flex-column'>
|
||||
<div class='col-md-9 col-8 row align-content-end'>
|
||||
<div class='col-md-8 col-12 d-flex justify-content-end flex-column pl-20'>
|
||||
<div class='px-md-20 d-flex flex-column font-size-12'>
|
||||
<span class='title font-weight-bold pb-sm-15 text-white select-all'>
|
||||
{media.title.userPreferred}
|
||||
|
|
@ -84,59 +84,54 @@
|
|||
</div>
|
||||
<div class='container-xl bg-very-dark z-10'>
|
||||
<div class='row p-20 px-xl-0 flex-column-reverse flex-md-row'>
|
||||
<div class='col-md-9 px-20'>
|
||||
<div class='col-md-9 pr-50'>
|
||||
<h1 class='title font-weight-bold text-white'>Synopsis</h1>
|
||||
<div class='font-size-16 pr-15 pre-wrap select-all'>
|
||||
<div class='font-size-16 pre-wrap select-all card m-0'>
|
||||
{media.description?.replace(/<[^>]*>/g, '') || ''}
|
||||
</div>
|
||||
<ToggleList list={media.relations?.edges?.filter(({ node }) => node.type === 'ANIME')} let:item title='Relations'>
|
||||
<div class='w-150 mx-15 mb-10 rel pointer'
|
||||
<div class='w-150 mx-15 my-10 rel pointer'
|
||||
on:click={async () => { $view = null; $view = (await alRequest({ method: 'SearchIDSingle', id: item.node.id })).data.Media }}
|
||||
on:keydown={wrapEnter(async () => { $view = null; $view = (await alRequest({ method: 'SearchIDSingle', id: item.node.id })).data.Media })}
|
||||
tabindex='0' role='button'
|
||||
>
|
||||
<img loading='lazy' src={item.node.coverImage.medium || ''} alt='cover' class='cover-img w-full h-200 rel-img' />
|
||||
tabindex='0' role='button'>
|
||||
<img loading='lazy' src={item.node.coverImage.medium || ''} alt='cover' class='cover-img w-full h-200 rel-img rounded' />
|
||||
<div class='pt-5'>{item.relationType.replace(/_/g, ' ').toLowerCase()}</div>
|
||||
<h5 class='font-weight-bold text-white'>{item.node.title.userPreferred}</h5>
|
||||
<h5 class='font-weight-bold text-white mb-5'>{item.node.title.userPreferred}</h5>
|
||||
</div>
|
||||
</ToggleList>
|
||||
{#if maxPlayEp}
|
||||
<table class='table table-hover w-500 table-auto'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='px-0'><h2 class='title font-weight-bold text-white pt-20 mb-5'>Episodes</h2></th>
|
||||
<th />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each Array(maxPlayEp) as _, i}
|
||||
{@const ep = maxPlayEp - i}
|
||||
<tr class="font-size-20 py-10 pointer {ep <= media.mediaListEntry?.progress ? 'text-muted' : 'text-white'}"
|
||||
on:click={() => {
|
||||
playAnime(media, ep)
|
||||
close()
|
||||
}}
|
||||
on:keydown={wrapEnter(() => {
|
||||
playAnime(media, ep)
|
||||
close()
|
||||
})}
|
||||
tabindex='0' role='button'
|
||||
>
|
||||
<td class='w-full font-weight-semi-bold'>Episode {ep}</td>
|
||||
<td class='material-icons text-right h-full d-table-cell'>play_arrow</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<h1 class='title font-weight-bold text-white pt-20'>Episodes</h1>
|
||||
<div class='card m-0 d-inline-block'>
|
||||
<table class='table table-hover w-500 table-auto '>
|
||||
<tbody>
|
||||
{#each Array(maxPlayEp) as _, i}
|
||||
{@const ep = maxPlayEp - i}
|
||||
<tr class="font-size-20 py-10 pointer {ep <= media.mediaListEntry?.progress ? 'text-muted' : 'text-white'}"
|
||||
on:click={() => {
|
||||
playAnime(media, ep)
|
||||
close()
|
||||
}}
|
||||
on:keydown={wrapEnter(() => {
|
||||
playAnime(media, ep)
|
||||
close()
|
||||
})}
|
||||
tabindex='0' role='button'
|
||||
>
|
||||
<td class='w-full font-weight-semi-bold'>Episode {ep}</td>
|
||||
<td class='material-icons text-right h-full d-table-cell'>play_arrow</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
<ToggleList list={media.recommendations.edges.filter(edge => edge.node.mediaRecommendation)} let:item title='Recommendations'>
|
||||
<div class='w-150 mx-15 mb-10 rel pointer'
|
||||
<div class='w-150 mx-15 my-10 rel pointer'
|
||||
on:click={async () => { $view = null; $view = (await alRequest({ method: 'SearchIDSingle', id: item.node.mediaRecommendation.id })).data.Media }}
|
||||
on:keydown={wrapEnter(async () => { $view = null; $view = (await alRequest({ method: 'SearchIDSingle', id: item.node.mediaRecommendation.id })).data.Media })}
|
||||
tabindex='0' role='button'
|
||||
>
|
||||
<img loading='lazy' src={item.node.mediaRecommendation.coverImage.medium || ''} alt='cover' class='cover-img w-full h-200 rel-img' />
|
||||
<h5 class='font-weight-bold text-white'>{item.node.mediaRecommendation.title.userPreferred}</h5>
|
||||
tabindex='0' role='button'>
|
||||
<img loading='lazy' src={item.node.mediaRecommendation.coverImage.medium || ''} alt='cover' class='cover-img w-full h-200 rel-img rounded' />
|
||||
<h5 class='font-weight-bold text-white mb-5'>{item.node.mediaRecommendation.title.userPreferred}</h5>
|
||||
</div>
|
||||
</ToggleList>
|
||||
</div>
|
||||
|
|
@ -170,6 +165,9 @@
|
|||
.title {
|
||||
font-size: 4rem;
|
||||
}
|
||||
.pr-50 {
|
||||
padding-right: 5rem;
|
||||
}
|
||||
.close {
|
||||
top: 1rem !important;
|
||||
left: unset !important;
|
||||
|
|
|
|||
Loading…
Reference in a new issue