added AJAX loading for videos
This commit is contained in:
@@ -15,9 +15,9 @@ const epochs = [
|
||||
["second", 1]
|
||||
];
|
||||
const getDuration = timeAgoInSeconds => {
|
||||
for(let [name, seconds] of epochs) {
|
||||
for (let [name, seconds] of epochs) {
|
||||
const interval = ~~(timeAgoInSeconds / seconds);
|
||||
if(interval >= 1) return {
|
||||
if (interval >= 1) return {
|
||||
interval: interval,
|
||||
epoch: name
|
||||
};
|
||||
@@ -32,7 +32,9 @@ export default new class {
|
||||
return (Math.round((b * 8 / s / 1e6) * 1e4) / 1e4);
|
||||
};
|
||||
timeAgo(date) {
|
||||
const { interval, epoch } = getDuration(~~((new Date() - new Date(date)) / 1e3));
|
||||
const duration = getDuration(~~((new Date() - new Date(date)) / 1e3));
|
||||
if (!duration) return "just now";
|
||||
const { interval, epoch } = duration;
|
||||
return `${interval} ${epoch}${interval === 1 ? "" : "s"} ago`;
|
||||
};
|
||||
md5(str) {
|
||||
@@ -40,19 +42,19 @@ export default new class {
|
||||
};
|
||||
getMode(mode) {
|
||||
let tmp;
|
||||
switch(mode) {
|
||||
switch (mode) {
|
||||
case 1: // nsfw
|
||||
tmp = "items.id in (select item_id from tags_assign where tag_id = 2 group by item_id)";
|
||||
break;
|
||||
break;
|
||||
case 2: // untagged
|
||||
tmp = "items.id not in (select item_id from tags_assign group by item_id)";
|
||||
break;
|
||||
break;
|
||||
case 3: // all
|
||||
tmp = "1 = 1";
|
||||
break;
|
||||
break;
|
||||
default: // sfw
|
||||
tmp = "items.id in (select item_id from tags_assign where tag_id = 1 group by item_id)";
|
||||
break;
|
||||
break;
|
||||
}
|
||||
return tmp;
|
||||
};
|
||||
@@ -61,14 +63,14 @@ export default new class {
|
||||
};
|
||||
genLink(env) {
|
||||
const link = [];
|
||||
if(env.tag) link.push("tag", env.tag);
|
||||
if(env.user) link.push("user", env.user, env.type ?? 'f0cks');
|
||||
if(env.mime?.length > 2) link.push(env.mime);
|
||||
if (env.tag) link.push("tag", env.tag);
|
||||
if (env.user) link.push("user", env.user, env.type ?? 'f0cks');
|
||||
if (env.mime?.length > 2) link.push(env.mime);
|
||||
|
||||
let tmp = link.length === 0 ? '/' : link.join('/');
|
||||
if(!tmp.endsWith('/'))
|
||||
if (!tmp.endsWith('/'))
|
||||
tmp = tmp + '/';
|
||||
if(!tmp.startsWith('/'))
|
||||
if (!tmp.startsWith('/'))
|
||||
tmp = '/' + tmp;
|
||||
|
||||
return {
|
||||
@@ -77,7 +79,7 @@ export default new class {
|
||||
};
|
||||
};
|
||||
parseTag(tag) {
|
||||
if(!tag)
|
||||
if (!tag)
|
||||
return null;
|
||||
return decodeURI(tag);
|
||||
}
|
||||
@@ -129,7 +131,7 @@ export default new class {
|
||||
return "$f0ck$" + salt + ":" + derivedKey.toString("hex");
|
||||
};
|
||||
async verify(str, hash) {
|
||||
const [ salt, key ] = hash.substring(6).split(":");
|
||||
const [salt, key] = hash.substring(6).split(":");
|
||||
const keyBuffer = Buffer.from(key, "hex");
|
||||
const derivedKey = await scrypt(str, salt, 64);
|
||||
return crypto.timingSafeEqual(keyBuffer, derivedKey);
|
||||
@@ -143,20 +145,20 @@ export default new class {
|
||||
where "tags_assign".item_id = ${+itemid}
|
||||
order by "tags".id asc
|
||||
`;
|
||||
for(let t = 0; t < tags.length; t++) {
|
||||
if(tags[t].tag.startsWith(">"))
|
||||
for (let t = 0; t < tags.length; t++) {
|
||||
if (tags[t].tag.startsWith(">"))
|
||||
tags[t].badge = "badge-greentext badge-light";
|
||||
else if(tags[t].normalized === "ukraine")
|
||||
else if (tags[t].normalized === "ukraine")
|
||||
tags[t].badge = "badge-ukraine badge-light";
|
||||
else if(/[а-яё]/.test(tags[t].normalized) || tags[t].normalized === "russia")
|
||||
else if (/[а-яё]/.test(tags[t].normalized) || tags[t].normalized === "russia")
|
||||
tags[t].badge = "badge-russia badge-light";
|
||||
else if(tags[t].normalized === "german")
|
||||
else if (tags[t].normalized === "german")
|
||||
tags[t].badge = "badge-german badge-light";
|
||||
else if(tags[t].normalized === "dutch")
|
||||
else if (tags[t].normalized === "dutch")
|
||||
tags[t].badge = "badge-dutch badge-light";
|
||||
else if(tags[t].normalized === "sfw")
|
||||
else if (tags[t].normalized === "sfw")
|
||||
tags[t].badge = "badge-success";
|
||||
else if(tags[t].normalized === "nsfw")
|
||||
else if (tags[t].normalized === "nsfw")
|
||||
tags[t].badge = "badge-danger";
|
||||
else
|
||||
tags[t].badge = "badge-light";
|
||||
@@ -183,11 +185,11 @@ export default new class {
|
||||
const tmp = Object.values(res)[0];
|
||||
|
||||
let nsfw = false;
|
||||
if(tmp.neutral >= .7)
|
||||
if (tmp.neutral >= .7)
|
||||
nsfw = false;
|
||||
else if((tmp.sexy + tmp.porn + tmp.hentai) >= .7)
|
||||
else if ((tmp.sexy + tmp.porn + tmp.hentai) >= .7)
|
||||
nsfw = true;
|
||||
else if(tmp.drawings >= .4)
|
||||
else if (tmp.drawings >= .4)
|
||||
nsfw = false;
|
||||
else
|
||||
nsfw = false;
|
||||
@@ -197,7 +199,7 @@ export default new class {
|
||||
score: tmp.sexy + tmp.porn + tmp.hentai,
|
||||
scores: tmp
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
async getDefaultAvatar() {
|
||||
return (await db`
|
||||
@@ -212,7 +214,7 @@ export default new class {
|
||||
|
||||
// meddlware admin
|
||||
async auth(req, res, next) {
|
||||
if(!req.session || !req.session.admin) {
|
||||
if (!req.session || !req.session.admin) {
|
||||
return res.reply({
|
||||
code: 401,
|
||||
body: "401 - Unauthorized"
|
||||
@@ -223,7 +225,7 @@ export default new class {
|
||||
|
||||
// meddlware user
|
||||
async userauth(req, res, next) {
|
||||
if(!req.session) {
|
||||
if (!req.session) {
|
||||
return res.reply({
|
||||
code: 401,
|
||||
body: "401 - Unauthorized"
|
||||
@@ -232,14 +234,14 @@ export default new class {
|
||||
return next();
|
||||
};
|
||||
|
||||
async loggedin(req, res, next) {
|
||||
if(!req.session) {
|
||||
return res.reply({
|
||||
code: 401,
|
||||
body: "401 - Unauthorized"
|
||||
});
|
||||
}
|
||||
return next();
|
||||
async loggedin(req, res, next) {
|
||||
if (!req.session) {
|
||||
return res.reply({
|
||||
code: 401,
|
||||
body: "401 - Unauthorized"
|
||||
});
|
||||
}
|
||||
return next();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
68
src/inc/routes/ajax.mjs
Normal file
68
src/inc/routes/ajax.mjs
Normal file
@@ -0,0 +1,68 @@
|
||||
import f0cklib from "../routeinc/f0cklib.mjs";
|
||||
import url from "url";
|
||||
|
||||
export default (router, tpl) => {
|
||||
router.get(/\/ajax\/item\/(?<itemid>\d+)/, async (req, res) => {
|
||||
let query = {};
|
||||
if (typeof req.url === 'string') {
|
||||
const parsedUrl = url.parse(req.url, true);
|
||||
query = parsedUrl.query;
|
||||
} else {
|
||||
// flummpress uses req.url.qs for query string parameters
|
||||
query = req.url.qs || {};
|
||||
}
|
||||
|
||||
let contextUrl = `/${req.params.itemid}`;
|
||||
if (query.tag) contextUrl = `/tag/${query.tag}/${req.params.itemid}`;
|
||||
if (query.user) contextUrl = `/user/${query.user}/${req.params.itemid}`; // User filter takes precedence if both? usually mutually exclusive
|
||||
|
||||
const data = await f0cklib.getf0ck({
|
||||
itemid: req.params.itemid,
|
||||
mode: req.session.mode,
|
||||
session: !!req.session,
|
||||
url: contextUrl,
|
||||
user: query.user,
|
||||
tag: query.tag,
|
||||
mime: query.mime
|
||||
});
|
||||
|
||||
if (!data.success) {
|
||||
return res.reply({
|
||||
code: 404,
|
||||
body: "<h1>404 - Not f0cked</h1>"
|
||||
});
|
||||
}
|
||||
|
||||
// Inject session into data for the template
|
||||
// We clone session to avoid unintended side effects or collisions
|
||||
if (req.session) {
|
||||
data.session = { ...req.session };
|
||||
// data.user comes from f0cklib (uploader). req.session.user is logged-in user string.
|
||||
// If template engine confuses them, removing session.user from this context might help.
|
||||
// item-partial doesn't use session.user.
|
||||
// Note: If anything fails, it prints literal code, so we ensure no collision.
|
||||
if (data.session.user) delete data.session.user;
|
||||
} else {
|
||||
data.session = false;
|
||||
}
|
||||
|
||||
// Inject missing variables normally provided by req or middleware
|
||||
data.url = { pathname: `/${req.params.itemid}` }; // Template expects url.pathname
|
||||
data.fullscreen = req.cookies.fullscreen || 0; // Index.mjs uses req.cookies.fullscreen
|
||||
|
||||
// Render both the item content and the pagination
|
||||
const itemHtml = tpl.render('ajax-item', data);
|
||||
const paginationHtml = tpl.render('snippets/pagination', data);
|
||||
|
||||
// Return JSON response
|
||||
return res.reply({
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
html: itemHtml,
|
||||
pagination: paginationHtml
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
return router;
|
||||
};
|
||||
Reference in New Issue
Block a user