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

@ -3,9 +3,9 @@
import Modal from './Dialogue.svelte';
import Button from './Button.svelte';
import next from '$lib/assets/icons/next.svg';
import previous from '$lib/assets/icons/previous.svg';
import type { APILogo } from '$lib/types';
import next from '$lib/assets/icons/next.svg';
import previous from '$lib/assets/icons/previous.svg';
import type { APILogo } from '$lib/types';
export let name = '';
export let selected: string[];
@ -171,11 +171,6 @@
font-weight: 800;
}
h6 {
font-size: 0.9rem;
overflow: hidden;
text-overflow: ellipsis;
}
.text {
width: 100%;
white-space: nowrap;
@ -186,8 +181,7 @@
background-color: var(--accent-low-opacity);
}
.clicked h2,
.clicked h6 {
.clicked h2 {
color: var(--white);
}

View File

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