Skip to content

Commit e41e1f5

Browse files
Copilotv0l
andcommitted
Implement reviewed flag for reports instead of deletion and revert upload.tsx changes
Co-authored-by: v0l <[email protected]>
1 parent 1ac95f8 commit e41e1f5

File tree

5 files changed

+17
-76
lines changed

5 files changed

+17
-76
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Add reviewed flag to reports table
2+
alter table reports add column reviewed boolean not null default false;
3+
4+
-- Index for efficient filtering of non-reviewed reports
5+
create index ix_reports_reviewed on reports (reviewed);

src/db.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ pub struct Report {
116116
pub reporter_id: u64,
117117
pub event_json: String,
118118
pub created: DateTime<Utc>,
119+
pub reviewed: bool,
119120
}
120121

121122
#[derive(Clone)]
@@ -394,14 +395,14 @@ impl Database {
394395
/// List reports with pagination for admin view
395396
pub async fn list_reports(&self, offset: u32, limit: u32) -> Result<(Vec<Report>, i64), Error> {
396397
let reports: Vec<Report> = sqlx::query_as(
397-
"select id, file_id, reporter_id, event_json, created from reports order by created desc limit ? offset ?"
398+
"select id, file_id, reporter_id, event_json, created, reviewed from reports where reviewed = false order by created desc limit ? offset ?"
398399
)
399400
.bind(limit)
400401
.bind(offset)
401402
.fetch_all(&self.pool)
402403
.await?;
403404

404-
let count: i64 = sqlx::query("select count(id) from reports")
405+
let count: i64 = sqlx::query("select count(id) from reports where reviewed = false")
405406
.fetch_one(&self.pool)
406407
.await?
407408
.try_get(0)?;
@@ -412,16 +413,16 @@ impl Database {
412413
/// Get reports for a specific file
413414
pub async fn get_file_reports(&self, file_id: &[u8]) -> Result<Vec<Report>, Error> {
414415
sqlx::query_as(
415-
"select id, file_id, reporter_id, event_json, created from reports where file_id = ? order by created desc"
416+
"select id, file_id, reporter_id, event_json, created, reviewed from reports where file_id = ? order by created desc"
416417
)
417418
.bind(file_id)
418419
.fetch_all(&self.pool)
419420
.await
420421
}
421422

422-
/// Delete a report (used for acknowledging)
423-
pub async fn delete_report(&self, report_id: u64) -> Result<(), Error> {
424-
sqlx::query("delete from reports where id = ?")
423+
/// Mark a report as reviewed (used for acknowledging)
424+
pub async fn mark_report_reviewed(&self, report_id: u64) -> Result<(), Error> {
425+
sqlx::query("update reports set reviewed = true where id = ?")
425426
.bind(report_id)
426427
.execute(&self.pool)
427428
.await?;

src/routes/admin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ async fn admin_acknowledge_report(
208208
return AdminResponse::error("User is not an admin");
209209
}
210210

211-
match db.delete_report(report_id).await {
211+
match db.mark_report_reviewed(report_id).await {
212212
Ok(()) => AdminResponse::success(()),
213213
Err(e) => AdminResponse::error(&format!("Could not acknowledge report: {}", e)),
214214
}

ui_src/src/upload/admin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface Report {
1818
reporter_id: number;
1919
event_json: string;
2020
created: string;
21+
reviewed: boolean;
2122
}
2223

2324
export class Route96 {

ui_src/src/views/upload.tsx

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ import { Blossom } from "../upload/blossom";
66
import useLogin from "../hooks/login";
77
import usePublisher from "../hooks/publisher";
88
import { Nip96, Nip96FileList } from "../upload/nip96";
9-
import { AdminSelf, Route96, Report } from "../upload/admin";
9+
import { AdminSelf, Route96 } from "../upload/admin";
1010
import { FormatBytes } from "../const";
11-
import ReportJson from "../report.json";
12-
import ReportList from "./reports";
11+
import Report from "../report.json";
1312

1413
export default function Upload() {
1514
const [type, setType] = useState<"blossom" | "nip96">("blossom");
@@ -22,21 +21,14 @@ export default function Upload() {
2221
const [results, setResults] = useState<Array<object>>([]);
2322
const [listedFiles, setListedFiles] = useState<Nip96FileList>();
2423
const [adminListedFiles, setAdminListedFiles] = useState<Nip96FileList>();
25-
const [adminListedReports, setAdminListedReports] = useState<{
26-
total: number;
27-
page: number;
28-
count: number;
29-
files: Array<Report>;
30-
}>();
3124
const [listedPage, setListedPage] = useState(0);
3225
const [adminListedPage, setAdminListedPage] = useState(0);
33-
const [adminReportsPage, setAdminReportsPage] = useState(0);
3426
const [mimeFilter, setMimeFilter] = useState<string>();
3527

3628
const login = useLogin();
3729
const pub = usePublisher();
3830

39-
const legacyFiles = ReportJson as Record<string, Array<string>>;
31+
const legacyFiles = Report as Record<string, Array<string>>;
4032
const myLegacyFiles = login ? (legacyFiles[login.pubkey] ?? []) : [];
4133

4234
const url =
@@ -107,43 +99,6 @@ export default function Upload() {
10799
}
108100
}
109101

110-
async function listReports(n: number) {
111-
if (!pub) return;
112-
try {
113-
setError(undefined);
114-
const uploader = new Route96(url, pub);
115-
const result = await uploader.listReports(n, 50);
116-
setAdminListedReports(result);
117-
} catch (e) {
118-
if (e instanceof Error) {
119-
setError(e.message.length > 0 ? e.message : "List reports failed");
120-
} else if (typeof e === "string") {
121-
setError(e);
122-
} else {
123-
setError("List reports failed");
124-
}
125-
}
126-
}
127-
128-
async function acknowledgeReport(reportId: number) {
129-
if (!pub) return;
130-
try {
131-
setError(undefined);
132-
const uploader = new Route96(url, pub);
133-
await uploader.acknowledgeReport(reportId);
134-
// Refresh the reports list
135-
await listReports(adminReportsPage);
136-
} catch (e) {
137-
if (e instanceof Error) {
138-
setError(e.message.length > 0 ? e.message : "Acknowledge failed");
139-
} else if (typeof e === "string") {
140-
setError(e);
141-
} else {
142-
setError("Acknowledge failed");
143-
}
144-
}
145-
}
146-
147102
async function deleteFile(id: string) {
148103
if (!pub) return;
149104
try {
@@ -183,10 +138,6 @@ export default function Upload() {
183138
listAllUploads(adminListedPage);
184139
}, [adminListedPage, mimeFilter]);
185140

186-
useEffect(() => {
187-
listReports(adminReportsPage);
188-
}, [adminReportsPage]);
189-
190141
useEffect(() => {
191142
if (pub && !self) {
192143
const r96 = new Route96(url, pub);
@@ -323,23 +274,6 @@ export default function Upload() {
323274
}}
324275
/>
325276
)}
326-
327-
<hr />
328-
<h3>Admin Reports:</h3>
329-
<Button onClick={() => listReports(0)}>List Reports</Button>
330-
{adminListedReports && (
331-
<ReportList
332-
reports={adminListedReports.files}
333-
pages={Math.ceil(adminListedReports.total / adminListedReports.count)}
334-
page={adminListedReports.page}
335-
onPage={(x) => setAdminReportsPage(x)}
336-
onAcknowledge={acknowledgeReport}
337-
onDeleteFile={async (fileId) => {
338-
await deleteFile(fileId);
339-
await listReports(adminReportsPage);
340-
}}
341-
/>
342-
)}
343277
</>
344278
)}
345279
{error && <b className="text-red-500">{error}</b>}

0 commit comments

Comments
 (0)