Compare commits
5 Commits
eins-patch
...
964284d5c9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
964284d5c9 | ||
|
|
9b1041dda7 | ||
|
|
45f9345e9c | ||
|
|
c74e5a7402 | ||
|
|
6799ec1567 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@ deleted/b
|
|||||||
deleted/ca
|
deleted/ca
|
||||||
deleted/t
|
deleted/t
|
||||||
tmp/*
|
tmp/*
|
||||||
|
tools
|
||||||
15
debug/check_last_item.mjs
Normal file
15
debug/check_last_item.mjs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import db from "../src/inc/sql.mjs";
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const item = (await db`select * from items order by id desc limit 1`)?.[0];
|
||||||
|
console.log("Last Item:", item);
|
||||||
|
if (item) {
|
||||||
|
const tags = await db`select * from tags_assign where item_id = ${item.id}`;
|
||||||
|
console.log("Tags:", tags);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
process.exit(0);
|
||||||
|
})();
|
||||||
@@ -6,13 +6,14 @@ import { promises as fs } from "fs";
|
|||||||
network: "console",
|
network: "console",
|
||||||
message: _args.join(" "),
|
message: _args.join(" "),
|
||||||
args: _args.slice(1),
|
args: _args.slice(1),
|
||||||
channel: "console",
|
channel: "#w0bm",
|
||||||
user: {
|
user: {
|
||||||
prefix: "console!console@console",
|
prefix: "console!console@console",
|
||||||
nick: "console",
|
nick: "console",
|
||||||
username: "console",
|
username: "console",
|
||||||
account: "console"
|
account: "console"
|
||||||
},
|
},
|
||||||
|
raw: {},
|
||||||
reply: (...args) => console.log(args),
|
reply: (...args) => console.log(args),
|
||||||
replyAction: (...args) => console.log(args),
|
replyAction: (...args) => console.log(args),
|
||||||
replyNotice: (...args) => console.log(args)
|
replyNotice: (...args) => console.log(args)
|
||||||
@@ -24,11 +25,14 @@ import { promises as fs } from "fs";
|
|||||||
)).filter(t => t[0].call.test(_e.message)).map(t => ({ name: t[0].name, f: t[0].f }));
|
)).filter(t => t[0].call.test(_e.message)).map(t => ({ name: t[0].name, f: t[0].f }));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(trigger.length === 0)
|
if (trigger.length === 0)
|
||||||
return console.error("no matches");
|
return console.error("no matches");
|
||||||
console.log(`triggered > ${trigger[0].name} (${_e.message})`);
|
for (const t of trigger) {
|
||||||
await trigger[0].f(_e);
|
console.log(`triggered > ${t.name} (${_e.message})`);
|
||||||
} catch(err) {
|
await t.f(_e);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
process.exit(0);
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1197,7 +1197,9 @@ body {
|
|||||||
overscroll-behavior-y: contain;
|
overscroll-behavior-y: contain;
|
||||||
overflow: unset;
|
overflow: unset;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
height: /* 100%; */auto;
|
height:
|
||||||
|
/* 100%; */
|
||||||
|
auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
@@ -1318,6 +1320,13 @@ div.posts>a:hover::after {
|
|||||||
grid-template-columns: auto 1fr 0fr;
|
grid-template-columns: auto 1fr 0fr;
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
border-bottom: 1px solid var(--nav-border-color);
|
border-bottom: 1px solid var(--nav-border-color);
|
||||||
|
background: var(--nav-bg);
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar.scrolled {
|
||||||
|
background: #000 !important;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-brand {
|
.navbar-brand {
|
||||||
@@ -1424,7 +1433,7 @@ ul.navbar-nav li.nav-item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav-link[data-toggle="dropdown"].ddcontent::after {
|
.nav-link[data-toggle="dropdown"].ddcontent::after {
|
||||||
content: "\00a0("attr(content) ")\00a0\25bc";
|
content: "\00a0(" attr(content) ")\00a0\25bc";
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link[data-toggle="dropdown"]:not(.ddcontent)::after {
|
.nav-link[data-toggle="dropdown"]:not(.ddcontent)::after {
|
||||||
@@ -1608,7 +1617,7 @@ span.placeholder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1325px) {
|
@media (max-width: 1325px) {
|
||||||
/* ranking page - idea */
|
/* ranking page - idea */
|
||||||
/* .ranking {
|
/* .ranking {
|
||||||
grid-template-columns: 1fr 1fr !important;
|
grid-template-columns: 1fr 1fr !important;
|
||||||
} */
|
} */
|
||||||
@@ -1783,8 +1792,9 @@ span.placeholder {
|
|||||||
.index-container {
|
.index-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
/* background-color: var(--navigation-links-bg);
|
/* background-color: var(--navigation-links-bg);
|
||||||
*/}
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 361px) {
|
@media (min-width: 361px) {
|
||||||
.embed-responsive-image {
|
.embed-responsive-image {
|
||||||
@@ -2779,7 +2789,9 @@ ul.navbar-nav-guests li.nav-item {
|
|||||||
margin-right: .5rem;
|
margin-right: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-expand-lg .navbar-nav-guests .nav-link, .pagination > a, .pagination > span {
|
.navbar-expand-lg .navbar-nav-guests .nav-link,
|
||||||
|
.pagination>a,
|
||||||
|
.pagination>span {
|
||||||
padding-right: .5rem;
|
padding-right: .5rem;
|
||||||
padding-left: .5rem;
|
padding-left: .5rem;
|
||||||
}
|
}
|
||||||
@@ -2812,12 +2824,16 @@ ul.navbar-nav-guests li.nav-item {
|
|||||||
|
|
||||||
/* Pagination Responsiveness */
|
/* Pagination Responsiveness */
|
||||||
@media (max-width: 799px) {
|
@media (max-width: 799px) {
|
||||||
.navbar-expand-lg .navbar-nav-guests .nav-link, .pagination > a, .pagination > span {
|
|
||||||
|
.navbar-expand-lg .navbar-nav-guests .nav-link,
|
||||||
|
.pagination>a,
|
||||||
|
.pagination>span {
|
||||||
padding-right: 2px;
|
padding-right: 2px;
|
||||||
padding-left: 2px;
|
padding-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination > a, .pagination > span {
|
.pagination>a,
|
||||||
|
.pagination>span {
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
@@ -2832,12 +2848,16 @@ ul.navbar-nav-guests li.nav-item {
|
|||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
img#f0ck-image, div.imageDoor, div.posts a, video {
|
img#f0ck-image,
|
||||||
|
div.imageDoor,
|
||||||
|
div.posts a,
|
||||||
|
video {
|
||||||
animation: 1s ease-out 0s 1 fadeInFX;
|
animation: 1s ease-out 0s 1 fadeInFX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2892,11 +2912,13 @@ img#f0ck-image, div.imageDoor, div.posts a, video {
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.f0cks h5, .favs h5 {
|
.f0cks h5,
|
||||||
|
.favs h5 {
|
||||||
background: var(--dropdown-bg);
|
background: var(--dropdown-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.f0cks-header, .favs-header {
|
.f0cks-header,
|
||||||
|
.favs-header {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr auto;
|
grid-template-columns: 1fr auto;
|
||||||
background: var(--img-border-color);
|
background: var(--img-border-color);
|
||||||
@@ -2940,7 +2962,8 @@ button#togglebg {
|
|||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
100% {
|
|
||||||
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2949,7 +2972,8 @@ button#togglebg {
|
|||||||
0% {
|
0% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
100% {
|
|
||||||
|
100% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2959,6 +2983,7 @@ button#togglebg {
|
|||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
@@ -2968,6 +2993,7 @@ button#togglebg {
|
|||||||
0% {
|
0% {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@@ -3004,6 +3030,7 @@ input#s_avatar {
|
|||||||
#s_avatar:hover {
|
#s_avatar:hover {
|
||||||
background: #ffffff0f;
|
background: #ffffff0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theforceofthree {
|
.theforceofthree {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 0.4fr 1fr 0.4fr;
|
grid-template-columns: 0.4fr 1fr 0.4fr;
|
||||||
@@ -3012,3 +3039,23 @@ input#s_avatar {
|
|||||||
.upload {
|
.upload {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Infinite scroll loading indicator */
|
||||||
|
.loading-spinner {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--footbar-color);
|
||||||
|
animation: pulse 1s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -130,12 +130,12 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
renderTags(res.tags);
|
renderTags(res.tags);
|
||||||
span.parentElement.removeChild(span);
|
if (span.parentElement) span.parentElement.removeChild(span);
|
||||||
testList.innerText = "";
|
testList.innerText = "";
|
||||||
addtagClick();
|
addtagClick();
|
||||||
}
|
}
|
||||||
else if (e.key === "Escape") {
|
else if (e.key === "Escape") {
|
||||||
span.parentElement.removeChild(span);
|
if (span.parentElement) span.parentElement.removeChild(span);
|
||||||
testList.innerText = "";
|
testList.innerText = "";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -68,6 +68,18 @@ window.requestAnimFrame = (function () {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Navbar scroll effect - make background black when scrolling
|
||||||
|
const navbar = document.querySelector('.navbar');
|
||||||
|
if (navbar) {
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 50) {
|
||||||
|
navbar.classList.add('scrolled');
|
||||||
|
} else {
|
||||||
|
navbar.classList.remove('scrolled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const loadItemAjax = async (url, inheritContext = true) => {
|
const loadItemAjax = async (url, inheritContext = true) => {
|
||||||
console.log("loadItemAjax called with:", url, "inheritContext:", inheritContext);
|
console.log("loadItemAjax called with:", url, "inheritContext:", inheritContext);
|
||||||
// Show loading indicator
|
// Show loading indicator
|
||||||
@@ -140,7 +152,7 @@ window.requestAnimFrame = (function () {
|
|||||||
html = rawText;
|
html = rawText;
|
||||||
}
|
}
|
||||||
|
|
||||||
let container = document.querySelector('.container');
|
let container = document.querySelector('#main .container');
|
||||||
|
|
||||||
if (!container && document.querySelector('.index-container')) {
|
if (!container && document.querySelector('.index-container')) {
|
||||||
// Transition from Index to Item View
|
// Transition from Index to Item View
|
||||||
@@ -148,6 +160,11 @@ window.requestAnimFrame = (function () {
|
|||||||
main.innerHTML = '<div class="container"></div>';
|
main.innerHTML = '<div class="container"></div>';
|
||||||
container = main.querySelector('.container');
|
container = main.querySelector('.container');
|
||||||
} else if (container) {
|
} else if (container) {
|
||||||
|
// Check if we are on Tags Overview logic (which reuses .container)
|
||||||
|
const tagsOverview = container.querySelector('.tags');
|
||||||
|
if (tagsOverview) {
|
||||||
|
container.innerHTML = '';
|
||||||
|
} else {
|
||||||
// Already in Item View, clear usage
|
// Already in Item View, clear usage
|
||||||
const oldContent = container.querySelector('.content');
|
const oldContent = container.querySelector('.content');
|
||||||
const oldMetadata = container.querySelector('.metadata');
|
const oldMetadata = container.querySelector('.metadata');
|
||||||
@@ -156,6 +173,7 @@ window.requestAnimFrame = (function () {
|
|||||||
if (oldContent) oldContent.remove();
|
if (oldContent) oldContent.remove();
|
||||||
if (oldMetadata) oldMetadata.remove();
|
if (oldMetadata) oldMetadata.remove();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
container.insertAdjacentHTML('beforeend', html);
|
container.insertAdjacentHTML('beforeend', html);
|
||||||
|
|
||||||
@@ -187,13 +205,12 @@ window.requestAnimFrame = (function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const changePage = (e, pbwork = true) => {
|
const changePage = (e, pbwork = true) => {
|
||||||
if (e.tagName === 'A') {
|
if (pbwork) {
|
||||||
e.preventDefault();
|
const nav = document.querySelector("nav.navbar");
|
||||||
loadItemAjax(e.href);
|
if (nav) nav.classList.add("pbwork");
|
||||||
} else {
|
|
||||||
pbwork && document.querySelector("nav.navbar").classList.add("pbwork");
|
|
||||||
!tt && (tt = setTimeout(() => e.click(), stimeout));
|
|
||||||
}
|
}
|
||||||
|
// Trigger native click for navigation
|
||||||
|
e.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Intercept clicks
|
// Intercept clicks
|
||||||
@@ -208,10 +225,10 @@ window.requestAnimFrame = (function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const link = e.target.closest('#next, #prev, #random, .id-link, .nav-next, .nav-prev');
|
const link = e.target.closest('#next, #prev, #random, #nav-random, .id-link, .nav-next, .nav-prev');
|
||||||
if (link && link.href && link.hostname === window.location.hostname && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey) {
|
if (link && link.href && link.hostname === window.location.hostname && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey) {
|
||||||
// Special check for random
|
// Special check for random
|
||||||
if (link.id === 'random') {
|
if (link.id === 'random' || link.id === 'nav-random') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const nav = document.querySelector("nav.navbar");
|
const nav = document.querySelector("nav.navbar");
|
||||||
if (nav) nav.classList.add("pbwork");
|
if (nav) nav.classList.add("pbwork");
|
||||||
@@ -240,7 +257,10 @@ window.requestAnimFrame = (function () {
|
|||||||
window.location.href = link.href;
|
window.location.href = link.href;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => window.location.href = link.href);
|
.catch((err) => {
|
||||||
|
console.error("Random fetch failed:", err);
|
||||||
|
window.location.href = link.href;
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +281,7 @@ window.requestAnimFrame = (function () {
|
|||||||
"a": clickOnElementBinding("#next"),
|
"a": clickOnElementBinding("#next"),
|
||||||
"ArrowRight": clickOnElementBinding("#prev"),
|
"ArrowRight": clickOnElementBinding("#prev"),
|
||||||
"d": clickOnElementBinding("#prev"),
|
"d": clickOnElementBinding("#prev"),
|
||||||
"r": clickOnElementBinding("#random"),
|
"r": clickOnElementBinding("#random, #nav-random"),
|
||||||
" ": clickOnElementBinding("#f0ck-image")
|
" ": clickOnElementBinding("#f0ck-image")
|
||||||
};
|
};
|
||||||
document.addEventListener("keydown", e => {
|
document.addEventListener("keydown", e => {
|
||||||
@@ -327,59 +347,116 @@ window.requestAnimFrame = (function () {
|
|||||||
}
|
}
|
||||||
// </image-responsive>
|
// </image-responsive>
|
||||||
|
|
||||||
// <scroller>
|
// <infinite-scroll>
|
||||||
let tts = 0;
|
const postsContainer = document.querySelector("div.posts");
|
||||||
const scroll_treshold = 1;
|
if (postsContainer) {
|
||||||
if ([...document.querySelectorAll("div.posts")].length === 1) {
|
// Infinite scroll state
|
||||||
document.addEventListener("wheel", e => {
|
let infiniteState = {
|
||||||
|
loading: false,
|
||||||
|
hasMore: true,
|
||||||
|
currentPage: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extract current page from URL
|
||||||
|
const pageMatch = window.location.pathname.match(/\/p\/(\d+)/);
|
||||||
|
if (pageMatch) infiniteState.currentPage = parseInt(pageMatch[1]);
|
||||||
|
|
||||||
|
// Extract context (tag/user/mime) from URL
|
||||||
|
const getContext = () => {
|
||||||
|
const ctx = {};
|
||||||
|
const tagMatch = window.location.pathname.match(/\/tag\/([^/]+)/);
|
||||||
|
if (tagMatch) ctx.tag = decodeURIComponent(tagMatch[1]);
|
||||||
|
const userMatch = window.location.pathname.match(/\/user\/([^/]+)/);
|
||||||
|
if (userMatch) ctx.user = decodeURIComponent(userMatch[1]);
|
||||||
|
const mimeMatch = window.location.pathname.match(/\/(image|audio|video)(?:\/|$)/);
|
||||||
|
if (mimeMatch) ctx.mime = mimeMatch[1];
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build URL path for history
|
||||||
|
const buildUrl = (page) => {
|
||||||
|
const ctx = getContext();
|
||||||
|
let path = '/';
|
||||||
|
if (ctx.tag) path += `tag/${ctx.tag}/`;
|
||||||
|
if (ctx.user) path += `user/${ctx.user}/`;
|
||||||
|
if (ctx.mime) path += `${ctx.mime}/`;
|
||||||
|
if (page > 1) path += `p/${page}`;
|
||||||
|
return path.replace(/\/$/, '') || '/';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fetch and append more items
|
||||||
|
const loadMoreItems = async () => {
|
||||||
|
if (infiniteState.loading || !infiniteState.hasMore) return;
|
||||||
|
|
||||||
|
infiniteState.loading = true;
|
||||||
|
const foot = document.querySelector("div#footbar");
|
||||||
|
if (foot) {
|
||||||
|
foot.innerHTML = '<span class="loading-spinner">Loading...</span>';
|
||||||
|
foot.style.color = 'var(--footbar-color)';
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextPage = infiniteState.currentPage + 1;
|
||||||
|
const ctx = getContext();
|
||||||
|
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.append('page', nextPage);
|
||||||
|
if (ctx.tag) params.append('tag', ctx.tag);
|
||||||
|
if (ctx.user) params.append('user', ctx.user);
|
||||||
|
if (ctx.mime) params.append('mime', ctx.mime);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/ajax/items?${params.toString()}`);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.success && data.html) {
|
||||||
|
// Append new thumbnails
|
||||||
|
postsContainer.insertAdjacentHTML('beforeend', data.html);
|
||||||
|
|
||||||
|
// Update state
|
||||||
|
infiniteState.currentPage = data.currentPage;
|
||||||
|
infiniteState.hasMore = data.hasMore;
|
||||||
|
|
||||||
|
// Update URL
|
||||||
|
history.replaceState({}, '', buildUrl(infiniteState.currentPage));
|
||||||
|
|
||||||
|
// Update pagination display if exists
|
||||||
|
const paginationLinks = document.querySelectorAll('.pagination .pagination-int-item, .pagination .btn');
|
||||||
|
paginationLinks.forEach(el => {
|
||||||
|
if (el.textContent.trim() == infiniteState.currentPage) {
|
||||||
|
el.classList.add('disabled');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
infiniteState.hasMore = false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Infinite scroll fetch error:', err);
|
||||||
|
} finally {
|
||||||
|
infiniteState.loading = false;
|
||||||
|
if (foot) {
|
||||||
|
foot.innerHTML = infiniteState.hasMore ? '▼' : '—';
|
||||||
|
foot.style.color = 'transparent';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Scroll detection - preload before reaching bottom
|
||||||
|
const PRELOAD_OFFSET = 500; // pixels before bottom to trigger load
|
||||||
|
|
||||||
|
window.addEventListener("scroll", () => {
|
||||||
if (!document.querySelector('#main')) return;
|
if (!document.querySelector('#main')) return;
|
||||||
|
|
||||||
if (Math.ceil(window.innerHeight + window.scrollY) >= document.querySelector('#main').offsetHeight && e.deltaY > 0) { // down
|
const scrollPosition = window.innerHeight + window.scrollY;
|
||||||
if (elem = document.querySelector(".pagination > .next:not(.disabled)")) {
|
const pageHeight = document.querySelector('#main').offsetHeight;
|
||||||
if (tts < scroll_treshold) {
|
const distanceFromBottom = pageHeight - scrollPosition;
|
||||||
const foot = document.querySelector("div#footbar");
|
|
||||||
if (foot) {
|
// Load more when within PRELOAD_OFFSET pixels of bottom
|
||||||
foot.style.boxShadow = "inset 0px 4px 0px var(--footbar-color)";
|
if (distanceFromBottom < PRELOAD_OFFSET && infiniteState.hasMore && !infiniteState.loading) {
|
||||||
foot.style.color = "var(--footbar-color)";
|
loadMoreItems();
|
||||||
}
|
|
||||||
tts++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
changePage(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (window.scrollY <= 0 && e.deltaY < 0) { // up
|
|
||||||
if (elem = document.querySelector(".pagination > .prev:not(.disabled)")) {
|
|
||||||
if (tts < scroll_treshold) {
|
|
||||||
const nav = document.querySelector("nav.navbar");
|
|
||||||
if (nav) {
|
|
||||||
nav.style.boxShadow = "0px 2px 0px var(--loading-indicator-color)";
|
|
||||||
nav.style.transition = ".2s ease-in-out";
|
|
||||||
}
|
|
||||||
tts++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
changePage(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tts = 0;
|
|
||||||
const foot = document.querySelector("div#footbar");
|
|
||||||
if (foot) {
|
|
||||||
foot.style.boxShadow = "unset";
|
|
||||||
foot.style.color = "transparent";
|
|
||||||
}
|
|
||||||
const nav = document.querySelector("nav.navbar");
|
|
||||||
if (nav) nav.style.boxShadow = "unset";
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// </infinite-scroll>
|
||||||
const rmatch = /\/p\/(\d+?)/;
|
|
||||||
if (document.referrer.match(rmatch) && document.location.href.match(rmatch))
|
|
||||||
if (document.location.href.match(rmatch) < document.referrer.match(rmatch))
|
|
||||||
document.body.scrollTop = document.body.scrollHeight;
|
|
||||||
// </scroller>
|
|
||||||
|
|
||||||
// <swipe>
|
// <swipe>
|
||||||
const swipeRT = {
|
const swipeRT = {
|
||||||
@@ -541,10 +618,13 @@ function init() {
|
|||||||
|
|
||||||
window.addEventListener('load', init);
|
window.addEventListener('load', init);
|
||||||
|
|
||||||
document.getElementById('sbtForm').addEventListener('submit', (e) => {
|
const sbtForm = document.getElementById('sbtForm');
|
||||||
|
if (sbtForm) {
|
||||||
|
sbtForm.addEventListener('submit', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const input = document.getElementById('sbtInput').value.trim();
|
const input = document.getElementById('sbtInput').value.trim();
|
||||||
if (input) {
|
if (input) {
|
||||||
window.location.href = `/tag/${encodeURIComponent(input)}`;
|
window.location.href = `/tag/${encodeURIComponent(input)}`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
const Cookie = {
|
const Cookie = {
|
||||||
get: name => {
|
get: name => {
|
||||||
const c = document.cookie.match(`(?:(?:^|.*; *)${name} *= *([^;]*).*$)|^.*$`)[1];
|
const c = document.cookie.match(`(?:(?:^|.*; *)${name} *= *([^;]*).*$)|^.*$`)[1];
|
||||||
if(c) return decodeURIComponent(c);
|
if (c) return decodeURIComponent(c);
|
||||||
},
|
},
|
||||||
set: (name, value, opts = {}) => {
|
set: (name, value, opts = {}) => {
|
||||||
if(opts.days) {
|
if (opts.days) {
|
||||||
opts['max-age'] = opts.days * 60 * 60 * 24;
|
opts['max-age'] = opts.days * 60 * 60 * 24;
|
||||||
delete opts.days;
|
delete opts.days;
|
||||||
}
|
}
|
||||||
@@ -17,8 +17,11 @@ const Cookie = {
|
|||||||
(() => {
|
(() => {
|
||||||
const acttheme = Cookie.get('theme') ?? "w0bm";
|
const acttheme = Cookie.get('theme') ?? "w0bm";
|
||||||
const themecontainer = document.querySelector("li#themes > ul.dropdown-menu");
|
const themecontainer = document.querySelector("li#themes > ul.dropdown-menu");
|
||||||
|
|
||||||
|
if (!themecontainer) return; // Theme menu not present on this page
|
||||||
|
|
||||||
const themes = [...themecontainer.querySelectorAll("li > a")].map(t => t.innerText.toLowerCase());
|
const themes = [...themecontainer.querySelectorAll("li > a")].map(t => t.innerText.toLowerCase());
|
||||||
if(acttheme !== document.documentElement.getAttribute("theme") && themes.includes(acttheme))
|
if (acttheme !== document.documentElement.getAttribute("theme") && themes.includes(acttheme))
|
||||||
document.documentElement.setAttribute("theme", acttheme);
|
document.documentElement.setAttribute("theme", acttheme);
|
||||||
[...themecontainer.querySelectorAll("li > a")].forEach(t => t.addEventListener("click", e => {
|
[...themecontainer.querySelectorAll("li > a")].forEach(t => t.addEventListener("click", e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -30,15 +33,15 @@ const Cookie = {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
document.addEventListener("keydown", e => {
|
document.addEventListener("keydown", e => {
|
||||||
if(e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA")
|
if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA")
|
||||||
return;
|
return;
|
||||||
const acttheme = Cookie.get('theme') ?? "w0bm";
|
const acttheme = Cookie.get('theme') ?? "w0bm";
|
||||||
const themes = [...themecontainer.querySelectorAll("li > a")].map(t => t.innerText.toLowerCase());
|
const themes = [...themecontainer.querySelectorAll("li > a")].map(t => t.innerText.toLowerCase());
|
||||||
const k = e.key;
|
const k = e.key;
|
||||||
if(k === "t") {
|
if (k === "t") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let i = themes.indexOf(acttheme);
|
let i = themes.indexOf(acttheme);
|
||||||
if(++i >= themes.length)
|
if (++i >= themes.length)
|
||||||
i = 0;
|
i = 0;
|
||||||
document.documentElement.setAttribute("theme", themes[i]);
|
document.documentElement.setAttribute("theme", themes[i]);
|
||||||
document.querySelector("#themes > a").setAttribute("content", themes[i]);
|
document.querySelector("#themes > a").setAttribute("content", themes[i]);
|
||||||
@@ -46,10 +49,10 @@ const Cookie = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(tbuttonfull = document.querySelector('svg#a_tfull')) {
|
if (tbuttonfull = document.querySelector('svg#a_tfull')) {
|
||||||
tbuttonfull.addEventListener('click', e => {
|
tbuttonfull.addEventListener('click', e => {
|
||||||
let f = Cookie.get('fullscreen');
|
let f = Cookie.get('fullscreen');
|
||||||
if(f == 1) {
|
if (f == 1) {
|
||||||
Cookie.set('fullscreen', 0);
|
Cookie.set('fullscreen', 0);
|
||||||
document.querySelector('html').setAttribute('res', '');
|
document.querySelector('html').setAttribute('res', '');
|
||||||
tbuttonfull.innerHTML = `<use href="/s/img/iconset.svg#window-maximize"></use>`;
|
tbuttonfull.innerHTML = `<use href="/s/img/iconset.svg#window-maximize"></use>`;
|
||||||
|
|||||||
@@ -64,5 +64,58 @@ export default (router, tpl) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Infinite scroll endpoint for index thumbnails
|
||||||
|
router.get(/\/ajax\/items/, async (req, res) => {
|
||||||
|
let query = {};
|
||||||
|
if (typeof req.url === 'string') {
|
||||||
|
const parsedUrl = url.parse(req.url, true);
|
||||||
|
query = parsedUrl.query;
|
||||||
|
} else {
|
||||||
|
query = req.url.qs || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const page = parseInt(query.page) || 1;
|
||||||
|
|
||||||
|
const data = await f0cklib.getf0cks({
|
||||||
|
page: page,
|
||||||
|
tag: query.tag || null,
|
||||||
|
user: query.user || null,
|
||||||
|
mime: query.mime || null,
|
||||||
|
mode: req.session.mode,
|
||||||
|
session: !!req.session,
|
||||||
|
fav: false
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data.success) {
|
||||||
|
return res.reply({
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: false,
|
||||||
|
html: '',
|
||||||
|
hasMore: false
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render just the thumbnail items
|
||||||
|
const itemsHtml = tpl.render('snippets/items-grid', {
|
||||||
|
items: data.items,
|
||||||
|
link: data.link
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasMore = data.pagination.next !== null;
|
||||||
|
|
||||||
|
return res.reply({
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
html: itemsHtml,
|
||||||
|
hasMore: hasMore,
|
||||||
|
nextPage: data.pagination.next,
|
||||||
|
currentPage: data.pagination.page
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import db from '../../sql.mjs';
|
|||||||
import lib from '../../lib.mjs';
|
import lib from '../../lib.mjs';
|
||||||
import search from '../../routeinc/search.mjs';
|
import search from '../../routeinc/search.mjs';
|
||||||
|
|
||||||
const allowedMimes = [ "audio", "image", "video", "%" ];
|
const allowedMimes = ["audio", "image", "video", "%"];
|
||||||
export default router => {
|
export default router => {
|
||||||
router.group(/^\/api\/v2/, group => {
|
router.group(/^\/api\/v2/, group => {
|
||||||
group.get(/$/, (req, res) => {
|
group.get(/$/, (req, res) => {
|
||||||
@@ -13,14 +13,18 @@ export default router => {
|
|||||||
group.get(/\/random(\/user\/.+|\/image|\/video|\/audio)?$/, async (req, res) => {
|
group.get(/\/random(\/user\/.+|\/image|\/video|\/audio)?$/, async (req, res) => {
|
||||||
const user = req.url.split[3] === "user" ? req.url.split[4] : "%";
|
const user = req.url.split[3] === "user" ? req.url.split[4] : "%";
|
||||||
const mime = (allowedMimes.filter(n => req.url.split[3]?.startsWith(n))[0] ? req.url.split[3] : "") + "%";
|
const mime = (allowedMimes.filter(n => req.url.split[3]?.startsWith(n))[0] ? req.url.split[3] : "") + "%";
|
||||||
|
const tag = req.url.qs.tag || null;
|
||||||
|
|
||||||
const rows = await db`
|
const rows = await db`
|
||||||
select *
|
select "items".*
|
||||||
from "items"
|
from "items"
|
||||||
|
left join tags_assign on tags_assign.item_id = items.id
|
||||||
|
left join tags on tags.id = tags_assign.tag_id
|
||||||
where
|
where
|
||||||
mime ilike ${mime} and
|
mime ilike ${mime} and
|
||||||
username ilike ${user} and
|
username ilike ${user} and
|
||||||
active = 'true'
|
active = 'true'
|
||||||
|
${tag ? db`and tags.normalized ilike ${'%' + tag + '%'}` : db``}
|
||||||
order by random()
|
order by random()
|
||||||
limit 1
|
limit 1
|
||||||
`;
|
`;
|
||||||
@@ -51,15 +55,13 @@ export default router => {
|
|||||||
where
|
where
|
||||||
${db.unsafe(modequery)} and
|
${db.unsafe(modequery)} and
|
||||||
active = 'true'
|
active = 'true'
|
||||||
${
|
${opt.older
|
||||||
opt.older
|
|
||||||
? db`and id <= ${opt.older}`
|
? db`and id <= ${opt.older}`
|
||||||
: opt.newer
|
: opt.newer
|
||||||
? db`and id >= ${opt.newer}`
|
? db`and id >= ${opt.newer}`
|
||||||
: db``
|
: db``
|
||||||
}
|
}
|
||||||
order by id ${
|
order by id ${opt.newer
|
||||||
opt.newer
|
|
||||||
? db`asc`
|
? db`asc`
|
||||||
: db`desc`
|
: db`desc`
|
||||||
}
|
}
|
||||||
@@ -98,7 +100,7 @@ export default router => {
|
|||||||
limit 1
|
limit 1
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if(item.length === 0) {
|
if (item.length === 0) {
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false,
|
success: false,
|
||||||
msg: 'no items found'
|
msg: 'no items found'
|
||||||
@@ -140,7 +142,7 @@ export default router => {
|
|||||||
// tags lol
|
// tags lol
|
||||||
|
|
||||||
group.put(/\/admin\/tags\/(?<tagname>.*)/, lib.loggedin, async (req, res) => {
|
group.put(/\/admin\/tags\/(?<tagname>.*)/, lib.loggedin, async (req, res) => {
|
||||||
if(!req.params.tagname || !req.post.newtag) {
|
if (!req.params.tagname || !req.post.newtag) {
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false,
|
success: false,
|
||||||
msg: 'missing tagname or newtag',
|
msg: 'missing tagname or newtag',
|
||||||
@@ -154,7 +156,7 @@ export default router => {
|
|||||||
const tagname = decodeURIComponent(req.params.tagname);
|
const tagname = decodeURIComponent(req.params.tagname);
|
||||||
const newtag = req.post.newtag;
|
const newtag = req.post.newtag;
|
||||||
|
|
||||||
if(['sfw', 'nsfw'].includes(tagname) || ['sfw', 'nsfw'].includes(newtag)) {
|
if (['sfw', 'nsfw'].includes(tagname) || ['sfw', 'nsfw'].includes(newtag)) {
|
||||||
return res.json({
|
return res.json({
|
||||||
msg: 'f0ck you'
|
msg: 'f0ck you'
|
||||||
}, 405); // method not allowed
|
}, 405); // method not allowed
|
||||||
@@ -167,7 +169,7 @@ export default router => {
|
|||||||
limit 1
|
limit 1
|
||||||
`)[0];
|
`)[0];
|
||||||
|
|
||||||
if(!tmptag) {
|
if (!tmptag) {
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false,
|
success: false,
|
||||||
msg: 'no tag found'
|
msg: 'no tag found'
|
||||||
@@ -175,8 +177,7 @@ export default router => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const q = (await db`
|
const q = (await db`
|
||||||
update "tags" set ${
|
update "tags" set ${db({
|
||||||
db({
|
|
||||||
tag: newtag
|
tag: newtag
|
||||||
}, 'tag')
|
}, 'tag')
|
||||||
}
|
}
|
||||||
@@ -195,7 +196,7 @@ export default router => {
|
|||||||
|
|
||||||
const searchString = req.url.qs.q;
|
const searchString = req.url.qs.q;
|
||||||
|
|
||||||
if(searchString?.length <= 1) {
|
if (searchString?.length <= 1) {
|
||||||
reply.error = 'too short lol';
|
reply.error = 'too short lol';
|
||||||
return res.json(reply);
|
return res.json(reply);
|
||||||
}
|
}
|
||||||
@@ -212,7 +213,7 @@ export default router => {
|
|||||||
`;
|
`;
|
||||||
reply.success = true;
|
reply.success = true;
|
||||||
reply.suggestions = search(q, searchString);
|
reply.suggestions = search(q, searchString);
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
reply.error = err.msg;
|
reply.error = err.msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +221,7 @@ export default router => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group.post(/\/admin\/deletepost$/, lib.auth, async (req, res) => {
|
group.post(/\/admin\/deletepost$/, lib.auth, async (req, res) => {
|
||||||
if(!req.post.postid) {
|
if (!req.post.postid) {
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false,
|
success: false,
|
||||||
msg: 'no postid'
|
msg: 'no postid'
|
||||||
@@ -228,7 +229,7 @@ export default router => {
|
|||||||
}
|
}
|
||||||
const id = +req.post.postid;
|
const id = +req.post.postid;
|
||||||
|
|
||||||
if(id <= 1) {
|
if (id <= 1) {
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false
|
success: false
|
||||||
});
|
});
|
||||||
@@ -243,7 +244,7 @@ export default router => {
|
|||||||
limit 1
|
limit 1
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if(f0ck.length === 0) {
|
if (f0ck.length === 0) {
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false,
|
success: false,
|
||||||
msg: `f0ck ${id}: f0ck not found`
|
msg: `f0ck ${id}: f0ck not found`
|
||||||
@@ -252,14 +253,14 @@ export default router => {
|
|||||||
|
|
||||||
await db`update "items" set active = 'false' where id = ${id}`;
|
await db`update "items" set active = 'false' where id = ${id}`;
|
||||||
|
|
||||||
await fs.copyFile(`./public/b/${f0ck[0].dest}`, `./deleted/b/${f0ck[0].dest}`).catch(_=>{});
|
await fs.copyFile(`./public/b/${f0ck[0].dest}`, `./deleted/b/${f0ck[0].dest}`).catch(_ => { });
|
||||||
await fs.copyFile(`./public/t/${id}.webp`, `./deleted/t/${id}.webp`).catch(_=>{});
|
await fs.copyFile(`./public/t/${id}.webp`, `./deleted/t/${id}.webp`).catch(_ => { });
|
||||||
await fs.unlink(`./public/b/${f0ck[0].dest}`).catch(_=>{});
|
await fs.unlink(`./public/b/${f0ck[0].dest}`).catch(_ => { });
|
||||||
await fs.unlink(`./public/t/${id}.webp`).catch(_=>{});
|
await fs.unlink(`./public/t/${id}.webp`).catch(_ => { });
|
||||||
|
|
||||||
if(f0ck[0].mime.startsWith('audio')) {
|
if (f0ck[0].mime.startsWith('audio')) {
|
||||||
await fs.copyFile(`./public/ca/${id}.webp`, `./deleted/ca/${id}.webp`).catch(_=>{});
|
await fs.copyFile(`./public/ca/${id}.webp`, `./deleted/ca/${id}.webp`).catch(_ => { });
|
||||||
await fs.unlink(`./public/ca/${id}.webp`).catch(_=>{});
|
await fs.unlink(`./public/ca/${id}.webp`).catch(_ => { });
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
@@ -276,7 +277,7 @@ export default router => {
|
|||||||
where item_id = ${+postid}
|
where item_id = ${+postid}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if(Object.values(favs).filter(u => u.user_id === req.session.id)[0]) {
|
if (Object.values(favs).filter(u => u.user_id === req.session.id)[0]) {
|
||||||
// del fav
|
// del fav
|
||||||
await db`
|
await db`
|
||||||
delete from "favorites"
|
delete from "favorites"
|
||||||
@@ -287,8 +288,7 @@ export default router => {
|
|||||||
else {
|
else {
|
||||||
// add fav
|
// add fav
|
||||||
await db`
|
await db`
|
||||||
insert into "favorites" ${
|
insert into "favorites" ${db({
|
||||||
db({
|
|
||||||
item_id: +postid,
|
item_id: +postid,
|
||||||
user_id: +req.session.id
|
user_id: +req.session.id
|
||||||
}, 'item_id', 'user_id')
|
}, 'item_id', 'user_id')
|
||||||
|
|||||||
@@ -23,35 +23,35 @@ export default async bot => {
|
|||||||
name: "parser",
|
name: "parser",
|
||||||
call: regex.all,
|
call: regex.all,
|
||||||
active: true,
|
active: true,
|
||||||
f: e => {
|
f: async e => {
|
||||||
const links = e.message.match(regex.all)?.filter(link => !link.includes(cfg.main.url.domain)) || [];
|
const links = e.message.match(regex.all)?.filter(link => !link.includes(cfg.main.url.domain)) || [];
|
||||||
let repost;
|
let repost;
|
||||||
if(e.media)
|
if (e.media)
|
||||||
links.push(e.media);
|
links.push(e.media);
|
||||||
|
|
||||||
if(links.length === 0)
|
if (links.length === 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(e.message.match(/\!i(gnore)?\b/))
|
if (e.message.match(/\!i(gnore)?\b/))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!e.channel.includes("w0bm") && (!e.message.match(/\!w(0bm)?\b/i) && (typeof e.raw.forward_from == 'undefined')))
|
if (!e.channel.includes("w0bm") && (!e.message.match(/\!w(0bm)?\b/i) && (typeof e.raw.forward_from == 'undefined')))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(e.type === 'tg' && // proto: tg
|
if (e.type === 'tg' && // proto: tg
|
||||||
!e.message.match(/\!w(0bm)?\b/i) && // !w / !w0bm
|
!e.message.match(/\!w(0bm)?\b/i) && // !w / !w0bm
|
||||||
!e.raw.forward_date && // is forwarded?
|
!e.raw.forward_date && // is forwarded?
|
||||||
!mediagroupids.has(e.raw.media_group_id) // prepared mediagroup?
|
!mediagroupids.has(e.raw.media_group_id) // prepared mediagroup?
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(e.raw.media_group_id && e.message.match(/\!w(0bm)?\b/i)) {
|
else if (e.raw.media_group_id && e.message.match(/\!w(0bm)?\b/i)) {
|
||||||
mediagroupids.add(e.raw.media_group_id);
|
mediagroupids.add(e.raw.media_group_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`parsing ${links.length} link${links.length > 1 ? "s" : ""}...`);
|
console.log(`parsing ${links.length} link${links.length > 1 ? "s" : ""}...`);
|
||||||
|
|
||||||
links.forEach(async link => {
|
for (const link of links) {
|
||||||
//if(regex.imgur.test(link))
|
//if(regex.imgur.test(link))
|
||||||
// return await e.reply(`fuck imgur... seriously`);
|
// return await e.reply(`fuck imgur... seriously`);
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ export default async bot => {
|
|||||||
|
|
||||||
// check repost (link)
|
// check repost (link)
|
||||||
repost = await queue.checkrepostlink(link);
|
repost = await queue.checkrepostlink(link);
|
||||||
if(repost)
|
if (repost)
|
||||||
return await e.reply(`repost motherf0cker (link): ${cfg.main.url.full}/${repost}`);
|
return await e.reply(`repost motherf0cker (link): ${cfg.main.url.full}/${repost}`);
|
||||||
|
|
||||||
// generate uuid
|
// generate uuid
|
||||||
@@ -73,39 +73,41 @@ export default async bot => {
|
|||||||
|
|
||||||
// read metadata
|
// read metadata
|
||||||
let ext;
|
let ext;
|
||||||
if(link.match(regex.instagram)) {
|
const proxyArgs = cfg.main.socks ? `--proxy ${cfg.main.socks}` : '';
|
||||||
|
if (link.match(regex.instagram)) {
|
||||||
// is instagram
|
// is instagram
|
||||||
try {
|
try {
|
||||||
// @flummi -> is there a variable for the actual work directory so it doesn't have to be hardcoded?
|
// @flummi -> is there a variable for the actual work directory so it doesn't have to be hardcoded?
|
||||||
const meta = JSON.parse((await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout);
|
const meta = JSON.parse((await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout);
|
||||||
ext = meta.ext;
|
ext = meta.ext;
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
|
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
|
||||||
// this can be undefined for unsupported mime types, but will be caught in the general mime check below
|
// this can be undefined for unsupported mime types, but will be caught in the general mime check below
|
||||||
ext = cfg.mimes[tmphead];
|
ext = cfg.mimes[tmphead];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(link.match(regex.imgur)) {
|
else if (link.match(regex.imgur)) {
|
||||||
// imghure
|
// imghure
|
||||||
ext = link.split('.').pop();
|
ext = link.split('.').pop();
|
||||||
}
|
}
|
||||||
else if(link.match(regex.yt)) {
|
else if (link.match(regex.yt)) {
|
||||||
//yt - fuck anti bot protection
|
//yt - fuck anti bot protection
|
||||||
try {
|
try {
|
||||||
const meta = JSON.parse((await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' -I 1 --skip-download --dump-json "${link}"`)).stdout);
|
const meta = JSON.parse((await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' -I 1 --skip-download --dump-json "${link}"`)).stdout);
|
||||||
ext = meta.ext;
|
ext = meta.ext;
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
|
console.error("YT-DLP Error:", err);
|
||||||
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
|
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
|
||||||
// this can be undefined for unsupported mime types, but will be caught in the general mime check below
|
// this can be undefined for unsupported mime types, but will be caught in the general mime check below
|
||||||
ext = cfg.mimes[tmphead];
|
ext = cfg.mimes[tmphead];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(link.match(regex.fourchan)) {
|
else if (link.match(regex.fourchan)) {
|
||||||
//4chan - fuck cloudflare :)
|
//4chan - fuck cloudflare :)
|
||||||
try {
|
try {
|
||||||
const meta = JSON.parse((await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout);
|
const meta = JSON.parse((await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout);
|
||||||
ext = meta.ext;
|
ext = meta.ext;
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
|
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
|
||||||
// this can be undefined for unsupported mime types, but will be caught in the general mime check below
|
// this can be undefined for unsupported mime types, but will be caught in the general mime check below
|
||||||
ext = cfg.mimes[tmphead];
|
ext = cfg.mimes[tmphead];
|
||||||
@@ -117,14 +119,15 @@ export default async bot => {
|
|||||||
try {
|
try {
|
||||||
const meta = JSON.parse((await queue.exec(`yt-dlp -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout);
|
const meta = JSON.parse((await queue.exec(`yt-dlp -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout);
|
||||||
ext = meta.ext;
|
ext = meta.ext;
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
|
console.error('err:', err);
|
||||||
// this can be undefined for unsupported mime types, but will be caught in the general mime check below
|
if (e.type == 'tg')
|
||||||
ext = cfg.mimes[tmphead];
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err);
|
||||||
|
return await e.reply('something went wrong lol / check maxfilesize?');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Object.values(cfg.mimes).includes(ext?.toLowerCase())) {
|
if (!Object.values(cfg.mimes).includes(ext?.toLowerCase())) {
|
||||||
return console.log('mime schmime ' + ext);
|
return console.log('mime schmime ' + ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,44 +139,44 @@ export default async bot => {
|
|||||||
const start = new Date();
|
const start = new Date();
|
||||||
let source;
|
let source;
|
||||||
|
|
||||||
if(link.match(regex.instagram)) {
|
if (link.match(regex.instagram)) {
|
||||||
try {
|
try {
|
||||||
// add --cookies <path-to-cookies-file> on local instance if you want to avoid getting rate limited or optionally use a socks proxy from a network that is not being detected as a public network
|
// add --cookies <path-to-cookies-file> on local instance if you want to avoid getting rate limited or optionally use a socks proxy from a network that is not being detected as a public network
|
||||||
source = (await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=1080]+ba/b[height<=1080] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
|
source = (await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=1080]+ba/b[height<=1080] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "instagram dl error");
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "instagram dl error");
|
||||||
return await e.reply("instagram dl error", err);
|
return await e.reply("instagram dl error", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(link.match(regex.imgur)) {
|
else if (link.match(regex.imgur)) {
|
||||||
// imghure via torsocks // needs torsocks setup so this is optional
|
// imghure via torsocks // needs torsocks setup so this is optional
|
||||||
try {
|
try {
|
||||||
await queue.exec(`torsocks wget ${link} -O ./tmp/${uuid}.${ext}`);
|
await queue.exec(`torsocks wget ${link} -O ./tmp/${uuid}.${ext}`);
|
||||||
source = `./tmp/${uuid}.${ext}`;
|
source = `./tmp/${uuid}.${ext}`;
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
console.error('err:', err);
|
console.error('err:', err);
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err);
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err);
|
||||||
return await e.reply('something went wrong lol');
|
return await e.reply('something went wrong lol');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(link.match(regex.yt)) {
|
else if (link.match(regex.yt)) {
|
||||||
try {
|
try {
|
||||||
// add --cookies <path-to-cookies-file> on local instance if you want to avoid getting rate limited or optionally use a socks proxy from a network that is not being detected as a public network
|
// add --cookies <path-to-cookies-file> on local instance if you want to avoid getting rate limited or optionally use a socks proxy from a network that is not being detected as a public network
|
||||||
source = (await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" -I 1 --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
|
source = (await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" -I 1 --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "yt dl error");
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "yt dl error");
|
||||||
return await e.reply("yt dl error", err);
|
return await e.reply("yt dl error", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(link.match(regex.fourchan)) {
|
else if (link.match(regex.fourchan)) {
|
||||||
// 4chan via proxy - fuck cloudflare
|
// 4chan via proxy - fuck cloudflare
|
||||||
try {
|
try {
|
||||||
source = (await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
|
source = (await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "yt dl error");
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "yt dl error");
|
||||||
return await e.reply("yt dl error", err);
|
return await e.reply("yt dl error", err);
|
||||||
}
|
}
|
||||||
@@ -182,23 +185,23 @@ export default async bot => {
|
|||||||
// everything except the exceptions
|
// everything except the exceptions
|
||||||
try {
|
try {
|
||||||
source = (await queue.exec(`yt-dlp -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
|
source = (await queue.exec(`yt-dlp -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
console.error('err:', err);
|
console.error('err:', err);
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err);
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err);
|
||||||
return await e.reply('something went wrong lol / check maxfilesize?');
|
return await e.reply('something went wrong lol / check maxfilesize?');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// </download data>
|
// </download data>
|
||||||
|
|
||||||
if(!source) {
|
if (!source) {
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "something went wrong lol");
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "something went wrong lol");
|
||||||
return await e.reply("something went wrong lol");
|
return await e.reply("something went wrong lol");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.match(/larger than/)) {
|
if (source.match(/larger than/)) {
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "too large lol");
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "too large lol");
|
||||||
return await e.reply("too large lol");
|
return await e.reply("too large lol");
|
||||||
}
|
}
|
||||||
@@ -206,9 +209,9 @@ export default async bot => {
|
|||||||
|
|
||||||
// filesize check
|
// filesize check
|
||||||
const size = fs.statSync(source).size;
|
const size = fs.statSync(source).size;
|
||||||
if(size > maxfilesize) {
|
if (size > maxfilesize) {
|
||||||
await fs.promises.unlink(source).catch(_=>{});
|
await fs.promises.unlink(source).catch(_ => { });
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`);
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`);
|
||||||
return await e.reply(`too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`);
|
return await e.reply(`too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`);
|
||||||
}
|
}
|
||||||
@@ -216,28 +219,28 @@ export default async bot => {
|
|||||||
// mime check
|
// mime check
|
||||||
let mime = (await queue.exec(`file --mime-type -b ${source}`)).stdout.trim();
|
let mime = (await queue.exec(`file --mime-type -b ${source}`)).stdout.trim();
|
||||||
try {
|
try {
|
||||||
if(mime == 'video/x-matroska') { // mkv failsafe
|
if (mime == 'video/x-matroska') { // mkv failsafe
|
||||||
await queue.exec(`ffmpeg -i ./tmp/${uuid}.mkv -codec copy ./tmp/${uuid}.mp4`);
|
await queue.exec(`ffmpeg -i ./tmp/${uuid}.mkv -codec copy ./tmp/${uuid}.mp4`);
|
||||||
await fs.promises.unlink(source).catch(_=>{});
|
await fs.promises.unlink(source).catch(_ => { });
|
||||||
source = source.replace(/\.mkv$/, '.mp4');
|
source = source.replace(/\.mkv$/, '.mp4');
|
||||||
mime = 'video/mp4';
|
mime = 'video/mp4';
|
||||||
}
|
}
|
||||||
if(source.match(/\.opus$/)) { // opus failsafe
|
if (source.match(/\.opus$/)) { // opus failsafe
|
||||||
await queue.exec(`ffmpeg -i ./tmp/${uuid}.opus -codec copy ./tmp/${uuid}.ogg`);
|
await queue.exec(`ffmpeg -i ./tmp/${uuid}.opus -codec copy ./tmp/${uuid}.ogg`);
|
||||||
await fs.promises.unlink(source);
|
await fs.promises.unlink(source);
|
||||||
source = source.replace(/\.opus$/, '.ogg');
|
source = source.replace(/\.opus$/, '.ogg');
|
||||||
mime = 'audio/ogg';
|
mime = 'audio/ogg';
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
await fs.promises.unlink(source).catch(_=>{});
|
await fs.promises.unlink(source).catch(_ => { });
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "something went wrong lol");
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "something went wrong lol");
|
||||||
return await e.reply("something went wrong lol");
|
return await e.reply("something went wrong lol");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Object.keys(cfg.mimes).includes(mime)) {
|
if (!Object.keys(cfg.mimes).includes(mime)) {
|
||||||
await fs.promises.unlink(source).catch(_=>{});
|
await fs.promises.unlink(source).catch(_ => { });
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `lol, go f0ck yourself (${mime})`);
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `lol, go f0ck yourself (${mime})`);
|
||||||
return await e.reply(`lol, go f0ck yourself (${mime})`);
|
return await e.reply(`lol, go f0ck yourself (${mime})`);
|
||||||
}
|
}
|
||||||
@@ -247,9 +250,9 @@ export default async bot => {
|
|||||||
|
|
||||||
// check repost (checksum)
|
// check repost (checksum)
|
||||||
repost = await queue.checkrepostsum(checksum);
|
repost = await queue.checkrepostsum(checksum);
|
||||||
if(repost) {
|
if (repost) {
|
||||||
await fs.promises.unlink(source).catch(_=>{});
|
await fs.promises.unlink(source).catch(_ => { });
|
||||||
if(e.type == 'tg')
|
if (e.type == 'tg')
|
||||||
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`);
|
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`);
|
||||||
return await e.reply(`repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`);
|
return await e.reply(`repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`);
|
||||||
}
|
}
|
||||||
@@ -257,7 +260,7 @@ export default async bot => {
|
|||||||
const filename = path.basename(source);
|
const filename = path.basename(source);
|
||||||
|
|
||||||
await fs.promises.copyFile(source, `./public/b/${filename}`);
|
await fs.promises.copyFile(source, `./public/b/${filename}`);
|
||||||
await fs.promises.unlink(source).catch(_=>{});
|
await fs.promises.unlink(source).catch(_ => { });
|
||||||
|
|
||||||
// user alias
|
// user alias
|
||||||
let username = e.user.nick || e.user.username;
|
let username = e.user.nick || e.user.username;
|
||||||
@@ -268,13 +271,12 @@ export default async bot => {
|
|||||||
where lower(user_alias.alias) ilike ${username}
|
where lower(user_alias.alias) ilike ${username}
|
||||||
limit 1
|
limit 1
|
||||||
`)?.[0]?.user;
|
`)?.[0]?.user;
|
||||||
if(alias) {
|
if (alias) {
|
||||||
username = alias;
|
username = alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
await db`
|
await db`
|
||||||
insert into items ${
|
insert into items ${db({
|
||||||
db({
|
|
||||||
src: e.media ? "" : link,
|
src: e.media ? "" : link,
|
||||||
dest: filename,
|
dest: filename,
|
||||||
mime: mime,
|
mime: mime,
|
||||||
@@ -291,10 +293,20 @@ export default async bot => {
|
|||||||
|
|
||||||
const itemid = await queue.getItemID(filename);
|
const itemid = await queue.getItemID(filename);
|
||||||
|
|
||||||
|
// auto-tag sfw
|
||||||
|
await db`
|
||||||
|
insert into tags_assign ${db({
|
||||||
|
item_id: itemid,
|
||||||
|
tag_id: 1, // sfw
|
||||||
|
user_id: 2 // f0ck
|
||||||
|
}, 'item_id', 'tag_id', 'user_id')
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
// generate thumbnail
|
// generate thumbnail
|
||||||
try {
|
try {
|
||||||
await queue.genThumbnail(filename, mime, itemid, link);
|
await queue.genThumbnail(filename, mime, itemid, link);
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
await queue.exec(`magick ./mugge.png ./public/t/${itemid}.webp`);
|
await queue.exec(`magick ./mugge.png ./public/t/${itemid}.webp`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,13 +327,13 @@ export default async bot => {
|
|||||||
let outputmsgirc = `[f0cked] link: ${cfg.main.url.full}/${itemid} | size: ${lib.formatSize(size)} | speed: ${speed}`;
|
let outputmsgirc = `[f0cked] link: ${cfg.main.url.full}/${itemid} | size: ${lib.formatSize(size)} | speed: ${speed}`;
|
||||||
let outputmsgtg = `[f0cked] size: ${lib.formatSize(size)} | speed: ${speed}`;
|
let outputmsgtg = `[f0cked] size: ${lib.formatSize(size)} | speed: ${speed}`;
|
||||||
|
|
||||||
if(tags?.length > 0) {
|
if (tags?.length > 0) {
|
||||||
const tagstr = tags.join(', ');
|
const tagstr = tags.join(', ');
|
||||||
outputmsgirc += ` | tags: ${tagstr}`;
|
outputmsgirc += ` | tags: ${tagstr}`;
|
||||||
outputmsgtg += ` | tags: ${tagstr}`;
|
outputmsgtg += ` | tags: ${tagstr}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e.type == 'tg') {
|
if (e.type == 'tg') {
|
||||||
await e.deleteMessage(msg.result.chat.id, msg.result.message_id);
|
await e.deleteMessage(msg.result.chat.id, msg.result.message_id);
|
||||||
await e.reply(outputmsgtg, {
|
await e.reply(outputmsgtg, {
|
||||||
reply_markup: JSON.stringify({
|
reply_markup: JSON.stringify({
|
||||||
@@ -339,7 +351,7 @@ export default async bot => {
|
|||||||
else {
|
else {
|
||||||
await e.reply(outputmsgirc);
|
await e.reply(outputmsgirc);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
7
views/snippets/items-grid.html
Normal file
7
views/snippets/items-grid.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@each(items as item)
|
||||||
|
<a href="{{ link.main }}{{ item.id }}" data-mime="{{ item.mime }}"
|
||||||
|
data-mode="{{ item.tag_id ? ['','sfw','nsfw'][item.tag_id] : 'null' }}"
|
||||||
|
style="background-image: url('/t/{{ item.id }}.webp')">
|
||||||
|
<p></p>
|
||||||
|
</a>
|
||||||
|
@endeach
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<a href="/tags">tags</a>
|
<a href="/tags">tags</a>
|
||||||
<a href="/about">about</a>
|
<a href="/about">about</a>
|
||||||
@if(!/^\/\d$/.test(url.pathname))
|
@if(!/^\/\d$/.test(url.pathname))
|
||||||
<a href="/random">rand</a>
|
<a href="/random" id="nav-random">rand</a>
|
||||||
@endif
|
@endif
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
<a href="/tags">tags</a>
|
<a href="/tags">tags</a>
|
||||||
<a href="/about">about</a>
|
<a href="/about">about</a>
|
||||||
@if(!/^\/\d$/.test(url.pathname))
|
@if(!/^\/\d$/.test(url.pathname))
|
||||||
<a href="/random">rand</a>
|
<a href="/random" id="nav-random">rand</a>
|
||||||
@endif
|
@endif
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user