mirror of
https://github.com/revanced/revanced-website.git
synced 2025-05-02 07:34:34 +02:00
feat(poll): prevent submission, when there is no selection (#74)
This commit is contained in:
parent
7c9c655485
commit
0d6974e00d
@ -3,9 +3,9 @@
|
|||||||
import Modal from './Dialogue.svelte';
|
import Modal from './Dialogue.svelte';
|
||||||
import Button from './Button.svelte';
|
import Button from './Button.svelte';
|
||||||
|
|
||||||
import next from '$lib/assets/icons/next.svg';
|
import next from '$lib/assets/icons/next.svg';
|
||||||
import previous from '$lib/assets/icons/previous.svg';
|
import previous from '$lib/assets/icons/previous.svg';
|
||||||
import type { APILogo } from '$lib/types';
|
import type { APILogo } from '$lib/types';
|
||||||
|
|
||||||
export let name = '';
|
export let name = '';
|
||||||
export let selected: string[];
|
export let selected: string[];
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { fly } from 'svelte/transition';
|
import { fly } from 'svelte/transition';
|
||||||
import { expoOut } from 'svelte/easing';
|
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 Modal from '$lib/components/atoms/Dialogue.svelte';
|
||||||
import LogoOption from '$lib/components/atoms/LogoOption.svelte';
|
import LogoOption from '$lib/components/atoms/LogoOption.svelte';
|
||||||
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;
|
||||||
let selected: Selected = {};
|
let selected: Selected = {};
|
||||||
@ -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) {
|
||||||
currentPage--;
|
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;
|
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;
|
||||||
currentPage++;
|
|
||||||
|
|
||||||
min = currentPage * logoAmount;
|
// If the current page is the last page, set the current page to the first page
|
||||||
max = min + logoAmount;
|
if (currentPage >= logoPages - 1) {
|
||||||
|
currentPage = 0;
|
||||||
|
} else {
|
||||||
|
currentPage++;
|
||||||
|
|
||||||
if (currentPage < logoPages) {
|
// If the current page is now the last page, allow review selections and set the current page to the first page
|
||||||
const nextPage = currentPage + 1;
|
if (currentPage >= logoPages - 1) {
|
||||||
const nextMin = nextPage * logoAmount;
|
allowReviewSelections = true;
|
||||||
const nextMax = nextMin + logoAmount;
|
nextPage = 0;
|
||||||
logos.slice(nextMin, nextMax).forEach(({ variants }) => {
|
}
|
||||||
variants.forEach((variant) => preloadImage(variant.gdrive_direct_url));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nextMin = nextPage * logoAmount;
|
||||||
|
const nextMax = nextMin + logoAmount;
|
||||||
|
|
||||||
|
logos.slice(nextMin, nextMax).forEach(({ variants }) => {
|
||||||
|
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user