Added elaborate template switching.

This commit is contained in:
2024-08-26 06:15:22 +02:00
parent fa991c0294
commit 80d8a8109a
29 changed files with 617 additions and 180 deletions

View File

@@ -5,7 +5,7 @@ import { login, signup } from '../auth.js';
import { fetchUser } from '../users.js';
function getIp(req) {
const ip = req.headers['x-forwarded-for']?.split(',')[0] || req.connection.remoteAddress; // See src/ws
const ip = req.headers['x-forwarded-for']?.split(',')[0] || req.connection.remoteAddress;
const unmappedIp = ip?.includes('.')
? ip.slice(ip.lastIndexOf(':') + 1)

70
src/web/main.js Normal file
View File

@@ -0,0 +1,70 @@
import config from 'config';
import { renderPage } from 'vike/server'; // eslint-disable-line import/extensions
import { fetchUserStashes } from '../stashes.js';
import { fetchUserTemplates } from '../users.js';
import { fetchUnseenNotificationsCount } from '../alerts.js';
export default async function mainHandler(req, res, next) {
const [stashes, templates, unseenNotifications] = req.user && await Promise.all([
fetchUserStashes(req.user.id, req.user),
fetchUserTemplates(req.user),
fetchUnseenNotificationsCount(req.user),
]);
const pageContextInit = {
urlOriginal: req.originalUrl,
urlQuery: req.query, // vike's own query does not apply boolean parser
headers: req.headers,
cookies: req.cookies,
tagFilter: req.tagFilter,
user: req.user && {
id: req.user.id,
username: req.user.username,
email: req.user.email,
avatar: req.user.avatar,
},
assets: req.user ? {
stashes,
primaryStash: stashes.find((stash) => stash.isPrimary),
templates,
} : null,
env: {
theme: req.cookies.theme || req.headers['sec-ch-prefers-color-scheme'] || 'light',
selectedTemplate: Number(req.cookies.selectedTemplate) || 0,
allowLogin: config.auth.login,
allowSignup: config.auth.signup,
maxMatches: config.database.manticore.maxMatches,
maxAggregateSize: config.database.manticore.maxAggregateSize,
media: config.media,
psa: config.psa,
links: config.links,
},
meta: {
unseenNotifications,
},
};
const pageContext = await renderPage(pageContextInit);
const { httpResponse } = pageContext;
if (pageContext.errorWhileRendering) {
console.error(pageContext.errorWhileRendering);
}
if (!httpResponse) {
next();
return;
}
/*
if (res.writeEarlyHints) {
res.writeEarlyHints({ link: httpResponse.earlyHints.map((e) => e.earlyHintLink) });
}
*/
httpResponse.headers.forEach(([name, value]) => res.setHeader(name, value));
res.status(httpResponse.statusCode);
// For HTTP streams use httpResponse.pipe() instead, see https://vike.dev/stream
res.send(httpResponse.body);
}

View File

@@ -7,7 +7,6 @@ import session from 'express-session';
import RedisStore from 'connect-redis';
import compression from 'compression';
import cookie from 'cookie';
import { renderPage } from 'vike/server'; // eslint-disable-line import/extensions
import redis from '../redis.js';
@@ -22,6 +21,8 @@ import { fetchTagsApi } from './tags.js';
import { graphqlApi } from './graphql.js';
import mainHandler from './main.js';
import {
setUserApi,
loginApi,
@@ -31,9 +32,13 @@ import {
import {
fetchUserApi,
fetchUserTemplatesApi,
createTemplateApi,
removeTemplateApi,
} from './users.js';
import {
fetchUserStashesApi,
createStashApi,
removeStashApi,
stashActorApi,
@@ -54,8 +59,6 @@ import {
updateNotificationsApi,
} from './alerts.js';
import { fetchUnseenNotificationsCount } from '../alerts.js';
import initLogger from '../logger.js';
const logger = initLogger();
@@ -141,6 +144,7 @@ export default async function initServer() {
router.patch('/api/users/:userId/notifications/:notificationId', updateNotificationApi);
// STASHES
router.get('/api/users/:userId/stashes', fetchUserStashesApi);
router.post('/api/stashes', createStashApi);
router.patch('/api/stashes/:stashId', updateStashApi);
router.delete('/api/stashes/:stashId', removeStashApi);
@@ -153,6 +157,11 @@ export default async function initServer() {
router.delete('/api/stashes/:stashId/scenes/:sceneId', unstashSceneApi);
router.delete('/api/stashes/:stashId/movies/:movieId', unstashMovieApi);
// SUMMARY TEMPLATES
router.get('/api/users/:userId/templates', fetchUserTemplatesApi);
router.post('/api/templates', createTemplateApi);
router.delete('/api/templates/:templateId', removeTemplateApi);
// ALERTS
router.get('/api/alerts', fetchAlertsApi);
router.post('/api/alerts', createAlertApi);
@@ -186,61 +195,7 @@ export default async function initServer() {
next();
});
router.get('*', async (req, res, next) => {
const unseenNotifications = await fetchUnseenNotificationsCount(req.user);
const pageContextInit = {
urlOriginal: req.originalUrl,
urlQuery: req.query, // vike's own query does not apply boolean parser
headers: req.headers,
cookies: req.cookies,
tagFilter: req.tagFilter,
user: req.user && {
id: req.user.id,
username: req.user.username,
email: req.user.email,
avatar: req.user.avatar,
stashes: req.user.stashes,
primaryStash: req.user.primaryStash,
},
env: {
theme: req.cookies.theme || req.headers['sec-ch-prefers-color-scheme'] || 'light',
allowLogin: config.auth.login,
allowSignup: config.auth.signup,
maxMatches: config.database.manticore.maxMatches,
maxAggregateSize: config.database.manticore.maxAggregateSize,
media: config.media,
psa: config.psa,
links: config.links,
},
meta: {
unseenNotifications,
},
};
const pageContext = await renderPage(pageContextInit);
const { httpResponse } = pageContext;
if (pageContext.errorWhileRendering) {
console.error(pageContext.errorWhileRendering);
}
if (!httpResponse) {
next();
return;
}
/*
if (res.writeEarlyHints) {
res.writeEarlyHints({ link: httpResponse.earlyHints.map((e) => e.earlyHintLink) });
}
*/
httpResponse.headers.forEach(([name, value]) => res.setHeader(name, value));
res.status(httpResponse.statusCode);
// For HTTP streams use httpResponse.pipe() instead, see https://vike.dev/stream
res.send(httpResponse.body);
});
router.get('*', mainHandler);
router.use(errorHandler);
app.use(router);

View File

@@ -1,4 +1,5 @@
import {
fetchUserStashes,
createStash,
removeStash,
stashActor,
@@ -10,27 +11,26 @@ import {
updateStash,
} from '../stashes.js';
import { updateSessionUser } from './auth.js';
export async function fetchUserStashesApi(req, res) {
const stashes = await fetchUserStashes(req.user.id, req.user);
res.send(stashes);
}
export async function createStashApi(req, res) {
const stash = await createStash(req.body, req.session.user);
await updateSessionUser(req);
const stash = await createStash(req.body, req.user);
res.send(stash);
}
export async function updateStashApi(req, res) {
const stash = await updateStash(Number(req.params.stashId), req.body, req.session.user);
await updateSessionUser(req);
const stash = await updateStash(Number(req.params.stashId), req.body, req.user);
res.send(stash);
}
export async function removeStashApi(req, res) {
await removeStash(Number(req.params.stashId), req.session.user);
await updateSessionUser(req);
await removeStash(Number(req.params.stashId), req.user);
res.status(204).send();
}

View File

@@ -1,7 +1,32 @@
import { fetchUser } from '../users.js';
import { stringify } from '@brillout/json-serializer/stringify'; /* eslint-disable-line import/extensions */
import {
fetchUser,
fetchUserTemplates,
createTemplate,
removeTemplate,
} from '../users.js';
export async function fetchUserApi(req, res) {
const user = await fetchUser(req.params.userId, {}, req.user);
res.send(user);
res.send(stringify(user));
}
export async function fetchUserTemplatesApi(req, res) {
const templates = await fetchUserTemplates(req.user);
res.send(templates);
}
export async function createTemplateApi(req, res) {
const template = await createTemplate(req.body, req.user);
res.send(stringify(template));
}
export async function removeTemplateApi(req, res) {
await removeTemplate(req.params.templateId, req.user);
res.status(204).send();
}