mirror of
https://github.com/ReVanced/revanced-website.git
synced 2026-01-10 21:26:18 +00:00
refactor: Simplify announcement filtering and improve archived announcements handling
This commit is contained in:
@@ -22,52 +22,51 @@
|
||||
import ChevronDown from 'svelte-material-icons/ChevronDown.svelte';
|
||||
import Create from 'svelte-material-icons/Plus.svelte';
|
||||
|
||||
let searchParams: Readable<URLSearchParams>;
|
||||
let expanded = false;
|
||||
|
||||
if (building) searchParams = readable(new URLSearchParams());
|
||||
else searchParams = derived(page, ($page) => $page.url.searchParams);
|
||||
const searchParams: Readable<URLSearchParams> = building
|
||||
? readable(new URLSearchParams())
|
||||
: derived(page, ($page) => $page.url.searchParams);
|
||||
|
||||
let searchTerm = $searchParams.get('s') || '';
|
||||
let displayedTerm = '';
|
||||
|
||||
$: query = createQuery(queries.announcements());
|
||||
$: tagsQuery = createQuery(queries.announcementTags());
|
||||
$: selectedTags = $searchParams.getAll('tag');
|
||||
|
||||
let expanded = false;
|
||||
|
||||
function filterAnnouncements(
|
||||
announcements: Iterable<ResponseAnnouncement>,
|
||||
search: string,
|
||||
selectedTags: string[]
|
||||
): ResponseAnnouncement[] {
|
||||
const announcementFilter = createFilter(Array.from(announcements), {
|
||||
searcherOptions: {
|
||||
keys: ['title', 'content']
|
||||
},
|
||||
additionalFilter: (announcement: ResponseAnnouncement, tags: string[]): boolean => {
|
||||
return (
|
||||
tags.length === 0 ||
|
||||
tags.some((tag) => announcement.tags && announcement.tags.includes(tag))
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return announcementFilter(selectedTags, search);
|
||||
}
|
||||
|
||||
// Make sure we don't have to filter the announcements after every key press
|
||||
let displayedTerm = '';
|
||||
const update = () => {
|
||||
displayedTerm = searchTerm;
|
||||
|
||||
const url = new URL(window.location.href);
|
||||
url.pathname = '/announcements';
|
||||
|
||||
if (searchTerm) url.searchParams.set('s', searchTerm);
|
||||
else url.searchParams.delete('s');
|
||||
searchTerm ? url.searchParams.set('s', searchTerm) : url.searchParams.delete('s');
|
||||
};
|
||||
|
||||
onMount(update);
|
||||
const archivedAnnouncements = (announcements: ResponseAnnouncement[]) =>
|
||||
announcements.filter((a) => a.archived_at && moment(a.archived_at).isBefore(moment()));
|
||||
const activeAnnouncements = (announcements: ResponseAnnouncement[]) =>
|
||||
announcements.filter((a) => !a.archived_at || moment(a.archived_at).isAfter(moment()));
|
||||
|
||||
const filterAnnouncements = (
|
||||
announcements: ResponseAnnouncement[],
|
||||
search: string,
|
||||
tags: string[]
|
||||
): ResponseAnnouncement[] => {
|
||||
const announcementFilter = createFilter(announcements, {
|
||||
searcherOptions: { keys: ['title', 'content'] },
|
||||
|
||||
additionalFilter: (a: ResponseAnnouncement, tags: string[]) =>
|
||||
tags.length === 0 || tags.some((tag) => a.tags?.includes(tag))
|
||||
});
|
||||
|
||||
return announcementFilter(tags, search);
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
debounce(update)();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="search">
|
||||
@@ -92,60 +91,61 @@
|
||||
</Query>
|
||||
|
||||
<Query {query} let:data>
|
||||
<div class="cards">
|
||||
{#each filterAnnouncements(data.announcements, displayedTerm, selectedTags) as announcement}
|
||||
{#if !announcement.archived_at || moment(announcement.archived_at).isAfter(moment())}
|
||||
{#key selectedTags || displayedTerm}
|
||||
<div in:fly={{ y: 10, easing: quintOut, duration: 750 }}>
|
||||
<AnnouncementCard {announcement} />
|
||||
</div>
|
||||
{/key}
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div
|
||||
role="button"
|
||||
class="expand-archived"
|
||||
aria-expanded={expanded}
|
||||
class:closed={!expanded}
|
||||
on:click={() => (expanded = !expanded)}
|
||||
on:keypress={() => (expanded = !expanded)}
|
||||
tabindex="0"
|
||||
>
|
||||
<h4>Archived announcements</h4>
|
||||
|
||||
<div id="arrow" style:transform={expanded ? 'rotate(0deg)' : 'rotate(-180deg)'}>
|
||||
<ChevronDown size="24px" color="var(--surface-six)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if expanded}
|
||||
<div
|
||||
class="cards"
|
||||
in:slide={{ easing: quintIn, duration: 250 }}
|
||||
out:slide={{ easing: quintOut, duration: 250 }}
|
||||
>
|
||||
{#each filterAnnouncements(data.announcements, displayedTerm, selectedTags) as announcement}
|
||||
{#if announcement.archived_at && moment(announcement.archived_at).isBefore(moment())}
|
||||
{#key selectedTags || displayedTerm}
|
||||
<AnnouncementCard {announcement} />
|
||||
{/key}
|
||||
{/if}
|
||||
{#if activeAnnouncements(filterAnnouncements(data.announcements, displayedTerm, selectedTags)).length}
|
||||
<div class="cards">
|
||||
{#each activeAnnouncements(filterAnnouncements(data.announcements, displayedTerm, selectedTags)) as announcement}
|
||||
<div in:fly={{ y: 10, easing: quintOut, duration: 750 }}>
|
||||
<AnnouncementCard {announcement} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if archivedAnnouncements(filterAnnouncements(data.announcements, displayedTerm, selectedTags)).length}
|
||||
<div
|
||||
role="button"
|
||||
class="expand-archived"
|
||||
aria-expanded={expanded}
|
||||
on:click={() => (expanded = !expanded)}
|
||||
on:keypress={() => (expanded = !expanded)}
|
||||
tabindex="0"
|
||||
>
|
||||
<h4>Archived announcements</h4>
|
||||
|
||||
<div id="arrow" style:transform={expanded ? 'rotate(-180deg)' : 'rotate(0deg)'}>
|
||||
<ChevronDown size="24px" color="var(--surface-six)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if expanded}
|
||||
<div
|
||||
class="cards"
|
||||
in:slide={{ easing: quintIn, duration: 250 }}
|
||||
out:slide={{ easing: quintOut, duration: 250 }}
|
||||
>
|
||||
{#each archivedAnnouncements(filterAnnouncements(data.announcements, displayedTerm, selectedTags)) as announcement}
|
||||
<AnnouncementCard {announcement} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</Query>
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.expand-archived {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
padding: 0rem 0.25rem;
|
||||
padding-inline: 0.25rem;
|
||||
|
||||
#arrow {
|
||||
height: 1.5rem;
|
||||
@@ -174,7 +174,6 @@
|
||||
.cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
padding: 16px 0;
|
||||
width: 100%;
|
||||
gap: 16px;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user