mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
feat(themes): import a theme from a local .zip (#1012)
* feat(themes): validate and extract locally imported theme packages Add the backend + validation half of local theme import: users will be able to load a theme packaged as a .zip (manifest.json + theme.css). - `import_theme_zip` Tauri command unpacks only manifest.json + theme.css from the archive, outside the webview, with an archive-size cap, per-entry uncompressed caps, and path-traversal rejection. - `validateThemePackage` runs the full theme-store contract in-app: the manifest schema (field patterns copied from the repo schema), the CSS token whitelist with all core tokens required, color-scheme matching the declared mode, data-URI restricted to the arrow token, and a guard against ids that collide with built-in themes. The existing `validateThemeCss` containment guard is reused and runs again at injection time. The contract token list is a byte-identical copy of the themes repo's allowed-tokens.json. Covered by validateThemePackage tests for every rejection class. * feat(themes): add the Import a theme section to the Themes tab A dedicated section between the theme scheduler and the Theme Store lets users import a theme from a local .zip. After the package validates, a confirmation dialog names the theme and its author before it is installed. A rejected import shows a plain-language explanation aimed at end users; the raw contract diagnostics (token names, missing fields) are tucked into a collapsible "Technical details" block for theme authors. Fully localised across all nine languages. * docs(themes): changelog + credits for local theme import Fold the local .zip import (and the store pagination / refresh-scroll polish) into the still-unreleased Theme Store entry rather than a new section, and extend the credits line. PRs #1011 and #1012.
This commit is contained in:
@@ -432,6 +432,16 @@ export const settings = {
|
||||
themeStorePagePrev: 'Предыдущая страница',
|
||||
themeStorePageNext: 'Следующая страница',
|
||||
themeStorePageStatus: 'Страница {{page}} из {{total}}',
|
||||
themeImportTitle: 'Импорт темы',
|
||||
themeImportButton: 'Импортировать тему…',
|
||||
themeImporting: 'Импорт…',
|
||||
themeImportHint: 'Загружает тему, упакованную в .zip (manifest.json + theme.css).',
|
||||
themeImportSuccess: '«{{name}}» импортирована.',
|
||||
themeImportErrorTitle: 'Не удалось импортировать эту тему',
|
||||
themeImportErrorBody: 'Он не соответствует формату тем Psysonic. Возможно, он создан для другой версии или файл неполный — проверьте, что выбрали правильный .zip, или обратитесь к автору темы.',
|
||||
themeImportErrorDetails: 'Технические подробности',
|
||||
themeImportConfirmTitle: 'Установить тему?',
|
||||
themeImportConfirmBody: 'Установить «{{name}}» от {{author}}?',
|
||||
tabLibrary: 'Библиотека',
|
||||
tabServers: 'Серверы',
|
||||
tabLyrics: 'Тексты песен',
|
||||
|
||||
Reference in New Issue
Block a user