mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-06-13 12:15:09 +03:00
Compare commits
7 Commits
v3.2.4-pre1
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 00e866c39e | |||
| 5490961056 | |||
| d4442f6b0d | |||
| 7a629f1cef | |||
| 7a7ecdac55 | |||
| 232fadd796 | |||
| acaf165219 |
@@ -15,6 +15,9 @@
|
||||
<a href="https://deckbrew.xyz/discord"><img src="https://img.shields.io/discord/960281551428522045?color=%235865F2&label=discord" /></a>
|
||||
<br>
|
||||
<br>
|
||||
🌐 <a href="./README.md">English</a> · <a href="./README_zh-Hans.md">简体中文</a>
|
||||
<br>
|
||||
<br>
|
||||
<!-- <img src="https://media.discordapp.net/attachments/966017112244125756/1012466063893610506/main.jpg" alt="Decky screenshot" width="80%">-->
|
||||
</p>
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
<h1 align="center">
|
||||
<a name="logo" href="https://deckbrew.xyz/"><img src="https://deckbrew.xyz/static/icon-45ca1f5aea376a9ad37e92db906f283e.png" alt="Deckbrew logo" width="200"></a>
|
||||
<br>
|
||||
Decky Loader
|
||||
<br>
|
||||
<a name="download button" href="https://github.com/SteamDeckHomebrew/decky-installer/releases/latest/download/decky_installer.desktop"><img src="./docs/images/download_button.svg" alt="Download decky" width="150px" style="padding-top: 15px;"></a>
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/SteamDeckHomebrew/decky-loader/releases"><img src="https://img.shields.io/github/downloads/SteamDeckHomebrew/decky-loader/total" /></a>
|
||||
<a href="https://github.com/SteamDeckHomebrew/decky-loader/stargazers"><img src="https://img.shields.io/github/stars/SteamDeckHomebrew/decky-loader" /></a>
|
||||
<a href="https://github.com/SteamDeckHomebrew/decky-loader/commits/main"><img src="https://img.shields.io/github/last-commit/SteamDeckHomebrew/decky-loader.svg" /></a>
|
||||
<a href="https://weblate.werwolv.net/engage/decky/"><img src="https://weblate.werwolv.net/widgets/decky/-/decky/svg-badge.svg" alt="Translation status" /></a>
|
||||
<a href="https://github.com/SteamDeckHomebrew/decky-loader/blob/main/LICENSE"><img src="https://img.shields.io/github/license/SteamDeckHomebrew/decky-loader" /></a>
|
||||
<a href="https://deckbrew.xyz/discord"><img src="https://img.shields.io/discord/960281551428522045?color=%235865F2&label=discord" /></a>
|
||||
<br>
|
||||
<br>
|
||||
🌐 <a href="./README.md">English</a> · <a href="./README_zh-Hans.md">简体中文</a>
|
||||
<br>
|
||||
<br>
|
||||
<!-- <img src="https://media.discordapp.net/attachments/966017112244125756/1012466063893610506/main.jpg" alt="Decky screenshot" width="80%">-->
|
||||
</p>
|
||||
|
||||
## 🩵 赞助者
|
||||
|
||||
[成为赞助者](https://opencollective.com/steamdeckhomebrew)来支持我们的工作!向我们的集体项目捐款将帮助 Decky Loader 开发者支付网络服务器费用、购买新的开发硬件等。
|
||||
|
||||
<a href="https://opencollective.com/steamdeckhomebrew"><img alt="Steam Deck Homebrew sponsors on Open Collective" src="https://opencollective.com/steamdeckhomebrew/sponsors.svg?button=true&avatarHeight=46&width=750"></a>
|
||||
|
||||
<a href="https://opencollective.com/steamdeckhomebrew"><img alt="Steam Deck Homebrew backers on Open Collective" src="https://opencollective.com/steamdeckhomebrew/backers.svg?button=false&avatarHeight=46&width=750"></a>
|
||||
|
||||
## 📖 关于
|
||||
|
||||
Decky Loader 是一款用于 Steam Deck 的自制插件启动器。它可以用来[美化菜单界面](https://github.com/suchmememanyskill/SDH-CssLoader)、[更改系统音效](https://github.com/EMERALD0874/SDH-AudioLoader)、[调整屏幕饱和度](https://github.com/libvibrant/vibrantDeck)、[修改更多系统设置](https://github.com/NGnius/PowerTools),以及[更多功能](https://plugins.deckbrew.xyz/)。
|
||||
|
||||
有关 Decky Loader 的更多信息、文档和开发工具,请访问[我们的维基](https://wiki.deckbrew.xyz)。
|
||||
|
||||
### 🎨 功能特性
|
||||
|
||||
🧹 干净地注入和加载多个插件。
|
||||
🔒 在系统更新和重启后仍然保持安装状态。
|
||||
🔗 允许插件与启动器之间进行双向通信。
|
||||
🐍 支持从 TypeScript React 中运行 Python 函数。
|
||||
🌐 允许插件发起完全绕过 CORS 的 fetch 请求。
|
||||
|
||||
### 🤔 常见问题
|
||||
|
||||
- Syncthing 可能会占用 Steam Deck 上的 8080 端口,而 Decky Loader 需要该端口才能运行。如果您将 Syncthing 作为服务使用,请将其端口更改为其他端口。
|
||||
- 建议将 Syncthing 的端口改为 8384。
|
||||
- 如果您使用的任何软件占用了 1337 或 8080 端口,请将其端口更改为其他端口或卸载该软件。
|
||||
- 有时 Decky 会在 SteamOS 更新后消失。只需重新运行安装程序并再次安装稳定版即可轻松解决。如果这不起作用,请尝试安装预发布版。如果还是不行,请[查看现有问题](https://github.com/SteamDeckHomebrew/decky-loader/issues),如果没有相关问题,您可以[提交一个新问题](https://github.com/SteamDeckHomebrew/decky-loader/issues/new?assignees=&labels=bug&template=bug_report.yml&title=%5BBUG%5D+%3Ctitle%3E)。
|
||||
|
||||
## 💾 安装
|
||||
|
||||
- 安装过程无需设置管理员/sudo 密码。
|
||||
|
||||
1. 如果可能,请准备鼠标和键盘。
|
||||
- 键盘和鼠标可以通过 USB-C 或蓝牙连接到 Steam Deck。
|
||||
- iOS 和 Android 上有许多蓝牙键盘和鼠标应用可用。(Steam Deck 上预安装了 KDE Connect)
|
||||
- Steam Link 应用可在 [Windows](https://media.steampowered.com/steamlink/windows/latest/SteamLink.zip)、[macOS](https://apps.apple.com/us/app/steam-link/id1246969117) 和 [Linux](https://flathub.org/apps/details/com.valvesoftware.SteamLink) 上使用。它可以很好地替代远程桌面。
|
||||
- 如果您没有其他选择,可以使用右侧触控板作为鼠标,并按 <img src="./docs/images/light/steam.svg#gh-dark-mode-only" height=16><img src="./docs/images/dark/steam.svg#gh-light-mode-only" height=16>+<img src="./docs/images/light/x.svg#gh-dark-mode-only" height=16><img src="./docs/images/dark/x.svg#gh-light-mode-only" height=16> 打开屏幕键盘。
|
||||
1. 按下 <img src="./docs/images/light/steam.svg#gh-dark-mode-only" height=16><img src="./docs/images/dark/steam.svg#gh-light-mode-only" height=16> 按钮并打开电源菜单。
|
||||
1. 选择"切换到桌面模式"。
|
||||
1. 在您选择的浏览器中访问此 GitHub 页面。
|
||||
1. 下载[安装程序文件](https://github.com/SteamDeckHomebrew/decky-installer/releases/latest/download/decky_installer.desktop)。(如果使用 Firefox,文件将命名为 `decky_installer.desktop.download`,请在运行前将其重命名为 `decky_installer.desktop`)
|
||||
1. 将文件拖到桌面上,然后双击运行。
|
||||
1. 输入您的管理员密码或允许 Decky 临时将您的管理员密码设置为 `Decky!`(安装程序完成后将删除此密码)。
|
||||
1. 选择您要安装的 Decky Loader 版本。
|
||||
- **最新正式版**
|
||||
面向大多数用户。这是 Decky Loader 的最新稳定版本。
|
||||
- **最新预发布版**
|
||||
面向插件开发者。预发布版可能尚未完全稳定,但包含最新更改。有关插件开发的更多信息,请参阅[维基页面](https://wiki.deckbrew.xyz/en/loader-dev/development)。
|
||||
1. 打开桌面上的"返回游戏模式"快捷方式。
|
||||
|
||||
- 对于可以使用 Konsole 的用户,还有一种快速安装方式。运行 `curl -L https://github.com/SteamDeckHomebrew/decky-installer/releases/latest/download/install_release.sh | sh` 并在提示时输入密码。
|
||||
|
||||
### 👋 卸载
|
||||
|
||||
很抱歉看到您离开!如果您因为遇到问题而考虑卸载,请考虑[提交问题](https://github.com/SteamDeckHomebrew/decky-loader/issues)或[加入我们的 Discord](https://deckbrew.xyz/discord),以便我们帮助您和其他用户。
|
||||
|
||||
1. 按下 <img src="./docs/images/light/steam.svg#gh-dark-mode-only" height=16><img src="./docs/images/dark/steam.svg#gh-light-mode-only" height=16> 按钮并打开电源菜单。
|
||||
1. 选择"切换到桌面模式"。
|
||||
1. 再次运行安装程序文件,然后选择 `uninstall decky loader`。
|
||||
|
||||
- 对于可以使用 Konsole 的用户,还有一种快速卸载方式。运行 `curl -L https://github.com/SteamDeckHomebrew/decky-installer/releases/latest/download/uninstall.sh | sh` 并在提示时输入密码。
|
||||
|
||||
## 🚀 入门指南
|
||||
|
||||
现在您已经安装了 Decky Loader,可以开始使用插件了。每个插件由不同的开发者维护,具有各自的用途,但大多数遵循以下通用结构。
|
||||
|
||||
### 📦 插件
|
||||
|
||||
1. 按下 <img src="./docs/images/light/qam.svg#gh-dark-mode-only" height=16><img src="./docs/images/dark/qam.svg#gh-light-mode-only" height=16> 按钮并导航到 <img src="./docs/images/light/plug.svg#gh-dark-mode-only" height=16><img src="./docs/images/dark/plug.svg#gh-light-mode-only" height=16> 图标。这是 Decky 菜单,用于与插件和启动器本身交互。
|
||||
1. 选择 <img src="./docs/images/light/store.svg#gh-dark-mode-only" height=16><img src="./docs/images/dark/store.svg#gh-light-mode-only" height=16> 图标打开插件浏览器。在这里您可以查找和安装插件。
|
||||
- 您也可以在设置菜单中通过 URL 安装。我们不建议安装来自不可信来源的插件。
|
||||
1. 要安装插件,请在您想要的插件上选择"安装"按钮。您也可以从下拉菜单中选择一个版本,但不建议这样做。
|
||||
1. 要更新、卸载和重新加载插件,请导航到 Decky 菜单并选择 <img src="./docs/images/light/gear.svg#gh-dark-mode-only" height=16><img src="./docs/images/dark/gear.svg#gh-light-mode-only" height=16> 图标。
|
||||
- 请注意,卸载插件只会移除其插件文件,而不会删除它可能创建的任何其他文件。
|
||||
|
||||
### 🛠️ 插件开发
|
||||
|
||||
目前还没有完整的插件开发文档。不过,一个好的起点是[插件模板仓库](https://github.com/SteamDeckHomebrew/decky-plugin-template)。如果您有任何问题,请考虑[加入我们的 Discord](https://deckbrew.xyz/discord)。
|
||||
|
||||
### 🤝 贡献
|
||||
|
||||
有关安装 Decky Loader 开发版本的更多信息,请参阅[有关开发的维基页面](https://wiki.deckbrew.xyz/en/loader-dev/development)。您还可以通过观看[此 YouTube 教程](https://youtu.be/1IAbZte8e7E?t=112)在 Windows 或 Linux 计算机上安装 Steam Deck UI 进行测试。
|
||||
|
||||
1. 在开始您的 PR 之前,使用最新的 main 分支提交克隆仓库。
|
||||
1. 在您的仓库克隆中,运行以下命令。
|
||||
```bash
|
||||
cd frontend
|
||||
pnpm i # 注意:您可能需要使用 pnpm approve-builds 批准 esbuild 的构建脚本
|
||||
pnpm run build
|
||||
```
|
||||
1. 如果您正在修改 UI,则需要在部署更改到 Steam Deck 之前运行这些命令。
|
||||
1. 使用 VS Code 任务或 `deck.sh` 脚本将您的更改部署到 Steam Deck 以进行测试。
|
||||
1. 您将使用 Python 脚本版本测试您的更改。每次都需要构建、部署和重新加载。
|
||||
|
||||
⚠️ 如果您因库过时而收到构建错误,请在仓库内运行此命令。
|
||||
|
||||
```bash
|
||||
pnpm update @decky/ui --latest
|
||||
```
|
||||
|
||||
源代码管理和插件部署留给克隆仓库的各自贡献者处理,以保持依赖项为最新版本。
|
||||
|
||||
## 📜 鸣谢
|
||||
|
||||
插件加载器概念的最初想法基于 [marios8543 的 Steam Deck UI Inject 项目](https://github.com/marios8543/steamdeck-ui-inject)的工作。
|
||||
@@ -52,7 +52,9 @@
|
||||
"MultiplePluginsInstallModal": {
|
||||
"confirm": "¿Estás seguro de que quieres hacer las siguientes modificaciones?",
|
||||
"description": {
|
||||
"downgrade": "Downgrade {{name}} a la {{version}}",
|
||||
"install": "Instalar {{name}} {{version}}",
|
||||
"overwrite": "Sobrescribir {{name}} con {{version}}",
|
||||
"reinstall": "Reinstalar {{name}} {{version}}",
|
||||
"update": "Actualizar {{name}} a {{version}}"
|
||||
},
|
||||
@@ -61,12 +63,18 @@
|
||||
"loading": "Trabajando"
|
||||
},
|
||||
"title": {
|
||||
"downgrade_many": "Downgrade {{count}} plugins",
|
||||
"downgrade_one": "Downgrade 1 plugin",
|
||||
"downgrade_other": "Downgrade {{count}} plugins",
|
||||
"install_many": "Instalar {{count}} plugins",
|
||||
"install_one": "Instalar 1 plugin",
|
||||
"install_other": "Instalar {{count}} plugins",
|
||||
"mixed_many": "Modificar {{count}} plugins",
|
||||
"mixed_one": "Modificar 1 plugin",
|
||||
"mixed_other": "Modificar {{count}} plugins",
|
||||
"overwrite_many": "Sobrescribir {{count}} plugins",
|
||||
"overwrite_one": "Sobrescribir 1 plugin",
|
||||
"overwrite_other": "Sobrescribr {{count}} plugins",
|
||||
"reinstall_many": "Reinstalar {{count}} plugins",
|
||||
"reinstall_one": "Reinstalar 1 plugin",
|
||||
"reinstall_other": "Reinstalar {{count}} plugins",
|
||||
@@ -76,12 +84,22 @@
|
||||
}
|
||||
},
|
||||
"PluginCard": {
|
||||
"plugin_downgrade": "Downgrade",
|
||||
"plugin_full_access": "Este plugin tiene acceso completo a tu Steam Deck.",
|
||||
"plugin_install": "Instalar",
|
||||
"plugin_no_desc": "No se ha proporcionado una descripción.",
|
||||
"plugin_overwrite": "Sobrescribir",
|
||||
"plugin_reinstall": "Reinstalar",
|
||||
"plugin_update": "Actualizar",
|
||||
"plugin_version_label": "Versión de Plugin"
|
||||
},
|
||||
"PluginInstallModal": {
|
||||
"downgrade": {
|
||||
"button_idle": "Downgrade",
|
||||
"button_processing": "Downgrading",
|
||||
"desc": "¿Estas seguro de que quieres realizar el downgrade de {{artifact}} a la versión {{version}}?",
|
||||
"title": "Downgrade {{artifact}}"
|
||||
},
|
||||
"install": {
|
||||
"button_idle": "Instalar",
|
||||
"button_processing": "Instalando",
|
||||
@@ -89,6 +107,13 @@
|
||||
"title": "Instalar {{artifact}}"
|
||||
},
|
||||
"no_hash": "Este plugin no tiene un hash, lo estás instalando bajo tu propia responsabilidad.",
|
||||
"not_installed": "(no instalado)",
|
||||
"overwrite": {
|
||||
"button_idle": "Sobrescribir",
|
||||
"button_processing": "Sobrescribiendo",
|
||||
"desc": "¿Estas seguro de que quieres sobrescribir {{artifact}} con la versión {{version}}?",
|
||||
"title": "Sobrescribir {{artifact}}"
|
||||
},
|
||||
"reinstall": {
|
||||
"button_idle": "Reinstalar",
|
||||
"button_processing": "Reinstalando",
|
||||
@@ -98,7 +123,7 @@
|
||||
"update": {
|
||||
"button_idle": "Actualizar",
|
||||
"button_processing": "Actualizando",
|
||||
"desc": "¿Estás seguro de que quieres actualizar {{artifact}} {{version}}?",
|
||||
"desc": "¿Estás seguro de que quieres actualizar {{artifact}} a la {{version}}?",
|
||||
"title": "Actualizar {{artifact}}"
|
||||
}
|
||||
},
|
||||
@@ -206,6 +231,7 @@
|
||||
},
|
||||
"Store": {
|
||||
"download_progress_info": {
|
||||
"download_remote": "Descargando los binarios externos",
|
||||
"download_zip": "Descargando plugin",
|
||||
"increment_count": "Incrementando el contador de descargas",
|
||||
"installing_plugin": "Instalando plugin",
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
"MultiplePluginsInstallModal": {
|
||||
"confirm": "Sei sicuro di voler effettuare le modifiche seguenti?",
|
||||
"description": {
|
||||
"downgrade": "Downgrada {{name}} a versione {{version}}",
|
||||
"downgrade": "Declassa {{name}} a versione {{version}}",
|
||||
"install": "Installa {{name}} {{version}}",
|
||||
"overwrite": "Sovrascrive {{name}} con {{version}}",
|
||||
"reinstall": "Reinstalla {{name}} {{version}}",
|
||||
@@ -63,9 +63,9 @@
|
||||
"loading": "Elaboro"
|
||||
},
|
||||
"title": {
|
||||
"downgrade_many": "Downgrada {{count}} plugins",
|
||||
"downgrade_one": "Downgrada un plugin",
|
||||
"downgrade_other": "Downgrada {{count}} plugins",
|
||||
"downgrade_many": "Declassa {{count}} plugins",
|
||||
"downgrade_one": "Declassa un plugin",
|
||||
"downgrade_other": "Declassa {{count}} plugins",
|
||||
"install_many": "Installa {{count}} plugins",
|
||||
"install_one": "Installa un plugin",
|
||||
"install_other": "Installa {{count}} plugins",
|
||||
@@ -84,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
"PluginCard": {
|
||||
"plugin_downgrade": "Downgrada",
|
||||
"plugin_downgrade": "Declassa",
|
||||
"plugin_full_access": "Questo plugin ha accesso completo al tuo Steam Deck.",
|
||||
"plugin_install": "Installa",
|
||||
"plugin_no_desc": "Nessuna descrizione fornita.",
|
||||
@@ -95,10 +95,10 @@
|
||||
},
|
||||
"PluginInstallModal": {
|
||||
"downgrade": {
|
||||
"button_idle": "Downgrada",
|
||||
"button_processing": "Downgradando",
|
||||
"desc": "Sei sicuro di voler downgradare {{artifact}} alla versione {{version}}?",
|
||||
"title": "Downgrada {{artifact}}"
|
||||
"button_idle": "Declassa",
|
||||
"button_processing": "Declassando",
|
||||
"desc": "Sei sicuro di voler declassare {{artifact}} alla versione {{version}}?",
|
||||
"title": "Declassa {{artifact}}"
|
||||
},
|
||||
"install": {
|
||||
"button_idle": "Installa",
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
"download_progress_info": {
|
||||
"download_remote": "外部バイナリのダウンロード",
|
||||
"download_zip": "プラグインのダウンロード中",
|
||||
"increment_count": "ダウンロード数の増加",
|
||||
"increment_count": "ダウンロード進行中",
|
||||
"installing_plugin": "プラグインのインストール中",
|
||||
"open_zip": "zipファイルを展開中",
|
||||
"parse_zip": "zipファイルの解析中",
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
{
|
||||
"BranchSelect": {
|
||||
"update_channel": {
|
||||
"label": "Candalul de Actualizare",
|
||||
"prerelease": "Pre-lansare",
|
||||
"stable": "Stabil",
|
||||
"testing": "Testare"
|
||||
}
|
||||
},
|
||||
"Developer": {
|
||||
"5secreload": "Reîncărcare în 5 secunde",
|
||||
"disabling": "Dezactivare React DevTools",
|
||||
"enabling": "Activare React DevTools"
|
||||
},
|
||||
"DropdownMultiselect": {
|
||||
"button": {
|
||||
"back": "Înapoi"
|
||||
}
|
||||
},
|
||||
"FilePickerError": {
|
||||
"errors": {
|
||||
"file_not_found": "Calea specificată nu este validă. Vă rugăm să o verificați și să o reintroduceți corect.",
|
||||
"perm_denied": "Nu aveți acces la fișierul specificat. Te rugăm să verifici dacă utilizatorul tău (deck pe Steam Deck) are permisiunea corespunzătoare de a accesa folderul/fișierul specific.",
|
||||
"unknown": "A apărut o eroare necunoscută. Eroarea brută este: {{raw_error}}"
|
||||
}
|
||||
},
|
||||
"FilePickerIndex": {
|
||||
"file": {
|
||||
"select": "Selectați acest fișier"
|
||||
},
|
||||
"files": {
|
||||
"all_files": "Toate Fișierele",
|
||||
"file_type": "Tip de Fișier",
|
||||
"show_hidden": "Afișați Fișierele Ascunse"
|
||||
},
|
||||
"filter": {
|
||||
"created_asce": "Create (Cele mai vechi)",
|
||||
"created_desc": "Create (Cele mai noi)",
|
||||
"modified_asce": "Modificate (Cele mai vechi)",
|
||||
"modified_desc": "Modificate (Cele mai noi)",
|
||||
"name_asce": "Z-A",
|
||||
"name_desc": "A-Z",
|
||||
"size_asce": "Dimensiune (Cea mai mică)",
|
||||
"size_desc": "Dimensiune (Cea mai mare)"
|
||||
},
|
||||
"folder": {
|
||||
"label": "Fișier",
|
||||
"select": "Folosiți acest fișier",
|
||||
"show_more": "Afișați mai multe fișiere"
|
||||
}
|
||||
},
|
||||
"MultiplePluginsInstallModal": {
|
||||
"confirm": "Sigur doriți să faceți următoarele modificări?",
|
||||
"description": {
|
||||
"downgrade": "Retrogradare {{name}} la {{version}}",
|
||||
"install": "Instalați {{name}} {{version}}",
|
||||
"overwrite": "Suprascrie {{name}} cu {{version}}",
|
||||
"reinstall": "Reinstalați {{name}} {{version}}",
|
||||
"update": "Actualizați {{name}} la {{version}}"
|
||||
},
|
||||
"ok_button": {
|
||||
"idle": "Confirmați",
|
||||
"loading": "Încărcare"
|
||||
},
|
||||
"title": {
|
||||
"downgrade_few": "Retrogradează {{count}} pluginuri",
|
||||
"downgrade_one": "Retrogradează un plugin",
|
||||
"downgrade_other": "Retrogradează {{count}} pluginuri",
|
||||
"install_few": "Instalați {{count}} pluginuri",
|
||||
"install_one": "Instalați un plugin",
|
||||
"install_other": "Instalați {{count}} pluginuri",
|
||||
"mixed_few": "Modificați {{count}} pluginuri",
|
||||
"mixed_one": "Modificați un plugin",
|
||||
"mixed_other": "Modificați {{count}} pluginuri",
|
||||
"overwrite_few": "Suprascrie {{count}} pluginuri",
|
||||
"overwrite_one": "Suprascrie un plugin",
|
||||
"overwrite_other": "Suprascrie {{count}} pluginuri",
|
||||
"reinstall_few": "Reinstalați {{count}} pluginuri",
|
||||
"reinstall_one": "Reinstalați un plugin",
|
||||
"reinstall_other": "Reinstalați {{count}} pluginuri",
|
||||
"update_few": "Actualizați {{count}} pluginuri",
|
||||
"update_one": "Actualizați un plugin",
|
||||
"update_other": "Actualizați {{count}} pluginuri"
|
||||
}
|
||||
},
|
||||
"PluginCard": {
|
||||
"plugin_downgrade": "Retrogradare",
|
||||
"plugin_full_access": "Acest plugin are acces complet la Steam Deck-ul tău.",
|
||||
"plugin_install": "Instalați",
|
||||
"plugin_no_desc": "Nici-o descriere pusă.",
|
||||
"plugin_overwrite": "Suprascriere",
|
||||
"plugin_reinstall": "Reinstalați",
|
||||
"plugin_update": "Actualizare",
|
||||
"plugin_version_label": "Versiunea Plugin"
|
||||
},
|
||||
"PluginInstallModal": {
|
||||
"downgrade": {
|
||||
"button_idle": "Retrogradare",
|
||||
"button_processing": "Retrogradare",
|
||||
"desc": "Sunteți sigur că vreți să retrogradați {{artifact}} la versiunea {{version}}?",
|
||||
"title": "Retrogradare {{artifact}}"
|
||||
},
|
||||
"install": {
|
||||
"button_idle": "Instalați",
|
||||
"button_processing": "Instalare",
|
||||
"desc": "Sigur vreți să instalați {{artifact}} {{version}}?",
|
||||
"title": "Instalați {{artifact}}"
|
||||
},
|
||||
"no_hash": "Acest plugin nu are hash, îl instalați pe propriul risc.",
|
||||
"not_installed": "(neinstalat)",
|
||||
"overwrite": {
|
||||
"button_idle": "Suprascriere",
|
||||
"button_processing": "Suprascriere",
|
||||
"desc": "Sigur vreți să suprascrii {{artifact}} cu versiunea {{version}}?",
|
||||
"title": "Suprascrie {{artifact}}"
|
||||
},
|
||||
"reinstall": {
|
||||
"button_idle": "Reinstalare",
|
||||
"button_processing": "Reinstalare",
|
||||
"desc": "Sigur vreți să reinstalați {{artifact}} {{version}}?",
|
||||
"title": "Reinstalare {{artifact}}"
|
||||
},
|
||||
"update": {
|
||||
"button_idle": "Actualizare",
|
||||
"button_processing": "Se Actualizează",
|
||||
"desc": "Sigur vreți să actualizați {{artifact}} la versiunea {{version}}?",
|
||||
"title": "Actualizare {{artifact}}"
|
||||
}
|
||||
},
|
||||
"PluginListIndex": {
|
||||
"freeze": "Pauză actualizări",
|
||||
"hide": "Acces rapid: Ascunde",
|
||||
"no_plugin": "Niciun plugin instalat!",
|
||||
"plugin_actions": "Acțiuni plugin",
|
||||
"reinstall": "Reinstalare",
|
||||
"reload": "Reîncărcare",
|
||||
"show": "Acces rapid: Afișare",
|
||||
"unfreeze": "Permiteți actualizări",
|
||||
"uninstall": "Dezinstalare",
|
||||
"update_all_few": "Actualizați {{count}} pluginuri",
|
||||
"update_all_one": "Actualizare un plugin",
|
||||
"update_all_other": "Actualizați {{count}} pluginuri",
|
||||
"update_to": "Actualizare pentru {{name}}"
|
||||
},
|
||||
"PluginListLabel": {
|
||||
"hidden": "Ascuns din meniul de acces rapid"
|
||||
},
|
||||
"PluginLoader": {
|
||||
"decky_title": "Decky",
|
||||
"decky_update_available": "Actualizare disponibilă pentru {{tag_name}}!",
|
||||
"error": "Eroare",
|
||||
"plugin_error_uninstall": "Încărcarea pluginului {{name}} a cauzat o excepție, așa cum se arată mai sus. Aceasta înseamnă de obicei că pluginul necesită o actualizare pentru noua versiune de SteamUI. Verificați dacă există o actualizare sau evaluați eliminarea acesteia în setările Decky, în secțiunea Plugin-uri.",
|
||||
"plugin_load_error": {
|
||||
"message": "Eroare la încărcarea pluginului {{name}}",
|
||||
"toast": "Eroare la încărcarea {{name}}"
|
||||
},
|
||||
"plugin_uninstall": {
|
||||
"button": "Dezinstalare",
|
||||
"desc": "Sigur vreți să dezinstalați {{name}}?",
|
||||
"title": "Dezinstalați {{name}}"
|
||||
},
|
||||
"plugin_update_few": "Actualizări disponibile pentru {{count}} plugin-uri!",
|
||||
"plugin_update_one": "Actualizare disponibilă pentru un plugin!",
|
||||
"plugin_update_other": "Actualizări disponibile pentru {{count}} plugin-uri!"
|
||||
},
|
||||
"PluginView": {
|
||||
"hidden_few": "{{count}} pluginuri sunt ascunse din această listă",
|
||||
"hidden_one": "Un plugin este ascuns din această listă",
|
||||
"hidden_other": "{{count}} pluginuri sunt ascunse din această listă"
|
||||
},
|
||||
"RemoteDebugging": {
|
||||
"remote_cef": {
|
||||
"desc": "Permiteți accesul neautentificat la debugger CEF oricui din rețeaua dumneavoastră",
|
||||
"label": "Permiteți Deugging CEF la distanță"
|
||||
}
|
||||
},
|
||||
"SettingsDeveloperIndex": {
|
||||
"cef_console": {
|
||||
"button": "Deschideți Consola",
|
||||
"desc": "Deschide consola CEF. Utilă doar în scopuri de debugging. Informațiile de aici sunt potențial periculoase și ar trebui utilizate doar dacă ești dezvoltator de plugin-uri sau dacă ești îndrumat aici de unul dintre ei.",
|
||||
"label": "Consola CEF"
|
||||
},
|
||||
"header": "Alte",
|
||||
"react_devtools": {
|
||||
"desc": "Permite conectarea la un calculator care rulează React DevTools. Modificarea acestei setări va reîncărca Steam. Setați adresa IP înainte de activare.",
|
||||
"ip_label": "IP",
|
||||
"label": "Activați React DevTools"
|
||||
},
|
||||
"third_party_plugins": {
|
||||
"button_install": "Instalați",
|
||||
"button_zip": "Răsfoiți",
|
||||
"header": "Pluginuri terțe",
|
||||
"label_desc": "URL",
|
||||
"label_url": "Instalați pluginul de la URL",
|
||||
"label_zip": "Instalați pluginul din fișierul ZIP"
|
||||
},
|
||||
"valve_internal": {
|
||||
"desc1": "Activează meniul intern pentru dezvoltatori Valve.",
|
||||
"desc2": "Nu atingeți nimic din acest meniu decât dacă știți ce face.",
|
||||
"label": "Activare Valve Internă"
|
||||
}
|
||||
},
|
||||
"SettingsGeneralIndex": {
|
||||
"about": {
|
||||
"decky_version": "Versiunea Decky",
|
||||
"header": "Despre"
|
||||
},
|
||||
"beta": {
|
||||
"header": "Participarea la beta"
|
||||
},
|
||||
"developer_mode": {
|
||||
"label": "Mod dezvoltator"
|
||||
},
|
||||
"notifications": {
|
||||
"decky_updates_label": "Actualizare Decky disponibilă",
|
||||
"header": "Notificări",
|
||||
"plugin_updates_label": "Actualizări de pluginuri disponibile"
|
||||
},
|
||||
"other": {
|
||||
"header": "Alte"
|
||||
},
|
||||
"updates": {
|
||||
"header": "Actualizări"
|
||||
}
|
||||
},
|
||||
"SettingsIndex": {
|
||||
"developer_title": "Dezvoltator",
|
||||
"general_title": "General",
|
||||
"plugins_title": "Pluginuri",
|
||||
"testing_title": "Testare"
|
||||
},
|
||||
"Store": {
|
||||
"download_progress_info": {
|
||||
"download_remote": "Descărcarea oricăror binări externe",
|
||||
"download_zip": "Se descarcă pluginul",
|
||||
"increment_count": "Se mărește numărul de descărcări",
|
||||
"installing_plugin": "Se instalează plugin",
|
||||
"open_zip": "Deschiderea fișierului zip",
|
||||
"parse_zip": "Analizarea fișierului zip",
|
||||
"start": "Inițializare",
|
||||
"uninstalling_previous": "Se dezinstalează copia anterioară"
|
||||
},
|
||||
"store_contrib": {
|
||||
"desc": "Dacă doriți să contribuiți la Magazinul de Pluginuri Decky, verificați depozitul SteamDeckHomebrew/decky-plugin-template de pe GitHub. Informații despre dezvoltare și distribuție sunt disponibile în fișierul README.",
|
||||
"label": "Contribuţii"
|
||||
},
|
||||
"store_filter": {
|
||||
"label": "Filtru",
|
||||
"label_def": "Toate"
|
||||
},
|
||||
"store_search": {
|
||||
"label": "Căutare"
|
||||
},
|
||||
"store_sort": {
|
||||
"label": "Sortează",
|
||||
"label_def": "Ultima actualizare (cele mai noi)"
|
||||
},
|
||||
"store_source": {
|
||||
"desc": "Tot codul sursă al pluginului este disponibil în depozitul SteamDeckHomebrew/decky-plugin-database de pe GitHub.",
|
||||
"label": "Cod sursă"
|
||||
},
|
||||
"store_tabs": {
|
||||
"about": "Despre",
|
||||
"alph_asce": "Alfabetic (de la Z la A)",
|
||||
"alph_desc": "Alfabetic (de la A la Z)",
|
||||
"date_asce": "Cele mai vechi primele",
|
||||
"date_desc": "Cele mai noi primele",
|
||||
"downloads_asce": "Cele mai puțin descărcate primele",
|
||||
"downloads_desc": "Cele mai descărcate primele",
|
||||
"title": "Răsfoiți"
|
||||
},
|
||||
"store_testing_cta": "Vă rugăm să luați în considerare testarea la noi plugin-uri pentru a ajuta echipa Decky Loader!",
|
||||
"store_testing_warning": {
|
||||
"desc": "Puteți folosi acest canal de magazin pentru a testa versiuni de pluginuri de ultimă generație. Asigură-te că lași feedback pe GitHub, astfel încât pluginul să poată fi actualizat pentru toți utilizatorii.",
|
||||
"label": "Bun venit la Canalul Magazinului de Testare"
|
||||
}
|
||||
},
|
||||
"StoreSelect": {
|
||||
"custom_store": {
|
||||
"label": "Magazin personalizat",
|
||||
"url_label": "URL"
|
||||
},
|
||||
"store_channel": {
|
||||
"custom": "Personalizat",
|
||||
"default": "Standard",
|
||||
"label": "Canalul Magazinului",
|
||||
"testing": "Testare"
|
||||
}
|
||||
},
|
||||
"Testing": {
|
||||
"download": "Descărcare",
|
||||
"error": "Eroare la instalarea PR-ului",
|
||||
"header": "Următoarele versiuni de Decky Loader sunt construite pe baza unor solicitări de extragere (Pull Requests) deschise de la terți. Echipa Decky Loader nu a verificat funcționalitatea sau securitatea acestora și este posibil să fie învechite.",
|
||||
"loading": "Se încarcă cererile de extragere deschise...",
|
||||
"start_download_toast": "Se descarcă PR #{{id}}"
|
||||
},
|
||||
"TitleView": {
|
||||
"decky_store_desc": "Deschide Magazinul Decky",
|
||||
"settings_desc": "Deschide Setările Decky"
|
||||
},
|
||||
"Updater": {
|
||||
"decky_updates": "Actualizări Decky",
|
||||
"no_patch_notes_desc": "Nu există note de patch pentru această versiune",
|
||||
"patch_notes_desc": "Note de patch",
|
||||
"updates": {
|
||||
"check_button": "Verificare pentru actualizări",
|
||||
"checking": "Verificare",
|
||||
"cur_version": "Versiunea curentă: {{ver}}",
|
||||
"install_button": "Instalați actualizarea",
|
||||
"label": "Actualizări",
|
||||
"lat_version": "La zi cu actualizările: rulează {{ver}}",
|
||||
"reloading": "Reîncărcare",
|
||||
"updating": "Actualizare"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,15 +63,18 @@
|
||||
"loading": "В процессе"
|
||||
},
|
||||
"title": {
|
||||
"downgrade_few": "Откатить {{count}} плагинов",
|
||||
"downgrade_few": "Откатить {{count}} плагина",
|
||||
"downgrade_many": "Откатить {{count}} плагинов",
|
||||
"downgrade_one": "Откатить 1 плагин",
|
||||
"downgrade_one": "Откатить {{count}} плагин",
|
||||
"install_few": "Установить {{count}} плагинов",
|
||||
"install_many": "Установить {{count}} плагинов",
|
||||
"install_one": "Установить {{count}} плагин",
|
||||
"mixed_few": "Изменить {{count}} плагинов",
|
||||
"mixed_many": "Изменить {{count}} плагинов",
|
||||
"mixed_one": "Изменить {{count}} плагин",
|
||||
"overwrite_few": "Перезаписать {{count}} плагина",
|
||||
"overwrite_many": "Перезаписать {{count}} плагинов",
|
||||
"overwrite_one": "Перезаписать {{count}} плагин",
|
||||
"reinstall_few": "Переустановить {{count}} плагинов",
|
||||
"reinstall_many": "Переустановить {{count}} плагинов",
|
||||
"reinstall_one": "Переустановить {{count}} плагин",
|
||||
@@ -93,6 +96,7 @@
|
||||
"PluginInstallModal": {
|
||||
"downgrade": {
|
||||
"button_idle": "Откат",
|
||||
"button_processing": "Откатывание",
|
||||
"desc": "Вы уверенны, что хотите откатить {{artifact}} до версии {{version}}?",
|
||||
"title": "Откатить {{artifact}}"
|
||||
},
|
||||
@@ -103,6 +107,13 @@
|
||||
"title": "Установить {{artifact}}"
|
||||
},
|
||||
"no_hash": "У данного плагина отсутствует хэш, устанавливайте на свой страх и риск.",
|
||||
"not_installed": "(не установлено)",
|
||||
"overwrite": {
|
||||
"button_idle": "Перезаписать",
|
||||
"button_processing": "Перезаписывание",
|
||||
"desc": "Вы уверены, что хотите перезаписать {{artifact}} версией {{version}}?",
|
||||
"title": "Перезаписать {{artifact}}"
|
||||
},
|
||||
"reinstall": {
|
||||
"button_idle": "Переустановить",
|
||||
"button_processing": "Переустановка",
|
||||
@@ -220,6 +231,7 @@
|
||||
},
|
||||
"Store": {
|
||||
"download_progress_info": {
|
||||
"download_remote": "Загрузка внешних бинарных файлов",
|
||||
"download_zip": "Скачивание плагина",
|
||||
"increment_count": "Увеличение количества загрузок",
|
||||
"installing_plugin": "Установка плагина",
|
||||
|
||||
@@ -12,15 +12,49 @@
|
||||
"disabling": "Вимкнення React DevTools",
|
||||
"enabling": "Увімкнення React DevTools"
|
||||
},
|
||||
"DropdownMultiselect": {
|
||||
"button": {
|
||||
"back": "Назад"
|
||||
}
|
||||
},
|
||||
"FilePickerError": {
|
||||
"errors": {
|
||||
"file_not_found": "Вказаний шлях недійсний. Будь ласка, перевірте його та введіть правильно.",
|
||||
"perm_denied": "У вас немає доступу до вказаного каталогу. Будь ласка, перевірте, чи має ваш користувач (deck на Steam Deck) відповідні права доступу до зазначеної папки/файлу.",
|
||||
"unknown": "Сталася невідома помилка. Деталі помилки: {{raw_error}}"
|
||||
}
|
||||
},
|
||||
"FilePickerIndex": {
|
||||
"file": {
|
||||
"select": "Виберіть цей файл"
|
||||
},
|
||||
"files": {
|
||||
"all_files": "Усі файли",
|
||||
"file_type": "Тип файлу",
|
||||
"show_hidden": "Показати приховані файли"
|
||||
},
|
||||
"filter": {
|
||||
"created_asce": "Створено (спочатку найстаріші)",
|
||||
"created_desc": "Створено (спочатку найновіші)",
|
||||
"modified_asce": "Змінено (спочатку найстаріші)",
|
||||
"modified_desc": "Змінено (спочатку найновіші)",
|
||||
"name_asce": "Я-А",
|
||||
"name_desc": "А-Я",
|
||||
"size_asce": "Розмір (спочатку найменші)",
|
||||
"size_desc": "Розмір (спочатку найбільші)"
|
||||
},
|
||||
"folder": {
|
||||
"select": "Використовувати цю папку"
|
||||
"label": "Папка",
|
||||
"select": "Використовувати цю папку",
|
||||
"show_more": "Показати більше файлів"
|
||||
}
|
||||
},
|
||||
"MultiplePluginsInstallModal": {
|
||||
"confirm": "Ви впевнені, що хочете застосувати такі модифікації?",
|
||||
"description": {
|
||||
"downgrade": "Понизити {{name}} до версії {{version}}",
|
||||
"install": "Встановити {{name}} {{version}}",
|
||||
"overwrite": "Перезаписати {{name}} версією {{version}}",
|
||||
"reinstall": "Перевстановити {{name}} {{version}}",
|
||||
"update": "Оновити {{name}} до {{version}}"
|
||||
},
|
||||
@@ -29,27 +63,43 @@
|
||||
"loading": "Опрацювання"
|
||||
},
|
||||
"title": {
|
||||
"install_few": "Встановити {{count}} плагінів",
|
||||
"downgrade_few": "Понизити {{count}} плагіни",
|
||||
"downgrade_many": "Понизити {{count}} плагінів",
|
||||
"downgrade_one": "Понизити {{count}} плагін",
|
||||
"install_few": "Встановити {{count}} плагіни",
|
||||
"install_many": "Встановити {{count}} плагінів",
|
||||
"install_one": "Встановити 1 плагін",
|
||||
"mixed_few": "Модифікувати {{count}} плагінів",
|
||||
"mixed_many": "",
|
||||
"mixed_one": "Модифікувати 1 плагін",
|
||||
"reinstall_few": "Перевстановити {{count}} плагінів",
|
||||
"install_one": "Встановити {{count}} плагін",
|
||||
"mixed_few": "Модифікувати {{count}} плагіни",
|
||||
"mixed_many": "Модифікувати {{count}} плагінів",
|
||||
"mixed_one": "Модифікувати {{count}} плагін",
|
||||
"overwrite_few": "Перезаписати {{count}} плагіни",
|
||||
"overwrite_many": "Перезаписати {{count}} плагінів",
|
||||
"overwrite_one": "Перезаписати {{count}} плагін",
|
||||
"reinstall_few": "Перевстановити {{count}} плагіни",
|
||||
"reinstall_many": "Перевстановити {{count}} плагінів",
|
||||
"reinstall_one": "Перевстановити 1 плагін",
|
||||
"update_few": "Оновити {{count}} плагінів",
|
||||
"reinstall_one": "Перевстановити {{count}} плагін",
|
||||
"update_few": "Оновити {{count}} плагіни",
|
||||
"update_many": "Оновити {{count}} плагінів",
|
||||
"update_one": "Оновити 1 плагін"
|
||||
"update_one": "Оновити {{count}} плагін"
|
||||
}
|
||||
},
|
||||
"PluginCard": {
|
||||
"plugin_downgrade": "Понизити",
|
||||
"plugin_full_access": "Цей плагін має повний доступ до вашого Steam Deck.",
|
||||
"plugin_install": "Встановити",
|
||||
"plugin_no_desc": "Опис не надано.",
|
||||
"plugin_overwrite": "Перезаписати",
|
||||
"plugin_reinstall": "Перевстановити",
|
||||
"plugin_update": "Оновити",
|
||||
"plugin_version_label": "Версія плагіна"
|
||||
},
|
||||
"PluginInstallModal": {
|
||||
"downgrade": {
|
||||
"button_idle": "Понизити",
|
||||
"button_processing": "Пониження",
|
||||
"desc": "Ви впевнені, що хочете понизити {{artifact}} до версії {{version}}?",
|
||||
"title": "Понизити {{artifact}}"
|
||||
},
|
||||
"install": {
|
||||
"button_idle": "Встановити",
|
||||
"button_processing": "Встановлення",
|
||||
@@ -57,6 +107,13 @@
|
||||
"title": "Встановити {{artifact}}"
|
||||
},
|
||||
"no_hash": "Цей плагін не має хешу, ви встановлюєте його на власний ризик.",
|
||||
"not_installed": "(не встановлено)",
|
||||
"overwrite": {
|
||||
"button_idle": "Перезаписати",
|
||||
"button_processing": "Перезаписування",
|
||||
"desc": "Ви впевнені, що хочете перезаписати {{artifact}} версією {{version}}?",
|
||||
"title": "Перезаписати {{artifact}}"
|
||||
},
|
||||
"reinstall": {
|
||||
"button_idle": "Перевстановити",
|
||||
"button_processing": "Перевстановлення",
|
||||
@@ -66,21 +123,23 @@
|
||||
"update": {
|
||||
"button_idle": "Оновити",
|
||||
"button_processing": "Оновлення",
|
||||
"desc": "Ви впевнені, що хочете оновити {{artifact}} {{version}}?",
|
||||
"desc": "Ви впевнені, що хочете оновити {{artifact}} до версії {{version}}?",
|
||||
"title": "Оновити {{artifact}}"
|
||||
}
|
||||
},
|
||||
"PluginListIndex": {
|
||||
"freeze": "Заморозити оновлення",
|
||||
"hide": "Швидкий доступ: Приховати",
|
||||
"no_plugin": "Плагінів не встановлено!",
|
||||
"plugin_actions": "Дії плагінів",
|
||||
"reinstall": "Перевстановити",
|
||||
"reload": "Перезавантажити",
|
||||
"show": "Швидкий доступ: Показати",
|
||||
"unfreeze": "Дозволити оновлення",
|
||||
"uninstall": "Видалити",
|
||||
"update_all_few": "Оновити {{count}} плагінів",
|
||||
"update_all_few": "Оновити {{count}} плагіни",
|
||||
"update_all_many": "Оновити {{count}} плагінів",
|
||||
"update_all_one": "Оновити 1 плагін",
|
||||
"update_all_one": "Оновити {{count}} плагін",
|
||||
"update_to": "Оновити {{name}}"
|
||||
},
|
||||
"PluginListLabel": {
|
||||
@@ -100,9 +159,9 @@
|
||||
"desc": "Ви впевнені, що хочете видалити {{name}}?",
|
||||
"title": "Видалити {{name}}"
|
||||
},
|
||||
"plugin_update_few": "Доступне оновлення для {{count}} плагінів!",
|
||||
"plugin_update_few": "Доступне оновлення для {{count}} плагіни!",
|
||||
"plugin_update_many": "Доступне оновлення для {{count}} плагінів!",
|
||||
"plugin_update_one": "Доступне оновлення для 1 плагіна!"
|
||||
"plugin_update_one": "Доступне оновлення для {{count}} плагіна!"
|
||||
},
|
||||
"PluginView": {
|
||||
"hidden_few": "{{count}} плагінів приховано з цього списку",
|
||||
@@ -152,6 +211,11 @@
|
||||
"developer_mode": {
|
||||
"label": "Розробницький режим"
|
||||
},
|
||||
"notifications": {
|
||||
"decky_updates_label": "Доступне оновлення Decky",
|
||||
"header": "Сповіщення",
|
||||
"plugin_updates_label": "Доступні оновлення плагінів"
|
||||
},
|
||||
"other": {
|
||||
"header": "Інше"
|
||||
},
|
||||
@@ -162,9 +226,20 @@
|
||||
"SettingsIndex": {
|
||||
"developer_title": "Розробник",
|
||||
"general_title": "Загальне",
|
||||
"plugins_title": "Плагіни"
|
||||
"plugins_title": "Плагіни",
|
||||
"testing_title": "Тестування"
|
||||
},
|
||||
"Store": {
|
||||
"download_progress_info": {
|
||||
"download_remote": "Завантаження будь-яких зовнішніх бінарних файлів",
|
||||
"download_zip": "Завантаження плагіна",
|
||||
"increment_count": "Збільшення лічильника завантажень",
|
||||
"installing_plugin": "Встановлення плагіна",
|
||||
"open_zip": "Відкриття ZIP-файлу",
|
||||
"parse_zip": "Обробка ZIP-файлу",
|
||||
"start": "Ініціалізація",
|
||||
"uninstalling_previous": "Видалення попередньої копії"
|
||||
},
|
||||
"store_contrib": {
|
||||
"desc": "Якщо ви бажаєте додати щось у Decky Plugin Store, завітайте у репозиторій SteamDeckHomebrew/decky-plugin-template на GitHub. Інформація про розробку та поширення доступна у README.",
|
||||
"label": "Зробити внесок"
|
||||
@@ -188,9 +263,17 @@
|
||||
"about": "Інформація",
|
||||
"alph_asce": "За алфавітом (Z до A)",
|
||||
"alph_desc": "За алфавітом (A до Z)",
|
||||
"date_asce": "Спочатку найстаріші",
|
||||
"date_desc": "Спочатку найновіші",
|
||||
"downloads_asce": "Спочатку найменш завантажені",
|
||||
"downloads_desc": "Спочатку найчастіше завантажувані",
|
||||
"title": "Огляд"
|
||||
},
|
||||
"store_testing_cta": "Розгляньте можливість тестування нових плагінів, щоб допомогти команді Decky Loader!"
|
||||
"store_testing_cta": "Розгляньте можливість тестування нових плагінів, щоб допомогти команді Decky Loader!",
|
||||
"store_testing_warning": {
|
||||
"desc": "Ви можете використовувати цей канал магазину для тестування найновіших (експериментальних) версій плагінів. Обов’язково залишайте відгук на GitHub, щоб плагін можна було оновити для всіх користувачів.",
|
||||
"label": "Ласкаво просимо до каналу тестування магазину"
|
||||
}
|
||||
},
|
||||
"StoreSelect": {
|
||||
"custom_store": {
|
||||
@@ -204,6 +287,17 @@
|
||||
"testing": "Тестування"
|
||||
}
|
||||
},
|
||||
"Testing": {
|
||||
"download": "Завантажити",
|
||||
"error": "Помилка встановлення PR",
|
||||
"header": "Наведені нижче версії Decky Loader зібрані з відкритих сторонніх Pull Request. Команда Decky Loader не перевіряла їхню функціональність або безпеку, і вони можуть бути застарілими.",
|
||||
"loading": "Завантаження відкритих Pull Request...",
|
||||
"start_download_toast": "Завантаження PR #{{id}}"
|
||||
},
|
||||
"TitleView": {
|
||||
"decky_store_desc": "Відкрити Decky Store",
|
||||
"settings_desc": "Відкрити налаштування Decky"
|
||||
},
|
||||
"Updater": {
|
||||
"decky_updates": "Оновлення Decky",
|
||||
"no_patch_notes_desc": "Немає нотаток до цієї версії",
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import platform, os
|
||||
|
||||
ON_WINDOWS = platform.system() == "Windows"
|
||||
ON_LINUX = not ON_WINDOWS
|
||||
ON_MAC = platform.system() == "Darwin"
|
||||
ON_LINUX = not ON_WINDOWS and not ON_MAC
|
||||
|
||||
if ON_WINDOWS:
|
||||
from .localplatformwin import *
|
||||
from . import localplatformwin as localplatform
|
||||
elif ON_MAC:
|
||||
from .localplatformmac import *
|
||||
from . import localplatformmac as localplatform
|
||||
else:
|
||||
from .localplatformlinux import *
|
||||
from . import localplatformlinux as localplatform
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
from ..enums import UserType
|
||||
import os, sys
|
||||
from . import localplatformlinux
|
||||
|
||||
# this should be public
|
||||
def _get_effective_user_id() -> int:
|
||||
return os.geteuid()
|
||||
|
||||
def chown(path : str, user : UserType = UserType.HOST_USER, recursive : bool = True) -> bool:
|
||||
return localplatformlinux.chown(path, user, recursive)
|
||||
|
||||
def chmod(path : str, permissions : int, recursive : bool = True) -> bool:
|
||||
return localplatformlinux.chmod(path, permissions, recursive)
|
||||
|
||||
def file_owner(path : str) -> UserType|None:
|
||||
return localplatformlinux.file_owner(path)
|
||||
|
||||
def get_home_path(user : UserType = UserType.HOST_USER) -> str:
|
||||
return localplatformlinux.get_home_path(user)
|
||||
|
||||
def setgid(user : UserType = UserType.HOST_USER):
|
||||
return localplatformlinux.setgid(user)
|
||||
|
||||
def setuid(user : UserType = UserType.HOST_USER):
|
||||
return localplatformlinux.setuid(user)
|
||||
|
||||
async def service_active(service_name : str) -> bool:
|
||||
return True # Stubbed
|
||||
|
||||
async def service_stop(service_name : str) -> bool:
|
||||
return True # Stubbed
|
||||
|
||||
async def service_start(service_name : str) -> bool:
|
||||
return True # Stubbed
|
||||
|
||||
async def service_restart(service_name : str, block : bool = True) -> bool:
|
||||
return True # Stubbed
|
||||
|
||||
def get_effective_username() -> str:
|
||||
return localplatformlinux.get_effective_username()
|
||||
|
||||
def get_username() -> str:
|
||||
return localplatformlinux.get_username()
|
||||
|
||||
def get_privileged_path() -> str:
|
||||
'''On Mac, privileged_path is equal to unprivileged_path'''
|
||||
return get_unprivileged_path()
|
||||
|
||||
def get_unprivileged_path() -> str:
|
||||
return localplatformlinux.get_unprivileged_path()
|
||||
|
||||
def get_unprivileged_user() -> str:
|
||||
return localplatformlinux.get_unprivileged_user()
|
||||
|
||||
async def restart_webhelper() -> bool:
|
||||
return await localplatformlinux.restart_webhelper()
|
||||
|
||||
async def close_cef_socket():
|
||||
return # Stubbed
|
||||
@@ -82,6 +82,7 @@ class Utilities:
|
||||
context.ws.add_route("utilities/_call_legacy_utility", self._call_legacy_utility)
|
||||
context.ws.add_route("utilities/enable_plugin", self.enable_plugin)
|
||||
context.ws.add_route("utilities/disable_plugin", self.disable_plugin)
|
||||
context.ws.add_route("utilities/set_all_plugins_disabled", self.set_all_plugins_disabled)
|
||||
|
||||
context.web_app.add_routes([
|
||||
post("/methods/{method_name}", self._handle_legacy_server_method_call)
|
||||
@@ -503,4 +504,13 @@ class Utilities:
|
||||
disabled_plugins.remove(name)
|
||||
await self.set_setting("disabled_plugins", disabled_plugins)
|
||||
|
||||
await self.context.plugin_loader.import_plugin(path.join(plugin_dir, "main.py"), plugin_folder)
|
||||
await self.context.plugin_loader.import_plugin(path.join(plugin_dir, "main.py"), plugin_folder)
|
||||
|
||||
async def set_all_plugins_disabled(self):
|
||||
disabled_plugins: List[str] = await self.get_setting("disabled_plugins", [])
|
||||
|
||||
for name, _ in self.context.plugin_loader.plugins.items():
|
||||
if name not in disabled_plugins:
|
||||
disabled_plugins.append(name)
|
||||
|
||||
await self.set_setting("disabled_plugins", disabled_plugins)
|
||||
@@ -47,7 +47,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@decky/ui": "^4.11.4",
|
||||
"@decky/ui": "^4.11.6",
|
||||
"compare-versions": "^6.1.1",
|
||||
"filesize": "^10.1.2",
|
||||
"i18next": "^25.6.0",
|
||||
|
||||
Generated
+5
-5
@@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@decky/ui':
|
||||
specifier: ^4.11.4
|
||||
version: 4.11.4
|
||||
specifier: ^4.11.6
|
||||
version: 4.11.6
|
||||
compare-versions:
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.1
|
||||
@@ -222,8 +222,8 @@ packages:
|
||||
'@decky/api@1.1.3':
|
||||
resolution: {integrity: sha512-XsPCZxfxk5I1UtylIUN3qaWQI31siQbKfbLIskkI5innEatY1m4NQqBv/6hwPaO9mKMbdqYpnh5PSJDeMEOOBA==}
|
||||
|
||||
'@decky/ui@4.11.4':
|
||||
resolution: {integrity: sha512-8rANkj5vkYTcT7VBBUzlBuowyBctU8gU5reWtsntmYdr7dGPLRqfgKDRqVH09HCd5plXyJKWDSpqiDsUHmKRJg==}
|
||||
'@decky/ui@4.11.6':
|
||||
resolution: {integrity: sha512-vPCr2/KODeM6DAzIL/XN2e/RY7vhebXoWoh8e0VvB5QJU59Usb1z/cIpNmqe/GEMd1P3om6DFMcpEW5v8Se95Q==}
|
||||
|
||||
'@esbuild/aix-ppc64@0.20.2':
|
||||
resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
|
||||
@@ -2311,7 +2311,7 @@ snapshots:
|
||||
|
||||
'@decky/api@1.1.3': {}
|
||||
|
||||
'@decky/ui@4.11.4': {}
|
||||
'@decky/ui@4.11.6': {}
|
||||
|
||||
'@esbuild/aix-ppc64@0.20.2':
|
||||
optional: true
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
minimumReleaseAgeExclude:
|
||||
- "@decky/api"
|
||||
- "@decky/ui"
|
||||
@@ -1,7 +1,7 @@
|
||||
import { sleep } from '@decky/ui';
|
||||
import { joinClassNames, sleep } from '@decky/ui';
|
||||
import { FunctionComponent, useEffect, useReducer, useState } from 'react';
|
||||
|
||||
import { uninstallPlugin } from '../plugin';
|
||||
import { disablePlugin, uninstallPlugin } from '../plugin';
|
||||
import { VerInfo, doRestart, doShutdown } from '../updater';
|
||||
import { ValveReactErrorInfo, getLikelyErrorSourceFromValveReactError } from '../utils/errors';
|
||||
import { useSetting } from '../utils/hooks/useSetting';
|
||||
@@ -20,6 +20,26 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
const classes = {
|
||||
root: 'deckyErrorBoundary',
|
||||
likelyOccurred: 'likely-occured-msg',
|
||||
panel: 'panel-section',
|
||||
panelHeader: 'panel-header',
|
||||
trace: 'trace',
|
||||
rowList: 'row-list',
|
||||
rowItem: 'row-item',
|
||||
buttonDescRow: 'button-description-row',
|
||||
flexRowWGap: 'flex-row',
|
||||
marginBottom: 'margin-bottom',
|
||||
swipePrompt: 'swipe-prompt',
|
||||
};
|
||||
|
||||
const vars = {
|
||||
scrollBarwidth: '18px',
|
||||
rootMarginLeft: '15px',
|
||||
panelXPadding: '20px',
|
||||
};
|
||||
|
||||
export const startSSH = DeckyBackend.callable('utilities/start_ssh');
|
||||
export const starrCEFForwarding = DeckyBackend.callable('utilities/allow_remote_debugging');
|
||||
|
||||
@@ -64,39 +84,130 @@ const DeckyErrorBoundary: FunctionComponent<DeckyErrorBoundaryProps> = ({ error,
|
||||
<>
|
||||
<style>
|
||||
{`
|
||||
*:has(> .deckyErrorBoundary) {
|
||||
*:has(> .${classes.root}) {
|
||||
margin-top: var(--basicui-header-height);
|
||||
overflow: scroll !important;
|
||||
background: #000;
|
||||
}
|
||||
*:has(> .${classes.root})::-webkit-scrollbar {
|
||||
display: initial !important;
|
||||
width: ${vars.scrollBarwidth};
|
||||
height: 0px;
|
||||
}
|
||||
*:has(> .${classes.root})::-webkit-scrollbar-thumb {
|
||||
background: #4349535e;
|
||||
}
|
||||
.${classes.root} {
|
||||
color: #93929e;
|
||||
font-size: 15px;
|
||||
margin: 10px 0px 40px ${vars.rootMarginLeft};
|
||||
overflow: visible;
|
||||
}
|
||||
.${classes.root} button,
|
||||
.${classes.root} select {
|
||||
border: none;
|
||||
padding: 4px 16px !important;
|
||||
background: #333;
|
||||
color: #ddd;
|
||||
font-size: 12px;
|
||||
border-radius: 3px;
|
||||
outline: none;
|
||||
height: 28px;
|
||||
}
|
||||
.${classes.panel} {
|
||||
background: #080808;
|
||||
padding: 8px ${vars.panelXPadding};
|
||||
border-radius: 3px;
|
||||
/* box-shadow: 9px 9px 20px -5px rgb(0 0 0 / 89%); */
|
||||
}
|
||||
.${classes.panelHeader} {
|
||||
font-size: 18px;
|
||||
font-weight: bolder;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.${classes.likelyOccurred} {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
color: #588fb4;
|
||||
}
|
||||
.${classes.rowItem} {
|
||||
position: relative;
|
||||
}
|
||||
.${classes.rowItem}:not(:last-child)::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -4.5px;
|
||||
left: 5px;
|
||||
right: 15px;
|
||||
height: 0.5px;
|
||||
background: #3c3c3c47;
|
||||
}
|
||||
.${classes.flexRowWGap},
|
||||
.${classes.buttonDescRow},
|
||||
.${classes.rowList},
|
||||
.${classes.panel} {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.${classes.rowList},
|
||||
.${classes.panel} {
|
||||
flex-direction: column;
|
||||
}
|
||||
.${classes.flexRowWGap},
|
||||
.${classes.rowList} {
|
||||
gap: 8px;
|
||||
}
|
||||
.${classes.marginBottom} {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.${classes.buttonDescRow} {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.${classes.swipePrompt} {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
font-style: italic;
|
||||
font-size: small;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.${classes.swipePrompt} span {
|
||||
padding: 0 8px;
|
||||
background-color: #000;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.${classes.swipePrompt}::before,
|
||||
.${classes.swipePrompt}::after {
|
||||
content: "";
|
||||
flex-grow: 1;
|
||||
border-bottom: 1px solid #474752;
|
||||
top: 50%;
|
||||
}
|
||||
.${classes.swipePrompt}::before {
|
||||
right: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.${classes.swipePrompt}::after {
|
||||
left: 50%;
|
||||
margin-left: 8px;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<div
|
||||
style={{
|
||||
overflow: 'auto',
|
||||
marginLeft: '15px',
|
||||
color: 'white',
|
||||
fontSize: '16px',
|
||||
userSelect: 'auto',
|
||||
backgroundColor: 'black',
|
||||
marginTop: '48px', // Incase this is a page
|
||||
}}
|
||||
className="deckyErrorBoundary"
|
||||
>
|
||||
<h1
|
||||
style={{
|
||||
fontSize: '20px',
|
||||
display: 'inline-block',
|
||||
userSelect: 'auto',
|
||||
}}
|
||||
>
|
||||
⚠️ An error occured while rendering this content.
|
||||
</h1>
|
||||
<pre style={{}}>
|
||||
<div className={classes.root}>
|
||||
<div className={classes.marginBottom}>An error occurred while rendering this content.</div>
|
||||
<pre className={joinClassNames(classes.marginBottom)} style={{ marginTop: '0px' }}>
|
||||
<code>
|
||||
{identifier && `Error Reference: ${identifier}`}
|
||||
{versionInfo?.current && `\nDecky Version: ${versionInfo.current}`}
|
||||
</code>
|
||||
</pre>
|
||||
<p>This error likely occured in {errorSource}.</p>
|
||||
<div className={joinClassNames(classes.likelyOccurred, classes.marginBottom)}>
|
||||
This error likely occurred in {errorSource}.
|
||||
</div>
|
||||
{actionLog?.length > 0 && (
|
||||
<pre>
|
||||
<code>
|
||||
@@ -106,142 +217,88 @@ const DeckyErrorBoundary: FunctionComponent<DeckyErrorBoundaryProps> = ({ error,
|
||||
</pre>
|
||||
)}
|
||||
{actionsEnabled && (
|
||||
<>
|
||||
<h3>Actions: </h3>
|
||||
<p>Use the touch screen.</p>
|
||||
<div style={{ display: 'block', marginBottom: '5px' }}>
|
||||
<button style={{ marginRight: '5px', padding: '5px' }} onClick={reset}>
|
||||
Retry
|
||||
</button>
|
||||
<button
|
||||
style={{ marginRight: '5px', padding: '5px' }}
|
||||
onClick={() => {
|
||||
addLogLine('Restarting Steam...');
|
||||
SteamClient.User.StartRestart(false);
|
||||
}}
|
||||
>
|
||||
Restart Steam
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ display: 'block', marginBottom: '5px' }}>
|
||||
<button
|
||||
style={{ marginRight: '5px', padding: '5px' }}
|
||||
onClick={async () => {
|
||||
setActionsEnabled(false);
|
||||
addLogLine('Restarting Decky...');
|
||||
doRestart();
|
||||
await sleep(2000);
|
||||
addLogLine('Reloading UI...');
|
||||
}}
|
||||
>
|
||||
Restart Decky
|
||||
</button>
|
||||
<button
|
||||
style={{ marginRight: '5px', padding: '5px' }}
|
||||
onClick={async () => {
|
||||
setActionsEnabled(false);
|
||||
addLogLine('Stopping Decky...');
|
||||
doShutdown();
|
||||
await sleep(5000);
|
||||
addLogLine('Restarting Steam...');
|
||||
SteamClient.User.StartRestart(false);
|
||||
}}
|
||||
>
|
||||
Disable Decky until next boot
|
||||
</button>
|
||||
</div>
|
||||
{debugAllowed && (
|
||||
<div style={{ display: 'block', marginBottom: '5px' }}>
|
||||
<button
|
||||
style={{ marginRight: '5px', padding: '5px' }}
|
||||
onClick={async () => {
|
||||
setDebugAllowed(false);
|
||||
addLogLine('Enabling CEF debugger forwarding...');
|
||||
await starrCEFForwarding();
|
||||
addLogLine('Enabling SSH...');
|
||||
await startSSH();
|
||||
addLogLine('Ready for debugging!');
|
||||
if (window?.SystemNetworkStore?.wirelessNetworkDevice?.ip4?.addresses?.[0]?.ip) {
|
||||
const ip = ipToString(window.SystemNetworkStore.wirelessNetworkDevice.ip4.addresses[0].ip);
|
||||
addLogLine(`CEF Debugger: http://${ip}:8081`);
|
||||
addLogLine(`SSH: deck@${ip}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Allow remote debugging and SSH until next boot
|
||||
</button>
|
||||
<div className={classes.panel}>
|
||||
<div className={classes.flexRowWGap} style={{ alignItems: 'center', marginBottom: '8px' }}>
|
||||
<div className={classes.panelHeader}>Actions</div>
|
||||
<div style={{ fontSize: 'small', fontStyle: 'italic' }}>
|
||||
Use the touch screen. Solutions are listed in the recommended order. If you are still experiencing
|
||||
issues, please post in the #loader-support channel at decky.xyz/discord.
|
||||
</div>
|
||||
)}
|
||||
{
|
||||
<div style={{ display: 'block', marginBottom: '5px' }}>
|
||||
{updateProgress > -1
|
||||
? 'Update in progress... ' + updateProgress + '%'
|
||||
: updateProgress == -2
|
||||
? 'Update complete. Restarting...'
|
||||
: 'Changing your Decky Loader branch and/or \n checking for updates might help!\n'}
|
||||
{updateProgress == -1 && (
|
||||
<div style={{ height: '30px' }}>
|
||||
<select
|
||||
style={{ height: '100%' }}
|
||||
onChange={async (e) => {
|
||||
const branch = parseInt(e.target.value);
|
||||
setSelectedBranch(branch);
|
||||
setSetVersionToUpdateTo('');
|
||||
}}
|
||||
>
|
||||
<option value="0" selected={selectedBranch == UpdateBranch.Stable}>
|
||||
Stable
|
||||
</option>
|
||||
<option value="1" selected={selectedBranch == UpdateBranch.Prerelease}>
|
||||
Pre-Release
|
||||
</option>
|
||||
<option value="2" selected={selectedBranch == UpdateBranch.Testing}>
|
||||
Testing
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className={classes.rowList}>
|
||||
<div className={joinClassNames(classes.rowItem, classes.buttonDescRow)}>
|
||||
Retry the action or restart
|
||||
<div className={classes.flexRowWGap}>
|
||||
<button onClick={reset}>Retry</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
addLogLine('Restarting Steam...');
|
||||
SteamClient.User.StartRestart(false);
|
||||
}}
|
||||
>
|
||||
Restart Steam
|
||||
</button>
|
||||
<button
|
||||
onClick={async () => {
|
||||
setActionsEnabled(false);
|
||||
addLogLine('Restarting Decky...');
|
||||
doRestart();
|
||||
await sleep(2000);
|
||||
addLogLine('Reloading UI...');
|
||||
}}
|
||||
>
|
||||
Restart Decky
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{wasCausedByPlugin && (
|
||||
<div className={joinClassNames(classes.rowItem, classes.buttonDescRow)}>
|
||||
Disable or uninstall the suspected plugin
|
||||
<div className={classes.flexRowWGap}>
|
||||
<button
|
||||
style={{ height: '100%' }}
|
||||
disabled={updateProgress != -1 || isChecking}
|
||||
onClick={async () => {
|
||||
if (versionToUpdateTo == '') {
|
||||
setIsChecking(true);
|
||||
const versionInfo = (await DeckyBackend.callable(
|
||||
'updater/check_for_updates',
|
||||
)()) as unknown as VerInfo;
|
||||
setIsChecking(false);
|
||||
if (versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current) {
|
||||
setSetVersionToUpdateTo(versionInfo.remote.tag_name);
|
||||
} else {
|
||||
setSetVersionToUpdateTo('');
|
||||
}
|
||||
} else {
|
||||
DeckyBackend.callable('updater/do_update')();
|
||||
setUpdateProgress(0);
|
||||
}
|
||||
setActionsEnabled(false);
|
||||
addLogLine(`Disabling ${errorSource}...`);
|
||||
await disablePlugin(errorSource);
|
||||
await sleep(1000);
|
||||
addLogLine('Restarting Decky...');
|
||||
doRestart();
|
||||
await sleep(2000);
|
||||
addLogLine('Restarting Steam...');
|
||||
await sleep(500);
|
||||
SteamClient.User.StartRestart(false);
|
||||
}}
|
||||
>
|
||||
{' '}
|
||||
{isChecking
|
||||
? 'Checking for updates...'
|
||||
: versionToUpdateTo != ''
|
||||
? 'Update to ' + versionToUpdateTo
|
||||
: 'Check for updates'}
|
||||
Disable {errorSource}
|
||||
</button>
|
||||
<button
|
||||
onClick={async () => {
|
||||
setActionsEnabled(false);
|
||||
addLogLine(`Uninstalling ${errorSource}...`);
|
||||
await uninstallPlugin(errorSource);
|
||||
await DeckyPluginLoader.frozenPluginsService.invalidate();
|
||||
await DeckyPluginLoader.hiddenPluginsService.invalidate();
|
||||
await sleep(1000);
|
||||
addLogLine('Restarting Decky...');
|
||||
doRestart();
|
||||
await sleep(2000);
|
||||
addLogLine('Restarting Steam...');
|
||||
await sleep(500);
|
||||
SteamClient.User.StartRestart(false);
|
||||
}}
|
||||
>
|
||||
Uninstall {errorSource}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
{wasCausedByPlugin && (
|
||||
<div style={{ display: 'block', marginBottom: '5px' }}>
|
||||
{'\n'}
|
||||
</div>
|
||||
)}
|
||||
<div className={joinClassNames(classes.rowItem, classes.buttonDescRow)}>
|
||||
Disable all plugins
|
||||
<button
|
||||
style={{ marginRight: '5px', padding: '5px' }}
|
||||
onClick={async () => {
|
||||
setActionsEnabled(false);
|
||||
addLogLine(`Uninstalling ${errorSource}...`);
|
||||
await uninstallPlugin(errorSource);
|
||||
await DeckyPluginLoader.frozenPluginsService.invalidate();
|
||||
await DeckyPluginLoader.hiddenPluginsService.invalidate();
|
||||
addLogLine(`Disabling plugins...`);
|
||||
await DeckyBackend.call('utilities/set_all_plugins_disabled');
|
||||
await sleep(1000);
|
||||
addLogLine('Restarting Decky...');
|
||||
doRestart();
|
||||
@@ -251,27 +308,134 @@ const DeckyErrorBoundary: FunctionComponent<DeckyErrorBoundaryProps> = ({ error,
|
||||
SteamClient.User.StartRestart(false);
|
||||
}}
|
||||
>
|
||||
Uninstall {errorSource} and restart Decky
|
||||
Disable All Plugins
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
{
|
||||
<div className={joinClassNames(classes.rowItem, classes.buttonDescRow)}>
|
||||
{updateProgress > -1
|
||||
? 'Update in progress... ' + updateProgress + '%'
|
||||
: updateProgress == -2
|
||||
? 'Update complete. Restarting...'
|
||||
: 'Check for Decky updates'}
|
||||
{
|
||||
<div className={classes.flexRowWGap}>
|
||||
{updateProgress == -1 && (
|
||||
<>
|
||||
<select
|
||||
onChange={async (e) => {
|
||||
const branch = parseInt(e.target.value);
|
||||
setSelectedBranch(branch);
|
||||
setSetVersionToUpdateTo('');
|
||||
}}
|
||||
>
|
||||
<option value="0" selected={selectedBranch == UpdateBranch.Stable}>
|
||||
Stable
|
||||
</option>
|
||||
<option value="1" selected={selectedBranch == UpdateBranch.Prerelease}>
|
||||
Pre-Release
|
||||
</option>
|
||||
<option value="2" selected={selectedBranch == UpdateBranch.Testing}>
|
||||
Testing
|
||||
</option>
|
||||
</select>
|
||||
<button
|
||||
disabled={updateProgress != -1 || isChecking}
|
||||
onClick={async () => {
|
||||
if (versionToUpdateTo == '') {
|
||||
setIsChecking(true);
|
||||
const versionInfo = (await DeckyBackend.callable(
|
||||
'updater/check_for_updates',
|
||||
)()) as unknown as VerInfo;
|
||||
setIsChecking(false);
|
||||
if (versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current) {
|
||||
setSetVersionToUpdateTo(versionInfo.remote.tag_name);
|
||||
} else {
|
||||
setSetVersionToUpdateTo('');
|
||||
}
|
||||
} else {
|
||||
DeckyBackend.callable('updater/do_update')();
|
||||
setUpdateProgress(0);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{' '}
|
||||
{isChecking
|
||||
? 'Checking for updates...'
|
||||
: versionToUpdateTo != ''
|
||||
? 'Update to ' + versionToUpdateTo
|
||||
: 'Check for updates'}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div className={joinClassNames(classes.rowItem, classes.buttonDescRow)}>
|
||||
Disable Decky until next boot
|
||||
<button
|
||||
onClick={async () => {
|
||||
setActionsEnabled(false);
|
||||
addLogLine('Stopping Decky...');
|
||||
doShutdown();
|
||||
await sleep(5000);
|
||||
addLogLine('Restarting Steam...');
|
||||
SteamClient.User.StartRestart(false);
|
||||
}}
|
||||
>
|
||||
Disable Decky
|
||||
</button>
|
||||
</div>
|
||||
{debugAllowed && (
|
||||
<div className={joinClassNames(classes.rowItem, classes.buttonDescRow)}>
|
||||
Enable remote debugging and SSH until next boot (for developers)
|
||||
<button
|
||||
onClick={async () => {
|
||||
setDebugAllowed(false);
|
||||
addLogLine('Enabling CEF debugger forwarding...');
|
||||
await starrCEFForwarding();
|
||||
addLogLine('Enabling SSH...');
|
||||
await startSSH();
|
||||
addLogLine('Ready for debugging!');
|
||||
if (window?.SystemNetworkStore?.wirelessNetworkDevice?.ip4?.addresses?.[0]?.ip) {
|
||||
const ip = ipToString(window.SystemNetworkStore.wirelessNetworkDevice.ip4.addresses[0].ip);
|
||||
addLogLine(`CEF Debugger: http://${ip}:8081`);
|
||||
addLogLine(`SSH: deck@${ip}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Enable
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<pre
|
||||
style={{
|
||||
marginTop: '15px',
|
||||
opacity: 0.7,
|
||||
userSelect: 'auto',
|
||||
}}
|
||||
>
|
||||
<code>
|
||||
{error.error.stack}
|
||||
{'\n\n'}
|
||||
Component Stack:
|
||||
{error.info.componentStack}
|
||||
</code>
|
||||
</pre>
|
||||
{actionsEnabled && (
|
||||
<div className={classes.swipePrompt}>
|
||||
<span>Swipe to scroll</span>
|
||||
</div>
|
||||
)}
|
||||
<div className={classes.panel}>
|
||||
<div className={classes.panelHeader}>Trace</div>
|
||||
<pre
|
||||
style={{
|
||||
margin: `8px calc(-1 * ${vars.panelXPadding})`,
|
||||
userSelect: 'auto',
|
||||
overflowX: 'scroll',
|
||||
padding: `0px ${vars.panelXPadding}`,
|
||||
maskImage: `linear-gradient(to right, transparent, black ${vars.panelXPadding}, black calc(100% - ${vars.panelXPadding}), transparent)`,
|
||||
}}
|
||||
>
|
||||
<code>
|
||||
{error.error.stack}
|
||||
{'\n\n'}
|
||||
Component Stack:
|
||||
{error.info.componentStack}
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import { Carousel, DialogButton, Field, Focusable, ProgressBarWithInfo, Spinner, findSP, showModal } from '@decky/ui';
|
||||
import {
|
||||
Carousel,
|
||||
DialogButton,
|
||||
Field,
|
||||
Focusable,
|
||||
ProgressBarWithInfo,
|
||||
Spinner,
|
||||
findSP,
|
||||
gamepadDialogClasses,
|
||||
showModal,
|
||||
} from '@decky/ui';
|
||||
import { Suspense, lazy, useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaExclamation } from 'react-icons/fa';
|
||||
@@ -153,13 +163,22 @@ export default function UpdaterSettings() {
|
||||
: t('Updater.updates.install_button')}
|
||||
</DialogButton>
|
||||
) : (
|
||||
<ProgressBarWithInfo
|
||||
layout="inline"
|
||||
bottomSeparator="none"
|
||||
nProgress={updateProgress}
|
||||
indeterminate={reloading}
|
||||
sOperationText={reloading ? t('Updater.updates.reloading') : t('Updater.updates.updating')}
|
||||
/>
|
||||
<div id="decky-hide-left">
|
||||
<style>
|
||||
{`
|
||||
#decky-hide-left .${gamepadDialogClasses.FieldLeftColumn} {
|
||||
display: none;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<ProgressBarWithInfo
|
||||
layout="inline"
|
||||
bottomSeparator="none"
|
||||
nProgress={updateProgress}
|
||||
indeterminate={reloading}
|
||||
sOperationText={reloading ? t('Updater.updates.reloading') : t('Updater.updates.updating')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Field>
|
||||
{versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current && (
|
||||
|
||||
@@ -84,7 +84,10 @@ export default function TestingVersionList() {
|
||||
<Field
|
||||
label={
|
||||
<>
|
||||
{version.name} <span style={{ opacity: '50%' }}>{'#' + version.id}</span>
|
||||
{version.name}{' '}
|
||||
<span style={{ opacity: '50%', whiteSpace: 'nowrap', marginLeft: 'auto', alignSelf: 'center' }}>
|
||||
{'#' + version.id}
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -24,7 +24,7 @@ class ErrorBoundaryHook extends Logger {
|
||||
window.__ERRORBOUNDARY_HOOK_INSTANCE = this;
|
||||
|
||||
// valve writes only the sanest of code
|
||||
const exp = /^\(\)=>\(.\|\|.\(new .\),.\)$/;
|
||||
const exp = /^\(\)=>\(.\|\|(?:.\(|\(.=)new .\),.\)$/;
|
||||
const initErrorReportingStore = findModuleExport(
|
||||
(e) => typeof e == 'function' && e?.toString && exp.test(e.toString()),
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Adapted from a script provided by Jaynator495.
|
||||
# Make sure to place in home directory, chmod +x plugin-info.sh and then run with ./plugin-info.sh
|
||||
# Define the directory to scan
|
||||
directory_to_scan="~/homebrew/plugins"
|
||||
directory_to_scan="$HOME/homebrew/plugins"
|
||||
|
||||
# Loop through each subdirectory (one level deep)
|
||||
for dir in "$directory_to_scan"/*/; do
|
||||
|
||||
Reference in New Issue
Block a user