feat: Playtube Stream Dock Plugin 1.0.0 (Ajazz AKP153E) mit Icon-Pack
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
// Erzeugt das Playtube-Icon-Pack (PNG, 288x288) in zwei Varianten und packt es als Zip.
|
||||
// Aufruf: npm run iconpack
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { copyFileSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { Canvas } from './raster.mjs';
|
||||
import { drawGlyph, GLYPHS } from './glyphs.mjs';
|
||||
import { drawExtra, EXTRA_GLYPHS } from './glyphs-extra.mjs';
|
||||
import { drawApp, APP_GLYPHS } from './glyphs-apps.mjs';
|
||||
import { DARK_BG, WHITE, brandGradient } from './brand.mjs';
|
||||
|
||||
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const PACK_NAME = 'Playtube-Icons';
|
||||
const PACK_DIR = path.join(ROOT, 'iconpack', PACK_NAME);
|
||||
const ZIP = path.join(ROOT, 'dist', `${PACK_NAME}.zip`);
|
||||
const SIZE = 288;
|
||||
const GLYPH_RADIUS = SIZE * 0.31;
|
||||
|
||||
const README = `Playtube Icon Pack
|
||||
==================
|
||||
|
||||
Ordner:
|
||||
gradient/ Playtube-Look: Verlauf violett -> pink, weisses Symbol
|
||||
dark/ dunkler Hintergrund, Symbol im Playtube-Verlauf
|
||||
|
||||
Alle Bilder: PNG, 288 x 288 Pixel (das Geraet nutzt 144 x 144, die doppelte Groesse bleibt beim
|
||||
Verkleinern scharf).
|
||||
|
||||
Benutzen in der Stream-Dock-Software:
|
||||
Taste anklicken -> das Vorschaubild der Taste (oben links im Einstellungsbereich) anklicken ->
|
||||
"Bild waehlen" / Ordner-Symbol -> eine PNG-Datei aus diesem Pack auswaehlen.
|
||||
`;
|
||||
|
||||
function render(variant, drawer, name) {
|
||||
const canvas = new Canvas(SIZE);
|
||||
const gradient = brandGradient(SIZE);
|
||||
const background = variant === 'gradient' ? gradient : DARK_BG;
|
||||
canvas.roundRect(0, 0, SIZE, SIZE, 0, background);
|
||||
drawer(canvas, name, SIZE / 2, SIZE / 2, GLYPH_RADIUS, variant === 'gradient' ? WHITE : gradient, background);
|
||||
return canvas.png();
|
||||
}
|
||||
|
||||
const SD_PACK_DIR = path.join(ROOT, 'iconpack', 'com.fojadrachi.playtube.sdIconPack');
|
||||
// Deutsche Suchbegriffe zusaetzlich zu den englischen Symbolnamen.
|
||||
const GERMAN_TAGS = {
|
||||
folder: ['ordner'], file: ['datei'], home: ['start', 'zuhause'], gear: ['einstellungen', 'zahnrad'],
|
||||
plus: ['hinzufuegen'], minus: ['entfernen'], close: ['schliessen'], check: ['haken', 'ok'], star: ['stern', 'favorit'],
|
||||
search: ['suche', 'lupe'], power: ['ein', 'aus'], mic: ['mikrofon'], headphones: ['kopfhoerer'], lock: ['schloss'],
|
||||
bell: ['glocke', 'benachrichtigung'], clock: ['uhr', 'zeit'], calendar: ['kalender'], mail: ['post', 'email'],
|
||||
globe: ['welt', 'internet'], download: ['herunterladen'], upload: ['hochladen'], trash: ['papierkorb', 'loeschen'],
|
||||
eye: ['auge', 'anzeigen'], stop: ['stopp'], refresh: ['aktualisieren', 'neu laden'], wifi: ['wlan'], grid: ['raster'],
|
||||
menu: ['menue'], more: ['mehr'], info: ['information'], warning: ['warnung'], monitor: ['bildschirm'],
|
||||
sun: ['sonne', 'hell'], moon: ['mond', 'dunkel'], play: ['abspielen'], pause: ['pause'], next: ['weiter', 'naechster'],
|
||||
previous: ['zurueck', 'vorheriger'], volup: ['lauter'], voldown: ['leiser'], vol: ['lautstaerke'], mute: ['stumm'],
|
||||
heart: ['herz', 'gefaellt mir'], shuffle: ['zufall'], repeat: ['wiederholen'], playlist: ['liste'],
|
||||
'eye-off': ['auge', 'ausblenden', 'verstecken'], lightbulb: ['gluehbirne', 'licht', 'lampe'],
|
||||
'pc-monitor': ['pc', 'computer', 'system', 'monitor', 'leistung'], chrome: ['browser', 'google'],
|
||||
discord: ['chat', 'voice'], steam: ['spiele', 'games'], twitch: ['stream', 'live'], netflix: ['serien', 'filme'],
|
||||
youtube: ['video'], medal: ['clips', 'aufnahme'], nvidia: ['grafikkarte', 'gpu'], steelseries: ['sonar', 'audio'],
|
||||
aniworld: ['anime'], prismlens: ['filter', 'kamera'],
|
||||
};
|
||||
|
||||
/** Stream-Dock-Icon-Pack (.sdIconPack): manifest.json, icons.json, icon.png und icons/*.png. */
|
||||
function buildStreamDockPack(jobs) {
|
||||
rmSync(SD_PACK_DIR, { recursive: true, force: true });
|
||||
mkdirSync(path.join(SD_PACK_DIR, 'icons'), { recursive: true });
|
||||
mkdirSync(path.join(SD_PACK_DIR, 'previews'), { recursive: true });
|
||||
const entries = [];
|
||||
for (const variant of ['gradient', 'dark']) {
|
||||
for (const { name } of jobs) {
|
||||
const file = `${variant}_${name}.png`;
|
||||
copyFileSync(path.join(PACK_DIR, variant, `${name}.png`), path.join(SD_PACK_DIR, 'icons', file));
|
||||
const base = name.split('-')[0];
|
||||
entries.push({
|
||||
path: file,
|
||||
name: `${name.replace(/-/g, ' ')} (${variant})`,
|
||||
tags: ['playtube', variant, ...name.split('-'), ...(GERMAN_TAGS[name] || GERMAN_TAGS[base] || [])],
|
||||
});
|
||||
}
|
||||
}
|
||||
writeFileSync(path.join(SD_PACK_DIR, 'icons.json'), `${JSON.stringify(entries, null, 2)}\n`);
|
||||
writeFileSync(path.join(SD_PACK_DIR, 'manifest.json'), `${JSON.stringify({
|
||||
Name: 'Playtube Icons',
|
||||
Version: '1.0.0',
|
||||
Description: 'Icons im Playtube-Look (Verlauf violett/pink): Ordner, Pfeile, Player-Symbole und mehr.',
|
||||
Author: 'Playtube',
|
||||
Icon: 'icon.png',
|
||||
}, null, 2)}\n`);
|
||||
const logo = render('gradient', drawGlyph, 'play');
|
||||
writeFileSync(path.join(SD_PACK_DIR, 'icon.png'), logo);
|
||||
writeFileSync(path.join(SD_PACK_DIR, 'previews', 'preview1.png'), logo);
|
||||
}
|
||||
|
||||
function main() {
|
||||
rmSync(PACK_DIR, { recursive: true, force: true });
|
||||
const jobs = [
|
||||
...GLYPHS.map((name) => ({ name, drawer: drawGlyph })),
|
||||
...EXTRA_GLYPHS.map((name) => ({ name, drawer: drawExtra })),
|
||||
...APP_GLYPHS.map((name) => ({ name, drawer: drawApp })),
|
||||
];
|
||||
for (const variant of ['gradient', 'dark']) {
|
||||
mkdirSync(path.join(PACK_DIR, variant), { recursive: true });
|
||||
for (const { name, drawer } of jobs) {
|
||||
writeFileSync(path.join(PACK_DIR, variant, `${name}.png`), render(variant, drawer, name));
|
||||
}
|
||||
}
|
||||
writeFileSync(path.join(PACK_DIR, 'LIESMICH.txt'), README);
|
||||
buildStreamDockPack(jobs);
|
||||
|
||||
mkdirSync(path.dirname(ZIP), { recursive: true });
|
||||
rmSync(ZIP, { force: true });
|
||||
// Unter Windows das mitgelieferte bsdtar (Git-Bash-GNU-tar liest "C:" als Netzwerk-Host).
|
||||
const tar = process.platform === 'win32' ? path.join(process.env.SystemRoot || 'C:\\Windows', 'System32', 'tar.exe') : 'tar';
|
||||
execFileSync(tar, ['-a', '-c', '-f', ZIP, '-C', path.dirname(PACK_DIR), PACK_NAME], { stdio: 'inherit' });
|
||||
process.stdout.write(`${jobs.length} Symbole x 2 Varianten -> ${PACK_DIR}\nZip: ${ZIP}\n`);
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user