forked from mirrors/pronouns.cc
feat(!): return 204 instead of useless json responses, add fastFetch
This commit is contained in:
parent
abc78f3a9a
commit
9c8b6a8f91
16 changed files with 63 additions and 31 deletions
|
@ -42,7 +42,7 @@ func (s *Server) cancelDelete(w http.ResponseWriter, r *http.Request) error {
|
||||||
log.Errorf("executing undelete query: %v", err)
|
log.Errorf("executing undelete query: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, map[string]any{"success": true})
|
render.NoContent(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +104,6 @@ func (s *Server) forceDelete(w http.ResponseWriter, r *http.Request) error {
|
||||||
return errors.Wrap(err, "deleting user")
|
return errors.Wrap(err, "deleting user")
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, map[string]any{"success": true})
|
render.NoContent(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,6 @@ func (s *Server) deleteMember(w http.ResponseWriter, r *http.Request) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, map[string]any{"deleted": true})
|
render.NoContent(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,13 +51,13 @@ func (s *Server) createUserReport(w http.ResponseWriter, r *http.Request) error
|
||||||
return server.APIError{Code: server.ErrBadRequest, Details: "Reason cannot exceed 2000 characters"}
|
return server.APIError{Code: server.ErrBadRequest, Details: "Reason cannot exceed 2000 characters"}
|
||||||
}
|
}
|
||||||
|
|
||||||
report, err := s.DB.CreateReport(ctx, claims.UserID, u.ID, nil, req.Reason)
|
_, err = s.DB.CreateReport(ctx, claims.UserID, u.ID, nil, req.Reason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("creating report for %v: %v", u.ID, err)
|
log.Errorf("creating report for %v: %v", u.ID, err)
|
||||||
return errors.Wrap(err, "creating report")
|
return errors.Wrap(err, "creating report")
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, map[string]any{"created": true, "created_at": report.CreatedAt})
|
render.NoContent(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,12 +100,12 @@ func (s *Server) createMemberReport(w http.ResponseWriter, r *http.Request) erro
|
||||||
return server.APIError{Code: server.ErrBadRequest, Details: "Reason cannot exceed 2000 characters"}
|
return server.APIError{Code: server.ErrBadRequest, Details: "Reason cannot exceed 2000 characters"}
|
||||||
}
|
}
|
||||||
|
|
||||||
report, err := s.DB.CreateReport(ctx, claims.UserID, u.ID, &m.ID, req.Reason)
|
_, err = s.DB.CreateReport(ctx, claims.UserID, u.ID, &m.ID, req.Reason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("creating report for %v: %v", m.ID, err)
|
log.Errorf("creating report for %v: %v", m.ID, err)
|
||||||
return errors.Wrap(err, "creating report")
|
return errors.Wrap(err, "creating report")
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, map[string]any{"created": true, "created_at": report.CreatedAt})
|
render.NoContent(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,6 @@ func (s *Server) resolveReport(w http.ResponseWriter, r *http.Request) error {
|
||||||
return errors.Wrap(err, "committing transaction")
|
return errors.Wrap(err, "committing transaction")
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, map[string]any{"success": true})
|
render.NoContent(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,6 @@ func (s *Server) ackWarning(w http.ResponseWriter, r *http.Request) (err error)
|
||||||
return server.APIError{Code: server.ErrNotFound}
|
return server.APIError{Code: server.ErrNotFound}
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, map[string]any{"ok": true})
|
render.NoContent(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,6 @@ func (s *Server) deleteUser(w http.ResponseWriter, r *http.Request) error {
|
||||||
return errors.Wrap(err, "committing transaction")
|
return errors.Wrap(err, "committing transaction")
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, map[string]any{"deleted": true})
|
render.NoContent(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ func (s *Server) startExport(w http.ResponseWriter, r *http.Request) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, map[string]any{"started": true})
|
render.NoContent(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import type { APIError } from "./entities";
|
import type { APIError } from "./entities";
|
||||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||||
|
|
||||||
|
@ -21,9 +22,36 @@ export async function apiFetch<T>(
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
if (resp.status < 200 || resp.status >= 300) throw data as APIError;
|
if (resp.status < 200 || resp.status >= 400) throw data as APIError;
|
||||||
return data as T;
|
return data as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const apiFetchClient = async <T>(path: string, method: string = "GET", body: any = null) =>
|
export const apiFetchClient = async <T>(path: string, method = "GET", body: any = null) =>
|
||||||
apiFetch<T>(path, { method, body, token: localStorage.getItem("pronouns-token") || undefined });
|
apiFetch<T>(path, { method, body, token: localStorage.getItem("pronouns-token") || undefined });
|
||||||
|
|
||||||
|
/** Fetches the specified path without parsing the response body. */
|
||||||
|
export async function fastFetch(
|
||||||
|
path: string,
|
||||||
|
{
|
||||||
|
method,
|
||||||
|
body,
|
||||||
|
token,
|
||||||
|
headers,
|
||||||
|
}: { method?: string; body?: any; token?: string; headers?: Record<string, string> },
|
||||||
|
) {
|
||||||
|
const resp = await fetch(`${PUBLIC_BASE_URL}/api/v1${path}`, {
|
||||||
|
method: method || "GET",
|
||||||
|
headers: {
|
||||||
|
...(token ? { Authorization: token } : {}),
|
||||||
|
...(headers ? headers : {}),
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: body ? JSON.stringify(body) : null,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resp.status < 200 || resp.status >= 400) throw (await resp.json()) as APIError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fetches the specified path without parsing the response body. */
|
||||||
|
export const fastFetchClient = async (path: string, method = "GET", body: any = null) =>
|
||||||
|
fastFetch(path, { method, body, token: localStorage.getItem("pronouns-token") || undefined });
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { APIError } from "$lib/api/entities";
|
import type { APIError } from "$lib/api/entities";
|
||||||
import { apiFetchClient } from "$lib/api/fetch";
|
import { fastFetchClient } from "$lib/api/fetch";
|
||||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||||
import { addToast } from "$lib/toast";
|
import { addToast } from "$lib/toast";
|
||||||
import { Button, FormGroup, Icon, Modal, ModalBody, ModalFooter } from "sveltestrap";
|
import { Button, FormGroup, Icon, Modal, ModalBody, ModalFooter } from "sveltestrap";
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
const doReport = async () => {
|
const doReport = async () => {
|
||||||
try {
|
try {
|
||||||
await apiFetchClient<any>(reportUrl, "POST", { reason: reason });
|
await fastFetchClient(reportUrl, "POST", { reason: reason });
|
||||||
error = null;
|
error = null;
|
||||||
addToast({ header: "Sent report", body: "Successfully sent report!" });
|
addToast({ header: "Sent report", body: "Successfully sent report!" });
|
||||||
toggle();
|
toggle();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import type { APIError, MeUser } from "$lib/api/entities";
|
import type { APIError, MeUser } from "$lib/api/entities";
|
||||||
import { apiFetch } from "$lib/api/fetch";
|
import { fastFetch } from "$lib/api/fetch";
|
||||||
import { usernameRegex } from "$lib/api/regex";
|
import { usernameRegex } from "$lib/api/regex";
|
||||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||||
import { userStore } from "$lib/store";
|
import { userStore } from "$lib/store";
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
const forceDeleteAccount = async () => {
|
const forceDeleteAccount = async () => {
|
||||||
try {
|
try {
|
||||||
await apiFetch<any>("/auth/force-delete", {
|
await fastFetch("/auth/force-delete", {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"X-Delete-Token": token!,
|
"X-Delete-Token": token!,
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
|
|
||||||
const cancelDelete = async () => {
|
const cancelDelete = async () => {
|
||||||
try {
|
try {
|
||||||
await apiFetch<any>("/auth/cancel-delete", {
|
await fastFetch("/auth/cancel-delete", {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"X-Delete-Token": token!,
|
"X-Delete-Token": token!,
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
} from "sveltestrap";
|
} from "sveltestrap";
|
||||||
import { encode } from "base64-arraybuffer";
|
import { encode } from "base64-arraybuffer";
|
||||||
import { apiFetchClient } from "$lib/api/fetch";
|
import { apiFetchClient, fastFetchClient } from "$lib/api/fetch";
|
||||||
import IconButton from "$lib/components/IconButton.svelte";
|
import IconButton from "$lib/components/IconButton.svelte";
|
||||||
import EditableField from "../../EditableField.svelte";
|
import EditableField from "../../EditableField.svelte";
|
||||||
import EditableName from "../../EditableName.svelte";
|
import EditableName from "../../EditableName.svelte";
|
||||||
|
@ -242,9 +242,13 @@
|
||||||
|
|
||||||
const deleteMember = async () => {
|
const deleteMember = async () => {
|
||||||
try {
|
try {
|
||||||
await apiFetchClient<any>(`/members/${data.member.id}`, "DELETE");
|
await fastFetchClient(`/members/${data.member.id}`, "DELETE");
|
||||||
|
|
||||||
toggleDeleteOpen();
|
toggleDeleteOpen();
|
||||||
|
addToast({
|
||||||
|
header: "Deleted member",
|
||||||
|
body: `Successfully deleted member ${data.member.name}!`,
|
||||||
|
});
|
||||||
goto(`/@${data.member.user.name}`);
|
goto(`/@${data.member.user.name}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
deleteName = "";
|
deleteName = "";
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
} from "$lib/api/entities";
|
} from "$lib/api/entities";
|
||||||
import FallbackImage from "$lib/components/FallbackImage.svelte";
|
import FallbackImage from "$lib/components/FallbackImage.svelte";
|
||||||
import { userStore } from "$lib/store";
|
import { userStore } from "$lib/store";
|
||||||
import { Alert, Button, ButtonGroup, FormGroup, Icon, Input, Popover } from "sveltestrap";
|
import { Button, ButtonGroup, FormGroup, Icon, Input, Popover } from "sveltestrap";
|
||||||
import { encode } from "base64-arraybuffer";
|
import { encode } from "base64-arraybuffer";
|
||||||
import { apiFetchClient } from "$lib/api/fetch";
|
import { apiFetchClient } from "$lib/api/fetch";
|
||||||
import IconButton from "$lib/components/IconButton.svelte";
|
import IconButton from "$lib/components/IconButton.svelte";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { APIError } from "$lib/api/entities";
|
import type { APIError } from "$lib/api/entities";
|
||||||
import { apiFetchClient } from "$lib/api/fetch";
|
import { fastFetchClient } from "$lib/api/fetch";
|
||||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||||
import { addToast } from "$lib/toast";
|
import { addToast } from "$lib/toast";
|
||||||
import { Button, FormGroup, Modal, ModalBody, ModalFooter } from "sveltestrap";
|
import { Button, FormGroup, Modal, ModalBody, ModalFooter } from "sveltestrap";
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
const warnUser = async () => {
|
const warnUser = async () => {
|
||||||
try {
|
try {
|
||||||
await apiFetchClient<any>(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
|
await fastFetchClient(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
|
||||||
warn: true,
|
warn: true,
|
||||||
reason: reason,
|
reason: reason,
|
||||||
});
|
});
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
const deactivateUser = async () => {
|
const deactivateUser = async () => {
|
||||||
try {
|
try {
|
||||||
await apiFetchClient<any>(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
|
await fastFetchClient(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
|
||||||
warn: true,
|
warn: true,
|
||||||
ban: true,
|
ban: true,
|
||||||
delete: deleteUser,
|
delete: deleteUser,
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
|
|
||||||
const ignoreReport = async () => {
|
const ignoreReport = async () => {
|
||||||
try {
|
try {
|
||||||
await apiFetchClient<any>(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
|
await fastFetchClient(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
|
||||||
reason: reason,
|
reason: reason,
|
||||||
});
|
});
|
||||||
error = null;
|
error = null;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { type MeUser, userAvatars, type APIError, MAX_MEMBERS } from "$lib/api/entities";
|
import { type MeUser, userAvatars, type APIError, MAX_MEMBERS } from "$lib/api/entities";
|
||||||
import { apiFetchClient } from "$lib/api/fetch";
|
import { apiFetchClient, fastFetchClient } from "$lib/api/fetch";
|
||||||
import { usernameRegex } from "$lib/api/regex";
|
import { usernameRegex } from "$lib/api/regex";
|
||||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||||
import FallbackImage from "$lib/components/FallbackImage.svelte";
|
import FallbackImage from "$lib/components/FallbackImage.svelte";
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
const deleteAccount = async () => {
|
const deleteAccount = async () => {
|
||||||
try {
|
try {
|
||||||
await apiFetchClient<any>("/users/@me", "DELETE");
|
await fastFetchClient("/users/@me", "DELETE");
|
||||||
|
|
||||||
userStore.set(null);
|
userStore.set(null);
|
||||||
localStorage.removeItem("pronouns-token");
|
localStorage.removeItem("pronouns-token");
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { DateTime, Duration } from "luxon";
|
import { DateTime, Duration } from "luxon";
|
||||||
import { Alert, Button } from "sveltestrap";
|
import { Alert, Button } from "sveltestrap";
|
||||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||||
import { apiFetchClient } from "$lib/api/fetch";
|
import { fastFetchClient } from "$lib/api/fetch";
|
||||||
import type { APIError } from "$lib/api/entities";
|
import type { APIError } from "$lib/api/entities";
|
||||||
import { addToast } from "$lib/toast";
|
import { addToast } from "$lib/toast";
|
||||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
const requestExport = async () => {
|
const requestExport = async () => {
|
||||||
try {
|
try {
|
||||||
await apiFetchClient<any>("/users/@me/export/start");
|
await fastFetchClient("/users/@me/export/start");
|
||||||
|
|
||||||
addToast({
|
addToast({
|
||||||
header: "Export in progress",
|
header: "Export in progress",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { APIError } from "$lib/api/entities";
|
import type { APIError } from "$lib/api/entities";
|
||||||
import { apiFetchClient } from "$lib/api/fetch";
|
import { apiFetchClient, fastFetchClient } from "$lib/api/fetch";
|
||||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||||
import { addToast } from "$lib/toast";
|
import { addToast } from "$lib/toast";
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
const acknowledgeWarning = async (idx: number) => {
|
const acknowledgeWarning = async (idx: number) => {
|
||||||
try {
|
try {
|
||||||
await apiFetchClient<any>(`/auth/warnings/${data.warnings[idx].id}/ack`, "POST");
|
await fastFetchClient(`/auth/warnings/${data.warnings[idx].id}/ack`, "POST");
|
||||||
addToast({
|
addToast({
|
||||||
header: "Acknowledged",
|
header: "Acknowledged",
|
||||||
body: `Marked warning #${data.warnings[idx].id} as read.`,
|
body: `Marked warning #${data.warnings[idx].id} as read.`,
|
||||||
|
|
Loading…
Reference in a new issue