Added secondary stash button, centralized bookmark (heart) component.
This commit is contained in:
142
src/api.js
142
src/api.js
@@ -45,82 +45,102 @@ function showFeedback(isSuccess, options = {}, errorMessage) {
|
||||
}
|
||||
|
||||
export async function get(path, query = {}, options = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(query)}`);
|
||||
const body = parse(await res.text());
|
||||
try {
|
||||
const res = await fetch(`/api${path}${getQuery(query)}`);
|
||||
const body = parse(await res.text());
|
||||
|
||||
if (res.ok) {
|
||||
showFeedback(true, options);
|
||||
return body;
|
||||
if (res.ok) {
|
||||
showFeedback(true, options);
|
||||
return body;
|
||||
}
|
||||
|
||||
showFeedback(false, options, body.statusMessage);
|
||||
throw new Error(body.statusMessage);
|
||||
} catch (error) {
|
||||
showFeedback(false, options, error.message);
|
||||
throw error;
|
||||
}
|
||||
|
||||
showFeedback(false, options, body.statusMessage);
|
||||
throw new Error(body.statusMessage);
|
||||
}
|
||||
|
||||
export async function post(path, data, options = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(options.query)}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
...postHeaders,
|
||||
});
|
||||
try {
|
||||
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;
|
||||
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);
|
||||
} catch (error) {
|
||||
showFeedback(false, options, error.message);
|
||||
throw error;
|
||||
}
|
||||
|
||||
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, options = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(options.query)}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
...postHeaders,
|
||||
});
|
||||
try {
|
||||
const res = await fetch(`/api${path}${getQuery(options.query)}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
...postHeaders,
|
||||
});
|
||||
|
||||
if (res.status === 204) {
|
||||
return null;
|
||||
if (res.status === 204) {
|
||||
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);
|
||||
} catch (error) {
|
||||
showFeedback(false, options, error.message);
|
||||
throw error;
|
||||
}
|
||||
|
||||
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, options = {}) {
|
||||
const res = await fetch(`/api${path}${getQuery(options.query)}`, {
|
||||
method: 'DELETE',
|
||||
body: JSON.stringify(options.data),
|
||||
...postHeaders,
|
||||
});
|
||||
try {
|
||||
const res = await fetch(`/api${path}${getQuery(options.query)}`, {
|
||||
method: 'DELETE',
|
||||
body: JSON.stringify(options.data),
|
||||
...postHeaders,
|
||||
});
|
||||
|
||||
if (res.status === 204) {
|
||||
showFeedback(true, options);
|
||||
return null;
|
||||
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);
|
||||
} catch (error) {
|
||||
showFeedback(false, options, error.message);
|
||||
throw error;
|
||||
}
|
||||
|
||||
const body = parse(await res.text());
|
||||
|
||||
if (res.ok) {
|
||||
showFeedback(true, options);
|
||||
return body;
|
||||
}
|
||||
|
||||
showFeedback(false, options, body.statusMessage);
|
||||
throw new Error(body.statusMessage);
|
||||
}
|
||||
|
||||
@@ -128,7 +128,8 @@ export async function fetchMoviesById(movieIds, reqUser) {
|
||||
.orderBy('priority', 'desc'),
|
||||
covers: knex('movies_covers')
|
||||
.whereIn('movie_id', movieIds)
|
||||
.leftJoin('media', 'media.id', 'movies_covers.media_id'),
|
||||
.leftJoin('media', 'media.id', 'movies_covers.media_id')
|
||||
.orderBy('media.index'),
|
||||
photos: knex('movies')
|
||||
.whereIn('movies.id', movieIds)
|
||||
.leftJoin('movies_scenes', 'movies_scenes.movie_id', 'movies.id')
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import config from 'config';
|
||||
import { CronJob } from 'cron';
|
||||
|
||||
import { knexOwner as knex } from './knex.js';
|
||||
import { indexApi } from './manticore.js';
|
||||
@@ -8,7 +9,10 @@ import initLogger from './logger.js';
|
||||
|
||||
const logger = initLogger();
|
||||
|
||||
let lastActorsViewRefresh = 0;
|
||||
const lastViewRefresh = {
|
||||
actors: 0,
|
||||
stashes: 0,
|
||||
};
|
||||
|
||||
export function curateStash(stash, assets = {}) {
|
||||
if (!stash) {
|
||||
@@ -85,11 +89,11 @@ export async function fetchStashByUsernameAndSlug(username, stashSlug, sessionUs
|
||||
export async function fetchStashes(domain, itemId, sessionUser) {
|
||||
const stashes = await knex(`stashes_${domain}s`)
|
||||
.select('stashes.*')
|
||||
.leftJoin('stashes', 'stashes.id', `stashes_${domain}s.stash_id`)
|
||||
.where({
|
||||
[`${domain}_id`]: itemId,
|
||||
user_id: sessionUser.id,
|
||||
})
|
||||
.leftJoin('stashes', 'stashes.id', `stashes_${domain}s.stash_id`);
|
||||
});
|
||||
|
||||
return stashes.map((stash) => curateStash(stash));
|
||||
}
|
||||
@@ -112,6 +116,24 @@ function verifyStashName(stash) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function refreshView(domain = 'stashes') {
|
||||
// throttle view refreshes
|
||||
if (new Date() - lastViewRefresh[domain] > config.stashes.viewRefreshCooldowns[domain] * 60000) {
|
||||
lastViewRefresh[domain] = new Date();
|
||||
|
||||
logger.verbose(`Refreshing ${domain} view`);
|
||||
|
||||
await knex.schema.refreshMaterializedView(`${domain}_meta`);
|
||||
await knex.schema.refreshMaterializedView('stashes_meta');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
logger.debug(`Skipping ${domain} view refresh`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function createStash(newStash, sessionUser) {
|
||||
if (!sessionUser) {
|
||||
throw new HttpError('You are not authenthicated', 401);
|
||||
@@ -184,21 +206,6 @@ export async function removeStash(stashId, sessionUser) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function refreshActorsView() {
|
||||
if (new Date() - lastActorsViewRefresh > config.stashes.viewRefreshCooldown * 60000) {
|
||||
// don't refresh actors view more than once an hour
|
||||
lastActorsViewRefresh = new Date();
|
||||
|
||||
logger.debug('Refreshing actors view');
|
||||
|
||||
return knex.schema.refreshMaterializedView('actors_meta');
|
||||
}
|
||||
|
||||
logger.silly('Skipping actors view refresh');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function stashActor(actorId, stashId, sessionUser) {
|
||||
const stash = await fetchStashById(stashId, sessionUser);
|
||||
|
||||
@@ -222,7 +229,7 @@ export async function stashActor(actorId, stashId, sessionUser) {
|
||||
|
||||
logger.verbose(`${sessionUser.username} (${sessionUser.id}) stashed actor ${actorId} to stash ${stash.id} (${stash.name})`);
|
||||
|
||||
refreshActorsView();
|
||||
refreshView('actors');
|
||||
|
||||
return fetchStashes('actor', actorId, sessionUser);
|
||||
}
|
||||
@@ -257,7 +264,7 @@ export async function unstashActor(actorId, stashId, sessionUser) {
|
||||
|
||||
logger.verbose(`${sessionUser.username} (${sessionUser.id}) unstashed actor ${actorId} from stash ${stashId}`);
|
||||
|
||||
refreshActorsView();
|
||||
refreshView('actors');
|
||||
|
||||
return fetchStashes('actor', actorId, sessionUser);
|
||||
}
|
||||
@@ -286,6 +293,8 @@ export async function stashScene(sceneId, stashId, sessionUser) {
|
||||
|
||||
logger.verbose(`${sessionUser.username} (${sessionUser.id}) stashed scene ${sceneId} to stash ${stash.id} (${stash.name})`);
|
||||
|
||||
refreshView('scenes');
|
||||
|
||||
return fetchStashes('scene', sceneId, sessionUser);
|
||||
}
|
||||
|
||||
@@ -315,6 +324,8 @@ export async function unstashScene(sceneId, stashId, sessionUser) {
|
||||
|
||||
logger.verbose(`${sessionUser.username} (${sessionUser.id}) unstashed scene ${sceneId} from stash ${stashId}`);
|
||||
|
||||
refreshView('scenes');
|
||||
|
||||
return fetchStashes('scene', sceneId, sessionUser);
|
||||
}
|
||||
|
||||
@@ -341,6 +352,8 @@ export async function stashMovie(movieId, stashId, sessionUser) {
|
||||
|
||||
logger.verbose(`${sessionUser.username} (${sessionUser.id}) stashed movie ${movieId} to stash ${stash.id} (${stash.name})`);
|
||||
|
||||
refreshView('movies');
|
||||
|
||||
return fetchStashes('movie', movieId, sessionUser);
|
||||
}
|
||||
|
||||
@@ -370,5 +383,21 @@ export async function unstashMovie(movieId, stashId, sessionUser) {
|
||||
|
||||
logger.verbose(`${sessionUser.username} (${sessionUser.id}) unstashed movie ${movieId} from stash ${stashId}`);
|
||||
|
||||
refreshView('movies');
|
||||
|
||||
return fetchStashes('movie', movieId, sessionUser);
|
||||
}
|
||||
|
||||
CronJob.from({
|
||||
cronTime: config.stashes.viewRefreshCron,
|
||||
async onTick() {
|
||||
logger.verbose('Updating stash views');
|
||||
|
||||
await refreshView('scenes');
|
||||
await refreshView('actors');
|
||||
await refreshView('movies');
|
||||
await refreshView('stashes');
|
||||
},
|
||||
start: true,
|
||||
runOnInit: true,
|
||||
});
|
||||
|
||||
@@ -51,13 +51,14 @@ export async function fetchUser(userId, options = {}, reqUser) {
|
||||
}
|
||||
|
||||
const stashes = await knex('stashes')
|
||||
.select('stashes.*', 'stashes_meta.*')
|
||||
.leftJoin('stashes_meta', 'stashes_meta.stash_id', 'stashes.id')
|
||||
.where('user_id', user.id)
|
||||
.modify((builder) => {
|
||||
if (reqUser?.id !== user.id && !options.includeStashes) {
|
||||
builder.where('public', true);
|
||||
}
|
||||
})
|
||||
.leftJoin('stashes_meta', 'stashes_meta.stash_id', 'stashes.id');
|
||||
});
|
||||
|
||||
if (options.raw) {
|
||||
return { user, stashes };
|
||||
|
||||
Reference in New Issue
Block a user