hgfd
This commit is contained in:
@@ -4,7 +4,7 @@ Happy to finally bring you f0ckm! The long awaited imageboard solution that you
|
|||||||
|
|
||||||
It features extensive tagging, searching, filtering and a variety of options.
|
It features extensive tagging, searching, filtering and a variety of options.
|
||||||
|
|
||||||
The software is mostly generic, it can be modified easily via config.json to suit your communities needs. Most things can be enabled/disabled very easily and modified to needs.
|
The software is mostly generic, it can be modified easily via `config.yaml` (or `config.json`) to suit your communities needs. Most things can be enabled/disabled very easily and modified to needs.
|
||||||
|
|
||||||
The software comes without any warranties or entitlements of any kind! The developer is not responsible for anything you do with the use of this software.
|
The software comes without any warranties or entitlements of any kind! The developer is not responsible for anything you do with the use of this software.
|
||||||
|
|
||||||
@@ -20,7 +20,12 @@ first things
|
|||||||
|
|
||||||
fill with for example: f0ckm (prefilled)
|
fill with for example: f0ckm (prefilled)
|
||||||
|
|
||||||
`cp config_example.json config.json`
|
Copy example configuration and customize:
|
||||||
|
|
||||||
|
`cp config_example.yaml config.yaml`
|
||||||
|
`npm run config:gen`
|
||||||
|
|
||||||
|
(Or `cp config_example.json config.json` if configuring directly in JSON)
|
||||||
|
|
||||||
Edit to needs, for sql you can do this:
|
Edit to needs, for sql you can do this:
|
||||||
|
|
||||||
@@ -75,6 +80,13 @@ Create admin user in dev env
|
|||||||
|
|
||||||
now visit http://localhost:1337 in your browser, you can develop without needing to rebuild the docker image for every change
|
now visit http://localhost:1337 in your browser, you can develop without needing to rebuild the docker image for every change
|
||||||
|
|
||||||
|
## Configuration Management
|
||||||
|
|
||||||
|
You can manage configuration in YAML (`config.yaml`) or JSON (`config.json`):
|
||||||
|
- `npm run config:gen`: Compiles `config.yaml` to `config.json`. Automatically runs before `npm run dev` and `npm start`.
|
||||||
|
- `npm run config:watch`: Watches `config.yaml` for edits and recompiles `config.json` automatically on save.
|
||||||
|
- `npm run config:to-yaml`: Converts existing `config.json` into `config.yaml`.
|
||||||
|
|
||||||
## NGINX
|
## NGINX
|
||||||
|
|
||||||
uncomment in .env # COMPOSE_PROFILES=f0ckm-nginx to enable nginx proxy with automatic lets encrypt.
|
uncomment in .env # COMPOSE_PROFILES=f0ckm-nginx to enable nginx proxy with automatic lets encrypt.
|
||||||
|
|||||||
+5
-1
@@ -164,7 +164,11 @@
|
|||||||
"fileupload_comments_size": 104857600,
|
"fileupload_comments_size": 104857600,
|
||||||
"fileupload_comments_max": 5,
|
"fileupload_comments_max": 5,
|
||||||
"fileupload_comments_mode": "attachment",
|
"fileupload_comments_mode": "attachment",
|
||||||
"fileupload_comments_mimes": ["image", "video", "audio"],
|
"fileupload_comments_mimes": [
|
||||||
|
"image",
|
||||||
|
"video",
|
||||||
|
"audio"
|
||||||
|
],
|
||||||
"show_content_warning": true,
|
"show_content_warning": true,
|
||||||
"default_comment_display_mode": 1,
|
"default_comment_display_mode": 1,
|
||||||
"phrases": [
|
"phrases": [
|
||||||
|
|||||||
Generated
+22
-1
@@ -17,7 +17,8 @@
|
|||||||
"jszip": "3.10.1",
|
"jszip": "3.10.1",
|
||||||
"marked": "18.0.2",
|
"marked": "18.0.2",
|
||||||
"matrix-js-sdk": "^40.3.0-rc.0",
|
"matrix-js-sdk": "^40.3.0-rc.0",
|
||||||
"postgres": "^3.3.4"
|
"postgres": "^3.3.4",
|
||||||
|
"yaml": "^2.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
@@ -448,6 +449,21 @@
|
|||||||
"bin": {
|
"bin": {
|
||||||
"uuid": "dist-node/bin/uuid"
|
"uuid": "dist-node/bin/uuid"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yaml": {
|
||||||
|
"version": "2.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz",
|
||||||
|
"integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"yaml": "bin.mjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/eemeli"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -757,6 +773,11 @@
|
|||||||
"version": "13.0.2",
|
"version": "13.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.2.tgz",
|
||||||
"integrity": "sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw=="
|
"integrity": "sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw=="
|
||||||
|
},
|
||||||
|
"yaml": {
|
||||||
|
"version": "2.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz",
|
||||||
|
"integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1786,6 +1786,10 @@ window.cancelAnimFrame = (function () {
|
|||||||
|
|
||||||
// ── Onara Alternative Flavor: Fullscreen Modal Wrapper ─────────────────────
|
// ── Onara Alternative Flavor: Fullscreen Modal Wrapper ─────────────────────
|
||||||
const isOnaraActive = () => {
|
const isOnaraActive = () => {
|
||||||
|
// Global config onara overweighs always the user pref
|
||||||
|
if (window.f0ckSession && window.f0ckSession.onara_cfg !== undefined && window.f0ckSession.onara_cfg !== null) {
|
||||||
|
return !!window.f0ckSession.onara_cfg;
|
||||||
|
}
|
||||||
const stored = (() => { try { return localStorage.getItem('f0ck_onara_enabled'); } catch { return null; } })();
|
const stored = (() => { try { return localStorage.getItem('f0ck_onara_enabled'); } catch { return null; } })();
|
||||||
if (stored !== null) {
|
if (stored !== null) {
|
||||||
const active = stored === 'true';
|
const active = stored === 'true';
|
||||||
|
|||||||
+26
-17
@@ -1586,29 +1586,38 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Onara enable/disable toggle (localStorage only — no server round-trip needed)
|
// Onara enable/disable toggle
|
||||||
const onaraEnabledToggle = document.getElementById('onara_enabled_toggle');
|
const onaraEnabledToggle = document.getElementById('onara_enabled_toggle');
|
||||||
if (onaraEnabledToggle) {
|
if (onaraEnabledToggle) {
|
||||||
const LS_KEY = 'f0ck_onara_enabled';
|
const LS_KEY = 'f0ck_onara_enabled';
|
||||||
// Seed checkbox from localStorage; fall back to the server-set session value
|
const hasGlobalConfig = window.f0ckSession && window.f0ckSession.onara_cfg !== undefined && window.f0ckSession.onara_cfg !== null;
|
||||||
const stored = localStorage.getItem(LS_KEY);
|
|
||||||
const sessionOnara = !!(window.f0ckSession?.onara);
|
|
||||||
onaraEnabledToggle.checked = stored !== null ? stored === 'true' : sessionOnara;
|
|
||||||
// Reflect current state into window.onara so isOnaraActive() sees it
|
|
||||||
window.onara = onaraEnabledToggle.checked;
|
|
||||||
try {
|
|
||||||
document.cookie = `f0ck_onara=${onaraEnabledToggle.checked ? '1' : '0'}; path=/; max-age=31536000; SameSite=Lax`;
|
|
||||||
} catch {}
|
|
||||||
|
|
||||||
onaraEnabledToggle.addEventListener('change', () => {
|
if (hasGlobalConfig) {
|
||||||
const enabled = onaraEnabledToggle.checked;
|
const globalVal = !!window.f0ckSession.onara_cfg;
|
||||||
localStorage.setItem(LS_KEY, String(enabled));
|
onaraEnabledToggle.checked = globalVal;
|
||||||
|
onaraEnabledToggle.disabled = true;
|
||||||
|
window.onara = globalVal;
|
||||||
|
} else {
|
||||||
|
// Seed checkbox from localStorage; fall back to the server-set session value
|
||||||
|
const stored = localStorage.getItem(LS_KEY);
|
||||||
|
const sessionOnara = !!(window.f0ckSession?.onara);
|
||||||
|
onaraEnabledToggle.checked = stored !== null ? stored === 'true' : sessionOnara;
|
||||||
|
// Reflect current state into window.onara so isOnaraActive() sees it
|
||||||
|
window.onara = onaraEnabledToggle.checked;
|
||||||
try {
|
try {
|
||||||
document.cookie = `f0ck_onara=${enabled ? '1' : '0'}; path=/; max-age=31536000; SameSite=Lax`;
|
document.cookie = `f0ck_onara=${onaraEnabledToggle.checked ? '1' : '0'}; path=/; max-age=31536000; SameSite=Lax`;
|
||||||
} catch {}
|
} catch {}
|
||||||
window.onara = enabled;
|
|
||||||
showStatus('Onara viewer ' + (enabled ? 'enabled' : 'disabled') + '.', 'success');
|
onaraEnabledToggle.addEventListener('change', () => {
|
||||||
});
|
const enabled = onaraEnabledToggle.checked;
|
||||||
|
localStorage.setItem(LS_KEY, String(enabled));
|
||||||
|
try {
|
||||||
|
document.cookie = `f0ck_onara=${enabled ? '1' : '0'}; path=/; max-age=31536000; SameSite=Lax`;
|
||||||
|
} catch {}
|
||||||
|
window.onara = enabled;
|
||||||
|
showStatus('Onara viewer ' + (enabled ? 'enabled' : 'disabled') + '.', 'success');
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quote Emojis Toggle
|
// Quote Emojis Toggle
|
||||||
|
|||||||
Executable
+92
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import YAML from 'yaml';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
const rootDir = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
|
const DEFAULT_CONFIG_YAML = path.join(rootDir, 'config.yaml');
|
||||||
|
const DEFAULT_CONFIG_JSON = path.join(rootDir, 'config.json');
|
||||||
|
const EXAMPLE_CONFIG_YAML = path.join(rootDir, 'config_example.yaml');
|
||||||
|
const EXAMPLE_CONFIG_JSON = path.join(rootDir, 'config_example.json');
|
||||||
|
|
||||||
|
function convertYamlToJson(yamlPath, jsonPath) {
|
||||||
|
if (!fs.existsSync(yamlPath)) {
|
||||||
|
console.error(`[CONFIG-GEN] Error: Source YAML file not found at ${yamlPath}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const yamlContent = fs.readFileSync(yamlPath, 'utf8');
|
||||||
|
const parsed = YAML.parse(yamlContent);
|
||||||
|
if (parsed === null || typeof parsed !== 'object') {
|
||||||
|
throw new Error('Parsed YAML is not an object');
|
||||||
|
}
|
||||||
|
const jsonContent = JSON.stringify(parsed, null, 2) + '\n';
|
||||||
|
fs.writeFileSync(jsonPath, jsonContent, 'utf8');
|
||||||
|
console.log(`[CONFIG-GEN] Generated ${path.relative(rootDir, jsonPath)} from ${path.relative(rootDir, yamlPath)}`);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[CONFIG-GEN] Failed to generate JSON from ${path.relative(rootDir, yamlPath)}: ${err.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertJsonToYaml(jsonPath, yamlPath) {
|
||||||
|
if (!fs.existsSync(jsonPath)) {
|
||||||
|
console.error(`[CONFIG-GEN] Error: Source JSON file not found at ${jsonPath}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const jsonContent = fs.readFileSync(jsonPath, 'utf8');
|
||||||
|
const parsed = JSON.parse(jsonContent);
|
||||||
|
const doc = new YAML.Document(parsed);
|
||||||
|
const yamlContent = String(doc);
|
||||||
|
fs.writeFileSync(yamlPath, yamlContent, 'utf8');
|
||||||
|
console.log(`[CONFIG-GEN] Generated ${path.relative(rootDir, yamlPath)} from ${path.relative(rootDir, jsonPath)}`);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[CONFIG-GEN] Failed to generate YAML from ${path.relative(rootDir, jsonPath)}: ${err.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const isWatch = args.includes('--watch') || args.includes('-w');
|
||||||
|
const isToYaml = args.includes('--to-yaml');
|
||||||
|
const includeAll = args.includes('--all') || args.includes('--example');
|
||||||
|
|
||||||
|
if (isToYaml) {
|
||||||
|
convertJsonToYaml(DEFAULT_CONFIG_JSON, DEFAULT_CONFIG_YAML);
|
||||||
|
if (includeAll || fs.existsSync(EXAMPLE_CONFIG_JSON)) {
|
||||||
|
convertJsonToYaml(EXAMPLE_CONFIG_JSON, EXAMPLE_CONFIG_YAML);
|
||||||
|
}
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial generation
|
||||||
|
let success = convertYamlToJson(DEFAULT_CONFIG_YAML, DEFAULT_CONFIG_JSON);
|
||||||
|
if (includeAll && fs.existsSync(EXAMPLE_CONFIG_YAML)) {
|
||||||
|
convertYamlToJson(EXAMPLE_CONFIG_YAML, EXAMPLE_CONFIG_JSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success && !isWatch) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWatch) {
|
||||||
|
console.log(`[CONFIG-GEN] Watching ${path.relative(rootDir, DEFAULT_CONFIG_YAML)} for changes... (Press Ctrl+C to stop)`);
|
||||||
|
let debounceTimer = null;
|
||||||
|
fs.watch(DEFAULT_CONFIG_YAML, (eventType) => {
|
||||||
|
if (eventType === 'change' || eventType === 'rename') {
|
||||||
|
if (debounceTimer) clearTimeout(debounceTimer);
|
||||||
|
debounceTimer = setTimeout(() => {
|
||||||
|
console.log(`[CONFIG-GEN] File change detected, re-generating config.json...`);
|
||||||
|
convertYamlToJson(DEFAULT_CONFIG_YAML, DEFAULT_CONFIG_JSON);
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -100,4 +100,33 @@ config.paths = {
|
|||||||
import: resolveImportPath()
|
import: resolveImportPath()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const configFilePath = path.resolve(base, "config.json");
|
||||||
|
let watchDebounceTimer = null;
|
||||||
|
try {
|
||||||
|
if (fs.existsSync(configFilePath)) {
|
||||||
|
const watcher = fs.watch(configFilePath, (eventType) => {
|
||||||
|
if (eventType === 'change' || eventType === 'rename') {
|
||||||
|
if (watchDebounceTimer) clearTimeout(watchDebounceTimer);
|
||||||
|
watchDebounceTimer = setTimeout(() => {
|
||||||
|
try {
|
||||||
|
const raw = fs.readFileSync(configFilePath, 'utf8');
|
||||||
|
const updated = JSON.parse(raw);
|
||||||
|
Object.assign(config, updated);
|
||||||
|
if (config.sql) {
|
||||||
|
config.sql.host = process.env.DB_HOST || process.env.POSTGRES_HOST || process.env.PGHOST || config.sql.host;
|
||||||
|
config.sql.port = parseInt(process.env.DB_PORT || process.env.POSTGRES_PORT || process.env.PGPORT || config.sql.port, 10);
|
||||||
|
config.sql.user = process.env.DB_USER || process.env.POSTGRES_USER || process.env.PGUSER || config.sql.user;
|
||||||
|
config.sql.password = process.env.DB_PASS || process.env.POSTGRES_PASSWORD || process.env.PGPASSWORD || config.sql.password;
|
||||||
|
config.sql.database = process.env.DB_NAME || process.env.POSTGRES_DB || process.env.PGDATABASE || config.sql.database;
|
||||||
|
}
|
||||||
|
console.log('[CONFIG] config.json reloaded dynamically');
|
||||||
|
} catch (_) {}
|
||||||
|
}, 100);
|
||||||
|
if (watchDebounceTimer.unref) watchDebounceTimer.unref();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (watcher.unref) watcher.unref();
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import cfg from "../config.mjs";
|
|||||||
import security from "../security.mjs";
|
import security from "../security.mjs";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import YAML from "yaml";
|
||||||
import { getManualApproval, setManualApproval, getMinTags, setMinTags, getRegistrationOpen, setRegistrationOpen, getTrustedUploads, setTrustedUploads, getEnablePdf, setEnablePdf, getLogUserIps, setLogUserIps, getHashUserIps, setHashUserIps, getEnableCleanup, setEnableCleanup, getCleanupStartDate, setCleanupStartDate, getCleanupEndDate, setCleanupEndDate, getCleanupIncludeEngaged, setCleanupIncludeEngaged, getShitpostMode, ensureAllItemsHaveSlugs, getEnableItemSlugs, getBrandImageUrl } from "../settings.mjs";
|
import { getManualApproval, setManualApproval, getMinTags, setMinTags, getRegistrationOpen, setRegistrationOpen, getTrustedUploads, setTrustedUploads, getEnablePdf, setEnablePdf, getLogUserIps, setLogUserIps, getHashUserIps, setHashUserIps, getEnableCleanup, setEnableCleanup, getCleanupStartDate, setCleanupStartDate, getCleanupEndDate, setCleanupEndDate, getCleanupIncludeEngaged, setCleanupIncludeEngaged, getShitpostMode, ensureAllItemsHaveSlugs, getEnableItemSlugs, getBrandImageUrl } from "../settings.mjs";
|
||||||
|
|
||||||
export default (router, tpl) => {
|
export default (router, tpl) => {
|
||||||
@@ -939,6 +940,15 @@ export default (router, tpl) => {
|
|||||||
// Write formatted JSON to config.json on disk
|
// Write formatted JSON to config.json on disk
|
||||||
await fs.writeFile(configPath, JSON.stringify(updatedConfig, null, 2) + "\n", "utf-8");
|
await fs.writeFile(configPath, JSON.stringify(updatedConfig, null, 2) + "\n", "utf-8");
|
||||||
|
|
||||||
|
// Also update config.yaml if it exists
|
||||||
|
const configYamlPath = path.resolve(process.cwd(), "config.yaml");
|
||||||
|
try {
|
||||||
|
const yamlDoc = new YAML.Document(updatedConfig);
|
||||||
|
await fs.writeFile(configYamlPath, String(yamlDoc), "utf-8");
|
||||||
|
} catch (yamlErr) {
|
||||||
|
console.warn('[ADMIN] Could not sync config.yaml:', yamlErr.message);
|
||||||
|
}
|
||||||
|
|
||||||
// Mutate in-memory cfg object so changes apply immediately
|
// Mutate in-memory cfg object so changes apply immediately
|
||||||
Object.assign(cfg, updatedConfig);
|
Object.assign(cfg, updatedConfig);
|
||||||
|
|
||||||
|
|||||||
+16
-2
@@ -221,7 +221,14 @@ export default (router, tpl) => {
|
|||||||
console.log(`[AJAX-RANDOM] ${itemid} total=${tAjaxRender - tAjaxStart}ms | getRandom=${tRandom - tAjaxStart}ms | getf0ck=${tAjaxFetch - tRandom}ms | aux=${tAjaxAux - tAjaxFetch}ms | render=${tAjaxRender - tAjaxAux}ms`);
|
console.log(`[AJAX-RANDOM] ${itemid} total=${tAjaxRender - tAjaxStart}ms | getRandom=${tRandom - tAjaxStart}ms | getf0ck=${tAjaxFetch - tRandom}ms | aux=${tAjaxAux - tAjaxFetch}ms | render=${tAjaxRender - tAjaxAux}ms`);
|
||||||
|
|
||||||
let itemPage = null;
|
let itemPage = null;
|
||||||
if (query.onara === '1' || req.cookies?.onara === '1' || req.cookies?.f0ck_onara === '1' || cfg.onara) {
|
const cfgOnara = cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara;
|
||||||
|
const cookieOnara = req.cookies?.f0ck_onara !== undefined
|
||||||
|
? (req.cookies.f0ck_onara === '1' || req.cookies.f0ck_onara === 'true')
|
||||||
|
: (req.cookies?.onara !== undefined ? (req.cookies.onara === '1' || req.cookies.onara === 'true') : null);
|
||||||
|
const effectiveOnara = (cfgOnara !== undefined && cfgOnara !== null)
|
||||||
|
? !!cfgOnara
|
||||||
|
: (query.onara === '1' || cookieOnara === true);
|
||||||
|
if (effectiveOnara) {
|
||||||
try {
|
try {
|
||||||
itemPage = await f0cklib.getItemPage({
|
itemPage = await f0cklib.getItemPage({
|
||||||
targetItemId: data.item?.id || itemid,
|
targetItemId: data.item?.id || itemid,
|
||||||
@@ -487,7 +494,14 @@ export default (router, tpl) => {
|
|||||||
- Render: ${tAjaxRender - tAjaxAux}ms`);
|
- Render: ${tAjaxRender - tAjaxAux}ms`);
|
||||||
|
|
||||||
let itemPage = null;
|
let itemPage = null;
|
||||||
if (query.onara === '1' || req.cookies?.onara === '1' || req.cookies?.f0ck_onara === '1' || cfg.onara || query.get_page === '1') {
|
const cfgOnara = cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara;
|
||||||
|
const cookieOnara = req.cookies?.f0ck_onara !== undefined
|
||||||
|
? (req.cookies.f0ck_onara === '1' || req.cookies.f0ck_onara === 'true')
|
||||||
|
: (req.cookies?.onara !== undefined ? (req.cookies.onara === '1' || req.cookies.onara === 'true') : null);
|
||||||
|
const effectiveOnara = (cfgOnara !== undefined && cfgOnara !== null)
|
||||||
|
? !!cfgOnara
|
||||||
|
: (query.onara === '1' || cookieOnara === true);
|
||||||
|
if (effectiveOnara || query.get_page === '1') {
|
||||||
try {
|
try {
|
||||||
itemPage = await f0cklib.getItemPage({
|
itemPage = await f0cklib.getItemPage({
|
||||||
targetItemId: data.item?.id || itemid,
|
targetItemId: data.item?.id || itemid,
|
||||||
|
|||||||
@@ -494,12 +494,14 @@ export default (router, tpl) => {
|
|||||||
return res.reply({ body });
|
return res.reply({ body });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cfgOnara = cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara;
|
||||||
const cookieOnara = req.cookies?.f0ck_onara !== undefined
|
const cookieOnara = req.cookies?.f0ck_onara !== undefined
|
||||||
? (req.cookies.f0ck_onara === '1' || req.cookies.f0ck_onara === 'true')
|
? (req.cookies.f0ck_onara === '1' || req.cookies.f0ck_onara === 'true')
|
||||||
: (req.cookies?.onara !== undefined ? (req.cookies.onara === '1' || req.cookies.onara === 'true') : null);
|
: (req.cookies?.onara !== undefined ? (req.cookies.onara === '1' || req.cookies.onara === 'true') : null);
|
||||||
const isOnara = cookieOnara !== null
|
// Global config onara overweighs always the user pref
|
||||||
? cookieOnara
|
const isOnara = (cfgOnara !== undefined && cfgOnara !== null)
|
||||||
: !!(req.session?.onara || (cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara));
|
? !!cfgOnara
|
||||||
|
: (cookieOnara !== null ? cookieOnara : !!req.session?.onara);
|
||||||
if (mode === 'item' && isOnara) {
|
if (mode === 'item' && isOnara) {
|
||||||
const itemHtml = tpl.render('ajax-item', data, req);
|
const itemHtml = tpl.render('ajax-item', data, req);
|
||||||
|
|
||||||
|
|||||||
+22
-1
@@ -1947,7 +1947,14 @@ process.on('uncaughtException', err => {
|
|||||||
enable_comments: cfg.enable_comments !== false,
|
enable_comments: cfg.enable_comments !== false,
|
||||||
public_nsfw: !!cfg.websrv.public_nsfw,
|
public_nsfw: !!cfg.websrv.public_nsfw,
|
||||||
public_untagged: !!cfg.websrv.public_untagged,
|
public_untagged: !!cfg.websrv.public_untagged,
|
||||||
onara: !!(cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara),
|
get onara() {
|
||||||
|
const c = cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara;
|
||||||
|
return !!c;
|
||||||
|
},
|
||||||
|
get onara_cfg() {
|
||||||
|
const c = cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara;
|
||||||
|
return (c !== undefined && c !== null) ? !!c : null;
|
||||||
|
},
|
||||||
is_onara_item: false,
|
is_onara_item: false,
|
||||||
enable_private_uploads: cfg.enable_private_uploads !== false,
|
enable_private_uploads: cfg.enable_private_uploads !== false,
|
||||||
get enable_expiring_uploads() { return getEnableExpiringUploads(); },
|
get enable_expiring_uploads() { return getEnableExpiringUploads(); },
|
||||||
@@ -2147,12 +2154,26 @@ process.on('uncaughtException', err => {
|
|||||||
data.max_file_size = lib.formatSize(cfg.main.maxfilesize * (activeReq.session?.admin ? cfg.main.adminmultiplier : 1));
|
data.max_file_size = lib.formatSize(cfg.main.maxfilesize * (activeReq.session?.admin ? cfg.main.adminmultiplier : 1));
|
||||||
data.max_file_size_bytes = Math.floor(cfg.main.maxfilesize * (activeReq.session?.admin ? cfg.main.adminmultiplier : 1));
|
data.max_file_size_bytes = Math.floor(cfg.main.maxfilesize * (activeReq.session?.admin ? cfg.main.adminmultiplier : 1));
|
||||||
data.web_url_upload = data.web_url_upload !== undefined ? data.web_url_upload : !!cfg.websrv.web_url_upload;
|
data.web_url_upload = data.web_url_upload !== undefined ? data.web_url_upload : !!cfg.websrv.web_url_upload;
|
||||||
|
|
||||||
|
const cfgOnara = cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara;
|
||||||
|
const cookieOnara = activeReq.cookies?.f0ck_onara !== undefined
|
||||||
|
? (activeReq.cookies.f0ck_onara === '1' || activeReq.cookies.f0ck_onara === 'true')
|
||||||
|
: (activeReq.cookies?.onara !== undefined ? (activeReq.cookies.onara === '1' || activeReq.cookies.onara === 'true') : null);
|
||||||
|
const effectiveOnara = (cfgOnara !== undefined && cfgOnara !== null)
|
||||||
|
? !!cfgOnara
|
||||||
|
: (cookieOnara !== null ? cookieOnara : !!activeReq.session?.onara);
|
||||||
|
data.onara = effectiveOnara;
|
||||||
|
data.onara_cfg = (cfgOnara !== undefined && cfgOnara !== null) ? !!cfgOnara : null;
|
||||||
} else {
|
} else {
|
||||||
data.recaptcha_enabled = perRequestRecaptcha;
|
data.recaptcha_enabled = perRequestRecaptcha;
|
||||||
data.theme = data.theme || cfg.websrv.theme || 'f0ck';
|
data.theme = data.theme || cfg.websrv.theme || 'f0ck';
|
||||||
data.user_strict_bool = false;
|
data.user_strict_bool = false;
|
||||||
data.user_logged_in_bool = false;
|
data.user_logged_in_bool = false;
|
||||||
globals.csrf_token = data.csrf_token || '';
|
globals.csrf_token = data.csrf_token || '';
|
||||||
|
|
||||||
|
const cfgOnara = cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara;
|
||||||
|
data.onara = !!cfgOnara;
|
||||||
|
data.onara_cfg = (cfgOnara !== undefined && cfgOnara !== null) ? !!cfgOnara : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return originalRender.call(tpl, view, data, (data.url && data.url !== req?.url) ? undefined : req);
|
return originalRender.call(tpl, view, data, (data.url && data.url !== req?.url) ? undefined : req);
|
||||||
|
|||||||
+9
-3
@@ -253,11 +253,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting-item" style="margin-top: 15px;">
|
<div class="setting-item" style="margin-top: 15px;">
|
||||||
<label for="onara_enabled_toggle" style="cursor: pointer; display: flex; align-items: center; gap: 10px;">
|
<label for="onara_enabled_toggle" style="cursor: @if(onara_cfg !== undefined && onara_cfg !== null) not-allowed @else pointer @endif; display: flex; align-items: center; gap: 10px;">
|
||||||
<input type="checkbox" id="onara_enabled_toggle">
|
<input type="checkbox" id="onara_enabled_toggle" @if(onara_cfg !== undefined && onara_cfg !== null) disabled @if(onara_cfg) checked @endif @endif>
|
||||||
<span>Enable Onara viewer</span>
|
<span>Enable Onara viewer</span>
|
||||||
</label>
|
</label>
|
||||||
<small class="text-muted" style="margin-left: 25px;">Open items in the fullscreen Onara modal instead of navigating to the item page. Fine-tune appearance in the <strong>Tuner → Background</strong> tab.</small>
|
<small class="text-muted" style="margin-left: 25px;">
|
||||||
|
@if(onara_cfg !== undefined && onara_cfg !== null)
|
||||||
|
Controlled by site configuration (@if(onara_cfg)enabled globally@else disabled globally@endif).
|
||||||
|
@else
|
||||||
|
Open items in the fullscreen Onara modal instead of navigating to the item page. Fine-tune appearance in the <strong>Tuner → Background</strong> tab.
|
||||||
|
@endif
|
||||||
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting-item" style="margin-top: 15px;">
|
<div class="setting-item" style="margin-top: 15px;">
|
||||||
|
|||||||
@@ -231,7 +231,7 @@
|
|||||||
@endif
|
@endif
|
||||||
@if(private_society && !session)
|
@if(private_society && !session)
|
||||||
<script>
|
<script>
|
||||||
window.f0ckSession = { logged_in: false, is_anon: false, excluded_tags: [], onara: @if(onara) true @else false @endif, enable_item_slugs: @if(enable_item_slugs) true @else false @endif, enable_anonymous_access: @if(enable_anonymous_access) true @else false @endif, anon_permissions: {{ anon_permissions_json || '{}' }}, hide_comments_from_public: @if(hide_comments_from_public) true @else false @endif, guest_anonymize: @if(guest_anonymize) true @else false @endif, anon_anonymize: @if(anon_anonymize) true @else false @endif, is_anonymized: @if(is_anonymized) true @else false @endif, enable_xd_score: @if(enable_xd_score) true @else false @endif, default_theme: "{{ default_theme }}", show_content_warning: @if(show_content_warning) true @else false @endif, use_new_layout: @if(default_layout === 'legacy')false @else true @endif, comment_display_mode: {{ comment_display_mode }}, comment_max_length: {{ comment_max_length !== null && comment_max_length !== undefined ? comment_max_length : 'null' }}, development: @if(development) true @else false @endif, allow_comment_deletion: @if(allow_comment_deletion) true @else false @endif, hide_sidebar_default: @if(hide_sidebar_default) true @else false @endif, public_untagged: @if(public_untagged) true @else false @endif, public_nsfw: @if(public_nsfw) true @else false @endif };
|
window.f0ckSession = { logged_in: false, is_anon: false, excluded_tags: [], onara: @if(onara) true @else false @endif, onara_cfg: @if(onara_cfg !== undefined && onara_cfg !== null) @if(onara_cfg) true @else false @endif @else null @endif, enable_item_slugs: @if(enable_item_slugs) true @else false @endif, enable_anonymous_access: @if(enable_anonymous_access) true @else false @endif, anon_permissions: {{ anon_permissions_json || '{}' }}, hide_comments_from_public: @if(hide_comments_from_public) true @else false @endif, guest_anonymize: @if(guest_anonymize) true @else false @endif, anon_anonymize: @if(anon_anonymize) true @else false @endif, is_anonymized: @if(is_anonymized) true @else false @endif, enable_xd_score: @if(enable_xd_score) true @else false @endif, default_theme: "{{ default_theme }}", show_content_warning: @if(show_content_warning) true @else false @endif, use_new_layout: @if(default_layout === 'legacy')false @else true @endif, comment_display_mode: {{ comment_display_mode }}, comment_max_length: {{ comment_max_length !== null && comment_max_length !== undefined ? comment_max_length : 'null' }}, development: @if(development) true @else false @endif, allow_comment_deletion: @if(allow_comment_deletion) true @else false @endif, hide_sidebar_default: @if(hide_sidebar_default) true @else false @endif, public_untagged: @if(public_untagged) true @else false @endif, public_nsfw: @if(public_nsfw) true @else false @endif };
|
||||||
window.f0ckDebug = window.f0ckSession.development ? console.log.bind(console) : () => {};
|
window.f0ckDebug = window.f0ckSession.development ? console.log.bind(console) : () => {};
|
||||||
window.f0ckDefaultThumbSize = "{{ default_thumb_size }}";
|
window.f0ckDefaultThumbSize = "{{ default_thumb_size }}";
|
||||||
(() => {
|
(() => {
|
||||||
@@ -471,6 +471,7 @@
|
|||||||
<script>
|
<script>
|
||||||
window.f0ckSession = {
|
window.f0ckSession = {
|
||||||
onara: @if(onara) true @else false @endif,
|
onara: @if(onara) true @else false @endif,
|
||||||
|
onara_cfg: @if(onara_cfg !== undefined && onara_cfg !== null) @if(onara_cfg) true @else false @endif @else null @endif,
|
||||||
public_untagged: @if(public_untagged) true @else false @endif,
|
public_untagged: @if(public_untagged) true @else false @endif,
|
||||||
public_nsfw: @if(public_nsfw) true @else false @endif,
|
public_nsfw: @if(public_nsfw) true @else false @endif,
|
||||||
enable_item_slugs: @if(enable_item_slugs) true @else false @endif,
|
enable_item_slugs: @if(enable_item_slugs) true @else false @endif,
|
||||||
|
|||||||
Reference in New Issue
Block a user