Added stash menu with remove and rename.
This commit is contained in:
52
src/api.js
52
src/api.js
@@ -1,4 +1,5 @@
|
||||
import { parse } from '@brillout/json-serializer/parse'; /* eslint-disable-line import/extensions */
|
||||
import events from '#/src/events.js';
|
||||
|
||||
const postHeaders = {
|
||||
mode: 'cors',
|
||||
@@ -18,39 +19,69 @@ function getQuery(data) {
|
||||
return `?${encodeURI(decodeURIComponent(new URLSearchParams(curatedQuery).toString()))}`; // recode so commas aren't encoded
|
||||
}
|
||||
|
||||
export async function get(path, query = {}) {
|
||||
function showFeedback(isSuccess, options = {}, errorMessage) {
|
||||
if (!isSuccess && typeof options.errorFeedback) {
|
||||
events.emit('feedback', {
|
||||
type: 'error',
|
||||
message: options.appendErrorMessage && errorMessage
|
||||
? `${options.errorFeedback}: ${errorMessage}`
|
||||
: options.errorFeedback,
|
||||
});
|
||||
}
|
||||
|
||||
if (isSuccess && options.successFeedback) {
|
||||
events.emit('feedback', {
|
||||
type: 'success',
|
||||
message: options.successFeedback,
|
||||
});
|
||||
}
|
||||
|
||||
if (isSuccess && options.undoFeedback) {
|
||||
events.emit('feedback', {
|
||||
type: 'undo',
|
||||
message: options.undoFeedback,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function get(path, query = {}, options = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(query)}`);
|
||||
const body = parse(await res.text());
|
||||
|
||||
if (res.ok) {
|
||||
showFeedback(true, options);
|
||||
return body;
|
||||
}
|
||||
|
||||
showFeedback(false, options, body.statusMessage);
|
||||
throw new Error(body.statusMessage);
|
||||
}
|
||||
|
||||
export async function post(path, data, { query } = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(query)}`, {
|
||||
export async function post(path, data, options = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(options.query)}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
...postHeaders,
|
||||
});
|
||||
|
||||
if (res.status === 204) {
|
||||
showFeedback(true, options);
|
||||
return null;
|
||||
}
|
||||
|
||||
const body = parse(await res.text());
|
||||
|
||||
if (res.ok) {
|
||||
showFeedback(true, options);
|
||||
return body;
|
||||
}
|
||||
|
||||
showFeedback(false, options, body.statusMessage);
|
||||
throw new Error(body.statusMessage);
|
||||
}
|
||||
|
||||
export async function patch(path, data, { query } = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(query)}`, {
|
||||
export async function patch(path, data, options = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(options.query)}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
...postHeaders,
|
||||
@@ -63,28 +94,33 @@ export async function patch(path, data, { query } = {}) {
|
||||
const body = parse(await res.text());
|
||||
|
||||
if (res.ok) {
|
||||
showFeedback(true, options);
|
||||
return body;
|
||||
}
|
||||
|
||||
showFeedback(false, options, body.statusMessage);
|
||||
throw new Error(body.statusMessage);
|
||||
}
|
||||
|
||||
export async function del(path, { data, query } = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(query)}`, {
|
||||
export async function del(path, options = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(options.query)}`, {
|
||||
method: 'DELETE',
|
||||
body: JSON.stringify(data),
|
||||
body: JSON.stringify(options.data),
|
||||
...postHeaders,
|
||||
});
|
||||
|
||||
if (res.status === 204) {
|
||||
showFeedback(true, options);
|
||||
return null;
|
||||
}
|
||||
|
||||
const body = parse(await res.text());
|
||||
|
||||
if (res.ok) {
|
||||
showFeedback(true, options);
|
||||
return body;
|
||||
}
|
||||
|
||||
showFeedback(false, options, body.statusMessage);
|
||||
throw new Error(body.statusMessage);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export function curateStash(stash, assets = {}) {
|
||||
id: stash.id,
|
||||
name: stash.name,
|
||||
slug: stash.slug,
|
||||
primary: stash.primary,
|
||||
isPrimary: stash.primary,
|
||||
public: stash.public,
|
||||
createdAt: stash.created_at,
|
||||
stashedScenes: stash.stashed_scenes ?? null,
|
||||
@@ -38,10 +38,10 @@ export function curateStash(stash, assets = {}) {
|
||||
|
||||
function curateStashEntry(stash, user) {
|
||||
const curatedStashEntry = {
|
||||
user_id: user.id,
|
||||
name: stash.name,
|
||||
slug: slugify(stash.name),
|
||||
public: false,
|
||||
user_id: user?.id || undefined,
|
||||
name: stash.name || undefined,
|
||||
slug: slugify(stash.name) || undefined,
|
||||
public: stash.public ?? false,
|
||||
};
|
||||
|
||||
return curatedStashEntry;
|
||||
@@ -94,26 +94,30 @@ export async function fetchStashes(domain, itemId, sessionUser) {
|
||||
return stashes.map((stash) => curateStash(stash));
|
||||
}
|
||||
|
||||
function verifyStashName(stash) {
|
||||
if (!stash.name) {
|
||||
throw new HttpError('Stash name required', 400);
|
||||
}
|
||||
|
||||
if (stash.name.length < config.stashes.nameLength[0]) {
|
||||
throw new HttpError('Stash name is too short', 400);
|
||||
}
|
||||
|
||||
if (stash.name.length > config.stashes.nameLength[1]) {
|
||||
throw new HttpError('Stash name is too long', 400);
|
||||
}
|
||||
|
||||
if (!config.stashes.namePattern.test(stash.name)) {
|
||||
throw new HttpError('Stash name contains invalid characters', 400);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createStash(newStash, sessionUser) {
|
||||
if (!sessionUser) {
|
||||
throw new HttpError('You are not authenthicated', 401);
|
||||
}
|
||||
|
||||
if (!newStash.name) {
|
||||
throw new HttpError('Stash name required', 400);
|
||||
}
|
||||
|
||||
if (newStash.name.length < config.stashes.nameLength[0]) {
|
||||
throw new HttpError('Stash name is too short', 400);
|
||||
}
|
||||
|
||||
if (newStash.name.length > config.stashes.nameLength[1]) {
|
||||
throw new HttpError('Stash name is too long', 400);
|
||||
}
|
||||
|
||||
if (!config.stashes.namePattern.test(newStash.name)) {
|
||||
throw new HttpError('Stash name contains invalid characters', 400);
|
||||
}
|
||||
verifyStashName(newStash);
|
||||
|
||||
try {
|
||||
const stash = await knex('stashes')
|
||||
@@ -130,24 +134,36 @@ export async function createStash(newStash, sessionUser) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateStash(stashId, newStash, sessionUser) {
|
||||
export async function updateStash(stashId, updatedStash, sessionUser) {
|
||||
if (!sessionUser) {
|
||||
throw new HttpError('You are not authenthicated', 401);
|
||||
}
|
||||
|
||||
const stash = await knex('stashes')
|
||||
.where({
|
||||
id: stashId,
|
||||
user_id: sessionUser.id,
|
||||
})
|
||||
.update(newStash)
|
||||
.returning('*');
|
||||
|
||||
if (!stash) {
|
||||
throw new HttpError('You are not authorized to modify this stash', 403);
|
||||
if (updatedStash.name) {
|
||||
verifyStashName(updatedStash);
|
||||
}
|
||||
|
||||
return curateStash(stash);
|
||||
try {
|
||||
const stash = await knex('stashes')
|
||||
.where({
|
||||
id: stashId,
|
||||
user_id: sessionUser.id,
|
||||
})
|
||||
.update(curateStashEntry(updatedStash))
|
||||
.returning('*');
|
||||
|
||||
if (!stash) {
|
||||
throw new HttpError('You are not authorized to modify this stash', 403);
|
||||
}
|
||||
|
||||
return curateStash(stash);
|
||||
} catch (error) {
|
||||
if (error.routine === '_bt_check_unique') {
|
||||
throw new HttpError('Stash name should be unique', 409);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function removeStash(stashId, sessionUser) {
|
||||
|
||||
@@ -18,7 +18,7 @@ export function curateUser(user, assets = {}) {
|
||||
avatar: `/media/avatars/${user.id}_${user.username}.png`,
|
||||
createdAt: user.created_at,
|
||||
stashes: curatedStashes,
|
||||
primaryStash: curatedStashes.find((stash) => stash.primary),
|
||||
primaryStash: curatedStashes.find((stash) => stash.isPrimary),
|
||||
};
|
||||
|
||||
return curatedUser;
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
export function curateUser(user, assets = {}) {
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const curatedStashes = assets.stashes?.filter(Boolean).map((stash) => curateStash(stash)) || [];
|
||||
|
||||
const curatedUser = {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
emailVerified: user.email_verified,
|
||||
identityVerified: user.identity_verified,
|
||||
avatar: `/media/avatars/${user.id}_${user.username}.png`,
|
||||
createdAt: user.created_at,
|
||||
stashes: curatedStashes,
|
||||
primaryStash: curatedStashes.find((stash) => stash.primary),
|
||||
};
|
||||
|
||||
return curatedUser;
|
||||
}
|
||||
Reference in New Issue
Block a user