feat(poll): prevent submission, when there is no selection (#74)

This commit is contained in:
Ushie 2023-03-03 12:59:48 +03:00 committed by GitHub
parent 7c9c655485
commit 0d6974e00d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 60 deletions

View File

@ -171,11 +171,6 @@
font-weight: 800; font-weight: 800;
} }
h6 {
font-size: 0.9rem;
overflow: hidden;
text-overflow: ellipsis;
}
.text { .text {
width: 100%; width: 100%;
white-space: nowrap; white-space: nowrap;
@ -186,8 +181,7 @@
background-color: var(--accent-low-opacity); background-color: var(--accent-low-opacity);
} }
.clicked h2, .clicked h2 {
.clicked h6 {
color: var(--white); color: var(--white);
} }

View File

@ -9,7 +9,7 @@
import Button from '$lib/components/atoms/Button.svelte'; import Button from '$lib/components/atoms/Button.svelte';
interface Selected { interface Selected {
[key: string] : string[]; [key: string]: string[];
} }
let modalOpen = false; let modalOpen = false;
@ -37,7 +37,10 @@
let max = logoAmount; let max = logoAmount;
let token = ''; let token = '';
let submit = false; let submit = false;
$: finalPage = currentPage >= logoPages; let allowReviewSelections = false;
$: finalPage = false;
$: min = currentPage * logoAmount;
$: max = min + logoAmount;
async function exchange_token(bot_token: string) { async function exchange_token(bot_token: string) {
const response = await fetch('https://poll.revanced.app/auth/exchange', { const response = await fetch('https://poll.revanced.app/auth/exchange', {
@ -105,12 +108,19 @@
}); });
function previousPage() { function previousPage() {
if (currentPage <= 0) return null; if (currentPage <= 0 && !allowReviewSelections) {
if (allowReviewSelections) {
// If the current page is 0 and the user has reached the final page beforehand, go to the final page
currentPage = logoPages - 1;
} else {
// If the current page is 0 and the user has not reached the final page beforehand, return
return;
}
} else {
// If the current page is not 0, go to the previous page
currentPage--; currentPage--;
}
submit = false; submit = false;
min = currentPage * logoAmount;
max = min + logoAmount;
transitionDirection = -5; transitionDirection = -5;
} }
@ -120,23 +130,46 @@
} }
function nextPage() { function nextPage() {
if (currentPage >= logoPages || submit) return null; let nextPage = currentPage + 1;
// If the current page is the last page, set the current page to the first page
if (currentPage >= logoPages - 1) {
currentPage = 0;
} else {
currentPage++; currentPage++;
min = currentPage * logoAmount; // If the current page is now the last page, allow review selections and set the current page to the first page
max = min + logoAmount; if (currentPage >= logoPages - 1) {
allowReviewSelections = true;
nextPage = 0;
}
}
if (currentPage < logoPages) {
const nextPage = currentPage + 1;
const nextMin = nextPage * logoAmount; const nextMin = nextPage * logoAmount;
const nextMax = nextMin + logoAmount; const nextMax = nextMin + logoAmount;
logos.slice(nextMin, nextMax).forEach(({ variants }) => { logos.slice(nextMin, nextMax).forEach(({ variants }) => {
variants.forEach((variant) => preloadImage(variant.gdrive_direct_url)); variants.forEach((variant) => preloadImage(variant.gdrive_direct_url));
}); });
}
transitionDirection = 5; transitionDirection = 5;
} }
function stopReview() {
finalPage = false;
submit = false;
}
function reviewSelections() {
if (allowReviewSelections) {
finalPage = true;
}
}
function submitSelection() {
if (ui_selected_count < 1) return null;
submit = true;
}
function clearLogos() { function clearLogos() {
if (submit) { if (submit) {
return; return;
@ -186,7 +219,7 @@
<h3>ReVanced</h3> <h3>ReVanced</h3>
<h1>{finalPage ? 'Review selected logos' : 'Select logos'}</h1> <h1>{finalPage ? 'Review selected logos' : 'Select logos'}</h1>
<h2> <h2>
{ui_selected_count}/{logos.length} selected · Page {Number(currentPage) + 1}/{logoPages + 1} {ui_selected_count}/{logos.length} selected · Page {currentPage + 1}/{logoPages}
</h2> </h2>
<div class="top-custom-button-container"> <div class="top-custom-button-container">
<button on:click={() => (modalOpen = !modalOpen)}>How does this work?</button> <button on:click={() => (modalOpen = !modalOpen)}>How does this work?</button>
@ -195,19 +228,6 @@
</div> </div>
<div class="options-grid"> <div class="options-grid">
{#each logos.slice(min, max) as { variants, name }}
{#key currentPage}
<span in:fly={{ x: transitionDirection, easing: expoOut, duration: 1000 }}>
<LogoOption
bind:selected={selected[name]}
clicked={selected[name].length != 0}
{variants}
{name}
/>
</span>
{/key}
{/each}
{#if finalPage} {#if finalPage}
{#each logos as { variants, name }} {#each logos as { variants, name }}
{#if selected[name].length != 0} {#if selected[name].length != 0}
@ -221,6 +241,19 @@
</span> </span>
{/if} {/if}
{/each} {/each}
{:else}
{#each logos.slice(min, max) as { variants, name }}
{#key currentPage}
<span in:fly={{ x: transitionDirection, easing: expoOut, duration: 1000 }}>
<LogoOption
bind:selected={selected[name]}
clicked={selected[name].length != 0}
{variants}
{name}
/>
</span>
{/key}
{/each}
{/if} {/if}
</div> </div>
@ -254,11 +287,21 @@
{/if} {/if}
</div> </div>
<div class="buttons-container"> <div class="buttons-container">
<Button on:click={previousPage} unclickable={currentPage <= 0}>Previous</Button> {#if !finalPage}
<Button on:click={previousPage} unclickable={currentPage <= 0 && !allowReviewSelections}
>Previous</Button
>
{/if}
<Button
on:click={finalPage ? stopReview : reviewSelections}
unclickable={!allowReviewSelections}
>
{finalPage ? 'Go back' : 'Preview selection'}</Button
>
<Button <Button
kind="primary" kind="primary"
on:click={finalPage ? () => (submit = true) : nextPage} on:click={finalPage ? submitSelection : nextPage}
unclickable={submit} unclickable={submit || (finalPage && ui_selected_count < 1)}
> >
{finalPage ? 'Submit' : 'Next'} {finalPage ? 'Submit' : 'Next'}
</Button> </Button>
@ -270,8 +313,8 @@
<svelte:fragment slot="description"> <svelte:fragment slot="description">
<div class="desc"> <div class="desc">
<h6> <h6>
This is an approval voting system. Voters can choose any number of logo and variants. The logo that is This is an approval voting system. Voters can choose any number of logo and variants. The
selected the most wins. Note that you can only vote once! logo that is selected the most wins. Note that you can only vote once!
</h6> </h6>
</div> </div>
</svelte:fragment> </svelte:fragment>
@ -314,11 +357,6 @@
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
b {
color: var(--white);
margin-bottom: 1rem;
}
.buttons-container { .buttons-container {
display: flex; display: flex;
gap: 1rem; gap: 1rem;
@ -333,11 +371,6 @@
border-top: 1px solid var(--grey-three); border-top: 1px solid var(--grey-three);
} }
.information {
text-align: center;
margin-bottom: 1rem;
}
.buttons { .buttons {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;