From 1f8cf66e90e2a0f08ed09d09861dd01caf790e63 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 5 Oct 2023 13:07:30 +0200 Subject: [PATCH] add report selection via url hash --- src/routes/admin/+layout.svelte | 2 - src/routes/admin/reports/+page.svelte | 67 ++++++++++++++++++++++++--- src/routes/admin/reports/+server.ts | 11 ++++- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/src/routes/admin/+layout.svelte b/src/routes/admin/+layout.svelte index f07f540..a2c3e52 100644 --- a/src/routes/admin/+layout.svelte +++ b/src/routes/admin/+layout.svelte @@ -22,8 +22,6 @@ export let data: LayoutData; if (data.reportCount) $reportCount = data.reportCount; if (data.adminCount) $adminCount = data.adminCount; - - errorMessage.subscribe(console.log); {#if $page.url.pathname !== `${env.PUBLIC_BASE_PATH}/admin/login`} diff --git a/src/routes/admin/reports/+page.svelte b/src/routes/admin/reports/+page.svelte index 62b867f..507099a 100644 --- a/src/routes/admin/reports/+page.svelte +++ b/src/routes/admin/reports/+page.svelte @@ -11,10 +11,13 @@ import HeaderBar from './HeaderBar.svelte'; import { IconOutline } from 'svelte-heros-v2'; import NewReportModal from './NewReportModal.svelte'; + import { onDestroy, onMount } from 'svelte'; + import { goto } from '$app/navigation'; export let data: PageData; let currentPageReports: (typeof Report.prototype.dataValues)[] = []; + let currentPageReportsRequest: Promise = Promise.resolve(); let reportsPerPage = 50; let reportPage = 0; let reportFilter = { draft: false, status: null, reporter: null, reported: null }; @@ -22,8 +25,8 @@ async function fetchPageReports( page: number, - filter: any - ): Promise<(typeof Report.prototype.dataValues)[]> { + filter: typeof reportFilter | { hash: string } + ): Promise { if (!browser) return []; const response = await fetch(`${env.PUBLIC_BASE_PATH}/admin/reports`, { @@ -31,10 +34,46 @@ body: JSON.stringify({ ...filter, limit: reportsPerPage, from: reportPage * page }) }); + if (activeReport) { + activeReport = null; + await goto(window.location.href.split('#')[0], { replaceState: true }); + } + return await response.json(); } - $: fetchPageReports(reportPage, reportFilter).then((r) => (currentPageReports = r)); + $: currentPageReportsRequest = fetchPageReports(reportPage, reportFilter).then((r) => { + currentPageReports = r; + }); + + async function openHashReport() { + if (!window.location.hash) return; + + const requestedHash = window.location.hash.substring(1); + let report = currentPageReports.find((r) => r.url_hash === requestedHash); + if (!report) { + const hashReport = (await fetchPageReports(0, { hash: requestedHash }))[0]; + if (hashReport) { + currentPageReports = [hashReport, ...currentPageReports]; + report = hashReport; + } else { + await goto(window.location.href.split('#')[0], { replaceState: true }); + return; + } + } + + activeReport = report; + activeReport.originalStatus = report; + } + onMount(async () => { + await currentPageReportsRequest; + await openHashReport(); + + if (browser) window.addEventListener('hashchange', openHashReport); + }); + onDestroy(() => { + if (browser) window.removeEventListener('hashchange', openHashReport); + }); async function updateActiveReport() { await fetch(`${env.PUBLIC_BASE_PATH}/admin/reports`, { @@ -80,8 +119,11 @@ {#each currentPageReports as report} { + goto(`${window.location.href.split('#')[0]}#${report.url_hash}`, { + replaceState: true + }); activeReport = report; activeReport.originalStatus = report.status; }} @@ -158,6 +200,15 @@ class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-max" >
  • +
  • - { + activeReport = null; + goto(window.location.href.split('#')[0], { replaceState: true }); + }}>✕

    Report

    diff --git a/src/routes/admin/reports/+server.ts b/src/routes/admin/reports/+server.ts index 420fa26..2301f3e 100644 --- a/src/routes/admin/reports/+server.ts +++ b/src/routes/admin/reports/+server.ts @@ -22,9 +22,11 @@ export const POST = (async ({ request, cookies }) => { status: 'none' | 'review' | 'reviewed' | null; reporter: string | null; reported: string | null; + + hash: string | null; } = await request.json(); - const reportFindOptions: Attributes = {}; + let reportFindOptions: Attributes = {}; if (data.draft != null) reportFindOptions.draft = data.draft; reportFindOptions.status = data.status == null ? ['none', 'review'] : data.status; if (data.reporter != null) { @@ -41,6 +43,13 @@ export const POST = (async ({ request, cookies }) => { }); reportFindOptions.reported_id = reported_ids.map((u) => u.id); } + + if (data.hash != null) { + reportFindOptions = { url_hash: data.hash }; + data.from = 0; + data.limit = 1; + } + let reports = await Report.findAll({ where: reportFindOptions, include: [