From 1be297221ed7f7c209917c44928c541f0f49a603 Mon Sep 17 00:00:00 2001 From: Jesper Zedlitz Date: Thu, 8 May 2025 13:14:59 +0200 Subject: [PATCH] started with i18n Started to use i18n to translate some texts in admin.js. --- package-lock.json | 226 ++++++++++++++++++++++++++++++++++++- package.json | 3 +- server.js | 27 ++++- src/locales/de.json | 23 ++++ src/locales/en.json | 23 ++++ src/pages/nonfederated.hbs | 9 +- src/routes/admin.js | 46 +++++--- 7 files changed, 324 insertions(+), 33 deletions(-) create mode 100644 src/locales/de.json create mode 100644 src/locales/en.json diff --git a/package-lock.json b/package-lock.json index 0113c3e..b1df7df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "postmarks", "version": "0.0.1", "license": "MIT", "dependencies": { @@ -20,6 +21,7 @@ "express-basic-auth": "^1.2.1", "express-handlebars": "^6.0.7", "express-session": "^1.17.3", + "i18n": "^0.15.1", "linkifyjs": "^4.1.1", "node-fetch": "^3.3.2", "open-graph-scraper": "^5.2.3", @@ -257,6 +259,50 @@ "node": ">=10" } }, + "node_modules/@messageformat/core": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.4.0.tgz", + "integrity": "sha512-NgCFubFFIdMWJGN5WuQhHCNmzk7QgiVfrViFxcS99j7F5dDS5EP6raR54I+2ydhe4+5/XTn/YIEppFaqqVWHsw==", + "license": "MIT", + "dependencies": { + "@messageformat/date-skeleton": "^1.0.0", + "@messageformat/number-skeleton": "^1.0.0", + "@messageformat/parser": "^5.1.0", + "@messageformat/runtime": "^3.0.1", + "make-plural": "^7.0.0", + "safe-identifier": "^0.4.1" + } + }, + "node_modules/@messageformat/date-skeleton": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.1.0.tgz", + "integrity": "sha512-rmGAfB1tIPER+gh3p/RgA+PVeRE/gxuQ2w4snFWPF5xtb5mbWR7Cbw7wCOftcUypbD6HVoxrVdyyghPm3WzP5A==", + "license": "MIT" + }, + "node_modules/@messageformat/number-skeleton": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@messageformat/number-skeleton/-/number-skeleton-1.2.0.tgz", + "integrity": "sha512-xsgwcL7J7WhlHJ3RNbaVgssaIwcEyFkBqxHdcdaiJzwTZAWEOD8BuUFxnxV9k5S0qHN3v/KzUpq0IUpjH1seRg==", + "license": "MIT" + }, + "node_modules/@messageformat/parser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.1.1.tgz", + "integrity": "sha512-3p0YRGCcTUCYvBKLIxtDDyrJ0YijGIwrTRu1DT8gIviIDZru8H23+FkY6MJBzM1n9n20CiM4VeDYuBsrrwnLjg==", + "license": "MIT", + "dependencies": { + "moo": "^0.5.1" + } + }, + "node_modules/@messageformat/runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz", + "integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==", + "license": "MIT", + "dependencies": { + "make-plural": "^7.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2692,6 +2738,15 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-printf": { + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.10.tgz", + "integrity": "sha512-GwTgG9O4FVIdShhbVF3JxOgSBY2+ePGsu2V/UONgoCPzF9VY6ZdBMKsHKCYQHZwNk3qNouUolRDsgVxcVA5G1w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=10.0" + } + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -3312,6 +3367,43 @@ "ms": "^2.0.0" } }, + "node_modules/i18n": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.15.1.tgz", + "integrity": "sha512-yue187t8MqUPMHdKjiZGrX+L+xcUsDClGO0Cz4loaKUOK9WrGw5pgan4bv130utOwX7fHE9w2iUeHFalVQWkXA==", + "license": "MIT", + "dependencies": { + "@messageformat/core": "^3.0.0", + "debug": "^4.3.3", + "fast-printf": "^1.6.9", + "make-plural": "^7.0.0", + "math-interval-parser": "^2.0.1", + "mustache": "^4.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/mashpie" + } + }, + "node_modules/i18n/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -3931,6 +4023,21 @@ "node": ">=8" } }, + "node_modules/make-plural": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.4.0.tgz", + "integrity": "sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg==", + "license": "Unicode-DFS-2016" + }, + "node_modules/math-interval-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", + "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -4195,11 +4302,25 @@ "node": ">=10" } }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "license": "BSD-3-Clause" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "devOptional": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } }, "node_modules/natural-compare": { "version": "1.4.0", @@ -5352,6 +5473,12 @@ } ] }, + "node_modules/safe-identifier": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz", + "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==", + "license": "ISC" + }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -6354,6 +6481,45 @@ } } }, + "@messageformat/core": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.4.0.tgz", + "integrity": "sha512-NgCFubFFIdMWJGN5WuQhHCNmzk7QgiVfrViFxcS99j7F5dDS5EP6raR54I+2ydhe4+5/XTn/YIEppFaqqVWHsw==", + "requires": { + "@messageformat/date-skeleton": "^1.0.0", + "@messageformat/number-skeleton": "^1.0.0", + "@messageformat/parser": "^5.1.0", + "@messageformat/runtime": "^3.0.1", + "make-plural": "^7.0.0", + "safe-identifier": "^0.4.1" + } + }, + "@messageformat/date-skeleton": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.1.0.tgz", + "integrity": "sha512-rmGAfB1tIPER+gh3p/RgA+PVeRE/gxuQ2w4snFWPF5xtb5mbWR7Cbw7wCOftcUypbD6HVoxrVdyyghPm3WzP5A==" + }, + "@messageformat/number-skeleton": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@messageformat/number-skeleton/-/number-skeleton-1.2.0.tgz", + "integrity": "sha512-xsgwcL7J7WhlHJ3RNbaVgssaIwcEyFkBqxHdcdaiJzwTZAWEOD8BuUFxnxV9k5S0qHN3v/KzUpq0IUpjH1seRg==" + }, + "@messageformat/parser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.1.1.tgz", + "integrity": "sha512-3p0YRGCcTUCYvBKLIxtDDyrJ0YijGIwrTRu1DT8gIviIDZru8H23+FkY6MJBzM1n9n20CiM4VeDYuBsrrwnLjg==", + "requires": { + "moo": "^0.5.1" + } + }, + "@messageformat/runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz", + "integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==", + "requires": { + "make-plural": "^7.0.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -8160,6 +8326,11 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "fast-printf": { + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.10.tgz", + "integrity": "sha512-GwTgG9O4FVIdShhbVF3JxOgSBY2+ePGsu2V/UONgoCPzF9VY6ZdBMKsHKCYQHZwNk3qNouUolRDsgVxcVA5G1w==" + }, "fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -8602,6 +8773,29 @@ "ms": "^2.0.0" } }, + "i18n": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.15.1.tgz", + "integrity": "sha512-yue187t8MqUPMHdKjiZGrX+L+xcUsDClGO0Cz4loaKUOK9WrGw5pgan4bv130utOwX7fHE9w2iUeHFalVQWkXA==", + "requires": { + "@messageformat/core": "^3.0.0", + "debug": "^4.3.3", + "fast-printf": "^1.6.9", + "make-plural": "^7.0.0", + "math-interval-parser": "^2.0.1", + "mustache": "^4.2.0" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "requires": { + "ms": "^2.1.3" + } + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -9044,6 +9238,16 @@ } } }, + "make-plural": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.4.0.tgz", + "integrity": "sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg==" + }, + "math-interval-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", + "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -9240,11 +9444,20 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, + "moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==" + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "devOptional": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==" }, "natural-compare": { "version": "1.4.0", @@ -10019,6 +10232,11 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safe-identifier": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz", + "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==" + }, "safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", diff --git a/package.json b/package.json index 590a109..51176ca 100644 --- a/package.json +++ b/package.json @@ -17,17 +17,18 @@ "csv-stringify": "^6.4.2", "dotenv": "^16.0.3", "es6-promisify": "^7.0.0", + "escape-html": "^1.0.3", "express": "^4.18.2", "express-basic-auth": "^1.2.1", "express-handlebars": "^6.0.7", "express-session": "^1.17.3", + "i18n": "^0.15.1", "linkifyjs": "^4.1.1", "node-fetch": "^3.3.2", "open-graph-scraper": "^5.2.3", "sqlite": "^5.0.1", "sqlite3": "^5.1.5", "string-strip-html": "^13.4.2", - "escape-html": "^1.0.3", "xml2js": "^0.6.2" }, "engines": { diff --git a/server.js b/server.js index d9a617a..72e408b 100644 --- a/server.js +++ b/server.js @@ -3,6 +3,9 @@ import express from 'express'; import cors from 'cors'; import { create } from 'express-handlebars'; import escapeHTML from 'escape-html'; +import i18n from 'i18n'; +import path from 'path'; +import { fileURLToPath } from 'url'; import { domain, account, simpleLogger, actorInfo, replaceEmptyText } from './src/util.js'; import session, { isAuthenticated } from './src/session-auth.js'; @@ -11,6 +14,9 @@ import * as apDb from './src/activity-pub-db.js'; import routes from './src/routes/index.js'; +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + dotenv.config(); const PORT = process.env.PORT || 3000; @@ -23,6 +29,19 @@ app.use(express.json({ type: ['application/json', 'application/ld+json', 'applic app.use(session()); +i18n.configure({ + locales: ['en', 'de'], + directory: path.join(__dirname, '/src/locales'), + defaultLocale: 'en', + cookie: 'lang', + queryParameter: 'lang', // for example /route?lang=fr + objectNotation: true, + // autoReload: true, // activiate this for development + // syncFiles: true, // activiate this for development +}); + +app.use(i18n.init); + app.use((req, res, next) => { res.locals.loggedIn = req.session.loggedIn; return next(); @@ -92,14 +111,14 @@ const hbs = create({ const lowercased = array.map((tag) => tag.toLowerCase()); return lowercased.indexOf(item.toLowerCase()) >= 0 ? options.fn(this) : options.inverse(this); }, - removeTag(tag, path) { - return path + removeTag(tag, path_) { + return path_ .split('/') .filter((x) => x.toLowerCase() !== tag.toLowerCase()) .join('/'); }, - ifThisTag(tag, path, options) { - return path.toLowerCase() === `/tagged/${tag}`.toLowerCase() ? options.fn(this) : options.inverse(this); + ifThisTag(tag, path_, options) { + return path_.toLowerCase() === `/tagged/${tag}`.toLowerCase() ? options.fn(this) : options.inverse(this); }, eq(a, b, options) { return a === b ? options.fn(this) : options.inverse(this); diff --git a/src/locales/de.json b/src/locales/de.json new file mode 100644 index 0000000..bb87f89 --- /dev/null +++ b/src/locales/de.json @@ -0,0 +1,23 @@ +{ + "admin" : { + "bookmarklet" : { + "title" : "JavaScript-Lesezeichen" + }, + "data_export" : { + "title" : "Datenexport" + }, + "followers" : { + "title" : "Berechtigungen & Follower" + }, + "following" : { + "title" : "Konten, denen ich folge" + }, + "import_bookmarks" : { + "title" : "Lesezeichen importieren" + } + }, + "nonfederated" : { + "message" : "Diese Funktion ist derzeit nicht aktiviert, da diese App offenbar nicht für das Fediverse eingerichtet ist. Wenn du denkst, das ist ein Fehler, überprüfe die Setup-Anleitung und stelle sicher, dass du alle Schritte zur Erstellung einer Identität befolgt hast.", + "title" : "Nicht aktiviert" + } +} diff --git a/src/locales/en.json b/src/locales/en.json new file mode 100644 index 0000000..dd2ed3a --- /dev/null +++ b/src/locales/en.json @@ -0,0 +1,23 @@ +{ + "nonfederated": { + "title": "Not enabled", + "message": "This feature is currently not enabled as it appears you don’t have this app set up to run on the fediverse. If you think that’s incorrect, go back to the setup instructions and make sure you’ve followed the necessary steps to create an identity." + }, + "admin": { + "bookmarklet": { + "title": "Bookmarklet" + }, + "data_export": { + "title": "Data export" + }, + "following": { + "title": "Federated follows" + }, + "followers": { + "title": "Permissions & followers" + }, + "import_bookmarks": { + "title": "Import bookmars" + }, + } +} diff --git a/src/pages/nonfederated.hbs b/src/pages/nonfederated.hbs index ee885b7..1f6a130 100644 --- a/src/pages/nonfederated.hbs +++ b/src/pages/nonfederated.hbs @@ -1,9 +1,4 @@
-

Not enabled

-

- This feature is currently not enabled as it appears you don’t have this app - set up to run on the fediverse. If you think that’s incorrect, go back to - the setup instructions and make sure you’ve followed the necessary steps to - create an identity. -

+

{{warning}}

+

{{message}}

diff --git a/src/routes/admin.js b/src/routes/admin.js index 8847362..572841f 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -7,19 +7,23 @@ import { lookupActorInfo, createFollowMessage, createUnfollowMessage, signAndSen const DATA_PATH = '/app/.data'; -const ADMIN_LINKS = [ - { href: '/admin', label: 'Bookmarklet' }, - { href: '/admin/bookmarks', label: 'Import bookmarks' }, - { href: '/admin/followers', label: 'Permissions & followers' }, - { href: '/admin/following', label: 'Federated follows' }, - { href: '/admin/data', label: 'Data export' }, -]; +function adminLinks(req) { + // eslint-disable-next-line prefer-destructuring + const __ = req.__; + return [ + { href: '/admin', label: __('admin.bookmarklet.title') }, + { href: '/admin/bookmarks', label: __('admin.import_bookmarks.title') }, + { href: '/admin/followers', label: __('admin.followers.title') }, + { href: '/admin/following', label: __('admin.following.title') }, + { href: '/admin/data', label: __('admin.data_export.title') }, + ]; +} const router = express.Router(); router.get('/', isAuthenticated, async (req, res) => { - const params = req.query.raw ? {} : { title: 'Bookmarklet' }; - params.adminLinks = ADMIN_LINKS; + const params = req.query.raw ? {} : { title: req.__('admin.bookmarklet.title') }; + params.adminLinks = adminLinks(req); params.currentPath = req.originalUrl; params.bookmarklet = `javascript:(function(){w=window.open('https://${domain}/bookmark/popup?url='+encodeURIComponent(window.location.href)+'&highlight='+encodeURIComponent(window.getSelection().toString()),'postmarks','scrollbars=yes,width=550,height=600');})();`; params.bookmarkletTruncated = `${params.bookmarklet.substr(0, 30)}…`; @@ -28,21 +32,25 @@ router.get('/', isAuthenticated, async (req, res) => { }); router.get('/bookmarks', isAuthenticated, async (req, res) => { - const params = req.query.raw ? {} : { title: 'Import bookmarks' }; - params.adminLinks = ADMIN_LINKS; + const params = req.query.raw ? {} : { title: req.__('admin.import_bookmarks.title') }; + params.adminLinks = adminLinks(req); params.currentPath = req.originalUrl; return res.render('admin/bookmarks', params); }); router.get('/followers', isAuthenticated, async (req, res) => { - const params = req.query.raw ? {} : { title: 'Permissions & followers' }; - params.adminLinks = ADMIN_LINKS; + // eslint-disable-next-line prefer-destructuring + const __ = req.__; + const params = req.query.raw ? {} : { title: __('admin.followers.title') }; + params.adminLinks = adminLinks(req); params.currentPath = req.originalUrl; const apDb = req.app.get('apDb'); if (actorInfo.disabled) { + params.warning = __('nonfederated.title'); + params.message = __('nonfederated.message'); return res.render('nonfederated', params); } @@ -69,13 +77,17 @@ router.get('/followers', isAuthenticated, async (req, res) => { }); router.get('/following', isAuthenticated, async (req, res) => { - const params = req.query.raw ? {} : { title: 'Federated follows' }; - params.adminLinks = ADMIN_LINKS; + // eslint-disable-next-line prefer-destructuring + const __ = req.__; + const params = req.query.raw ? {} : { title: __('admin.following.title') }; + params.adminLinks = adminLinks(req); params.currentPath = req.originalUrl; const apDb = req.app.get('apDb'); if (actorInfo.disabled) { + params.warning = __('nonfederated.title'); + params.message = __('nonfederated.message'); return res.render('nonfederated', params); } @@ -90,8 +102,8 @@ router.get('/following', isAuthenticated, async (req, res) => { }); router.get('/data', isAuthenticated, async (req, res) => { - const params = req.query.raw ? {} : { title: 'Data export' }; - params.adminLinks = ADMIN_LINKS; + const params = req.query.raw ? {} : { title: req.__('admin.data_export.title') }; + params.adminLinks = adminLinks(req); params.currentPath = req.originalUrl; return res.render('admin/data', params);