mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-06-20 10:11:22 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 543ee3d19e | |||
| 654957cb0c | |||
| 11e5236fa3 | |||
| c1dd1c7296 | |||
| 310dd700ac | |||
| 0c727d64d2 | |||
| 054517595d | |||
| ceb10fd7cf | |||
| 8e50886c48 | |||
| 76677fa877 | |||
| f6144f9634 | |||
| 79bb62a3c4 | |||
| 83f2c94712 | |||
| 25036b065f | |||
| 6bf21bf2ad | |||
| 4b47a8abeb |
@@ -105,7 +105,7 @@ Please consult [the wiki page regarding development](https://wiki.deckbrew.xyz/e
|
||||
⚠️ If you are recieving build errors due to an out of date library, you should run this command inside of your repository.
|
||||
|
||||
```bash
|
||||
pnpm update decky-frontend-lib --latest
|
||||
pnpm update @decky/ui --latest
|
||||
```
|
||||
|
||||
Source control and deploying plugins are left to each respective contributor for the cloned repos in order to keep dependencies up to date.
|
||||
|
||||
@@ -29,6 +29,8 @@ class PluginInstallType(IntEnum):
|
||||
INSTALL = 0
|
||||
REINSTALL = 1
|
||||
UPDATE = 2
|
||||
DOWNGRADE = 3
|
||||
OVERWRITE = 4
|
||||
|
||||
class PluginInstallRequest(TypedDict):
|
||||
name: str
|
||||
@@ -73,6 +75,8 @@ class PluginBrowser:
|
||||
packageJsonPath = path.join(pluginBasePath, 'package.json')
|
||||
pluginBinPath = path.join(pluginBasePath, 'bin')
|
||||
|
||||
logger.debug(f"Checking package.json at {packageJsonPath}")
|
||||
|
||||
if access(packageJsonPath, R_OK):
|
||||
with open(packageJsonPath, "r", encoding="utf-8") as f:
|
||||
packageJson = json.load(f)
|
||||
@@ -81,6 +85,7 @@ class PluginBrowser:
|
||||
chmod(pluginBasePath, 777)
|
||||
if access(pluginBasePath, W_OK):
|
||||
if not path.exists(pluginBinPath):
|
||||
logger.debug(f"Creating bin directory at {pluginBinPath}")
|
||||
mkdir(pluginBinPath)
|
||||
if not access(pluginBinPath, W_OK):
|
||||
chmod(pluginBinPath, 777)
|
||||
@@ -91,6 +96,7 @@ class PluginBrowser:
|
||||
binName = remoteBinary["name"]
|
||||
binURL = remoteBinary["url"]
|
||||
binHash = remoteBinary["sha256hash"]
|
||||
logger.info(f"Attempting to download {binName} from {binURL}")
|
||||
if not await download_remote_binary_to_path(binURL, binHash, path.join(pluginBinPath, binName)):
|
||||
rv = False
|
||||
raise Exception(f"Error Downloading Remote Binary {binName}@{binURL} with hash {binHash} to {path.join(pluginBinPath, binName)}")
|
||||
@@ -99,7 +105,7 @@ class PluginBrowser:
|
||||
chmod(pluginBasePath, 555)
|
||||
else:
|
||||
rv = True
|
||||
logger.debug(f"No Remote Binaries to Download")
|
||||
logger.info(f"No Remote Binaries to Download")
|
||||
|
||||
except Exception as e:
|
||||
rv = False
|
||||
@@ -194,7 +200,7 @@ class PluginBrowser:
|
||||
else:
|
||||
logger.fatal(f"Could not fetch from URL. {await res.text()}")
|
||||
|
||||
await self.loader.ws.emit("loader/plugin_download_info", 80, "Store.download_progress_info.increment_count")
|
||||
await self.loader.ws.emit("loader/plugin_download_info", 70, "Store.download_progress_info.increment_count")
|
||||
storeUrl = ""
|
||||
match self.settings.getSetting("store", 0):
|
||||
case 0: storeUrl = "https://plugins.deckbrew.xyz/plugins" # default
|
||||
@@ -207,7 +213,7 @@ class PluginBrowser:
|
||||
if res.status != 200:
|
||||
logger.error(f"Server did not accept install count increment request. code: {res.status}")
|
||||
|
||||
await self.loader.ws.emit("loader/plugin_download_info", 85, "Store.download_progress_info.parse_zip")
|
||||
await self.loader.ws.emit("loader/plugin_download_info", 75, "Store.download_progress_info.parse_zip")
|
||||
if res_zip and version == "dev":
|
||||
with ZipFile(res_zip) as plugin_zip:
|
||||
plugin_json_list = [file for file in plugin_zip.namelist() if file.endswith("/plugin.json") and file.count("/") == 1]
|
||||
@@ -242,7 +248,7 @@ class PluginBrowser:
|
||||
|
||||
# If plugin is installed, uninstall it
|
||||
if isInstalled:
|
||||
await self.loader.ws.emit("loader/plugin_download_info", 90, "Store.download_progress_info.uninstalling_previous")
|
||||
await self.loader.ws.emit("loader/plugin_download_info", 80, "Store.download_progress_info.uninstalling_previous")
|
||||
try:
|
||||
logger.debug("Uninstalling existing plugin...")
|
||||
await self.uninstall_plugin(name)
|
||||
@@ -250,7 +256,7 @@ class PluginBrowser:
|
||||
logger.error(f"Plugin {name} could not be uninstalled.")
|
||||
|
||||
|
||||
await self.loader.ws.emit("loader/plugin_download_info", 95, "Store.download_progress_info.installing_plugin")
|
||||
await self.loader.ws.emit("loader/plugin_download_info", 90, "Store.download_progress_info.installing_plugin")
|
||||
# Install the plugin
|
||||
logger.debug("Unzipping...")
|
||||
ret = self._unzip_to_plugin_dir(res_zip, name, hash)
|
||||
@@ -258,7 +264,7 @@ class PluginBrowser:
|
||||
plugin_folder = self.find_plugin_folder(name)
|
||||
assert plugin_folder is not None
|
||||
plugin_dir = path.join(self.plugin_path, plugin_folder)
|
||||
#TODO count again from 0% to 100% quickly for this one if it does anything
|
||||
await self.loader.ws.emit("loader/plugin_download_info", 95, "Store.download_progress_info.download_remote")
|
||||
ret = await self._download_remote_binaries_for_plugin_with_name(plugin_dir)
|
||||
if ret:
|
||||
logger.info(f"Installed {name} (Version: {version})")
|
||||
@@ -273,7 +279,8 @@ class PluginBrowser:
|
||||
logger.debug("Plugin %s was added to the pluginOrder setting", name)
|
||||
await self.loader.import_plugin(path.join(plugin_dir, "main.py"), plugin_folder)
|
||||
else:
|
||||
logger.fatal(f"Failed Downloading Remote Binaries")
|
||||
logger.error("Could not download remote binaries")
|
||||
return
|
||||
else:
|
||||
logger.fatal(f"SHA-256 Mismatch!!!! {name} (Version: {version})")
|
||||
if self.loader.watcher:
|
||||
@@ -323,5 +330,5 @@ class PluginBrowser:
|
||||
if name in plugin_order:
|
||||
plugin_order.remove(name)
|
||||
self.settings.setSetting("pluginOrder", plugin_order)
|
||||
|
||||
|
||||
logger.debug("Removed any settings for plugin %s", name)
|
||||
|
||||
@@ -4,7 +4,6 @@ import uuid
|
||||
import os
|
||||
import subprocess
|
||||
from hashlib import sha256
|
||||
from io import BytesIO
|
||||
import importlib.metadata
|
||||
|
||||
import certifi
|
||||
@@ -112,19 +111,20 @@ async def download_remote_binary_to_path(url: str, binHash: str, path: str) -> b
|
||||
if os.access(os.path.dirname(path), os.W_OK):
|
||||
async with ClientSession() as client:
|
||||
res = await client.get(url, ssl=get_ssl_context())
|
||||
if res.status == 200:
|
||||
data = BytesIO(await res.read())
|
||||
remoteHash = sha256(data.getbuffer()).hexdigest()
|
||||
if binHash == remoteHash:
|
||||
data.seek(0)
|
||||
with open(path, 'wb') as f:
|
||||
f.write(data.getbuffer())
|
||||
rv = True
|
||||
if res.status == 200:
|
||||
logger.debug("Download attempt of URL: " + url)
|
||||
data = await res.read()
|
||||
remoteHash = sha256(data).hexdigest()
|
||||
if binHash == remoteHash:
|
||||
with open(path, 'wb') as f:
|
||||
f.write(data)
|
||||
rv = True
|
||||
else:
|
||||
raise Exception(f"Fatal Error: Hash Mismatch for remote binary {path}@{url}")
|
||||
else:
|
||||
raise Exception(f"Fatal Error: Hash Mismatch for remote binary {path}@{url}")
|
||||
else:
|
||||
rv = False
|
||||
except:
|
||||
rv = False
|
||||
except Exception as e:
|
||||
logger.error("Error during download " + str(e))
|
||||
rv = False
|
||||
|
||||
return rv
|
||||
|
||||
@@ -52,7 +52,9 @@
|
||||
"MultiplePluginsInstallModal": {
|
||||
"confirm": "Are you sure you want to make the following modifications?",
|
||||
"description": {
|
||||
"downgrade": "Downgrade {{name}} to {{version}}",
|
||||
"install": "Install {{name}} {{version}}",
|
||||
"overwrite": "Overwrite {{name}} with {{version}}",
|
||||
"reinstall": "Reinstall {{name}} {{version}}",
|
||||
"update": "Update {{name}} to {{version}}"
|
||||
},
|
||||
@@ -61,10 +63,14 @@
|
||||
"loading": "Working"
|
||||
},
|
||||
"title": {
|
||||
"downgrade_one": "Downgrade 1 plugin",
|
||||
"downgrade_other": "Downgrade {{count}} plugins",
|
||||
"install_one": "Install 1 plugin",
|
||||
"install_other": "Install {{count}} plugins",
|
||||
"mixed_one": "Modify {{count}} plugin",
|
||||
"mixed_other": "Modify {{count}} plugins",
|
||||
"overwrite_one": "Overwrite 1 plugin",
|
||||
"overwrite_other": "Overwrite {{count}} plugins",
|
||||
"reinstall_one": "Reinstall 1 plugin",
|
||||
"reinstall_other": "Reinstall {{count}} plugins",
|
||||
"update_one": "Update 1 plugin",
|
||||
@@ -72,12 +78,22 @@
|
||||
}
|
||||
},
|
||||
"PluginCard": {
|
||||
"plugin_downgrade": "Downgrade",
|
||||
"plugin_full_access": "This plugin has full access to your Steam Deck.",
|
||||
"plugin_install": "Install",
|
||||
"plugin_no_desc": "No description provided.",
|
||||
"plugin_overwrite": "Overwrite",
|
||||
"plugin_reinstall": "Reinstall",
|
||||
"plugin_update": "Update",
|
||||
"plugin_version_label": "Plugin Version"
|
||||
},
|
||||
"PluginInstallModal": {
|
||||
"downgrade": {
|
||||
"button_idle": "Downgrade",
|
||||
"button_processing": "Downgrading",
|
||||
"desc": "Are you sure you want to downgrade {{artifact}} to version {{version}}?",
|
||||
"title": "Downgrade {{artifact}}"
|
||||
},
|
||||
"install": {
|
||||
"button_idle": "Install",
|
||||
"button_processing": "Installing",
|
||||
@@ -85,6 +101,13 @@
|
||||
"title": "Install {{artifact}}"
|
||||
},
|
||||
"no_hash": "This plugin does not have a hash, you are installing it at your own risk.",
|
||||
"not_installed": "(not installed)",
|
||||
"overwrite": {
|
||||
"button_idle": "Overwrite",
|
||||
"button_processing": "Overwriting",
|
||||
"desc": "Are you sure you want to overwrite {{artifact}} with version {{version}}?",
|
||||
"title": "Overwrite {{artifact}}"
|
||||
},
|
||||
"reinstall": {
|
||||
"button_idle": "Reinstall",
|
||||
"button_processing": "Reinstalling",
|
||||
@@ -94,7 +117,7 @@
|
||||
"update": {
|
||||
"button_idle": "Update",
|
||||
"button_processing": "Updating",
|
||||
"desc": "Are you sure you want to update {{artifact}} {{version}}?",
|
||||
"desc": "Are you sure you want to update {{artifact}} to version {{version}}?",
|
||||
"title": "Update {{artifact}}"
|
||||
}
|
||||
},
|
||||
@@ -200,6 +223,7 @@
|
||||
"Store": {
|
||||
"download_progress_info": {
|
||||
"download_zip": "Downloading plugin",
|
||||
"download_remote": "Downloading any external binaries",
|
||||
"increment_count": "Incrementing download count",
|
||||
"installing_plugin": "Installing plugin",
|
||||
"open_zip": "Opening zip file",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -26,7 +26,7 @@
|
||||
},
|
||||
"FilePickerIndex": {
|
||||
"file": {
|
||||
"select": "Wybierz ten plik"
|
||||
"select": "Zaznacz ten plik"
|
||||
},
|
||||
"files": {
|
||||
"all_files": "Wszystkie pliki",
|
||||
@@ -96,9 +96,9 @@
|
||||
"title": "Reinstaluj {{artifact}}"
|
||||
},
|
||||
"update": {
|
||||
"button_idle": "Aktualizacja",
|
||||
"button_idle": "Aktualizuj",
|
||||
"button_processing": "Aktualizowanie",
|
||||
"desc": "Czy na pewno chcesz zaktualizować {{artifact}} {{version}}?",
|
||||
"desc": "Czy na pewno chcesz zaktualizować {{artifact}} do wersji {{version}}?",
|
||||
"title": "Zaktualizuj {{artifact}}"
|
||||
}
|
||||
},
|
||||
@@ -122,11 +122,11 @@
|
||||
},
|
||||
"PluginLoader": {
|
||||
"decky_title": "Decky",
|
||||
"decky_update_available": "Dostępna aktualizacja do {{tag_name}}!",
|
||||
"decky_update_available": "Aktualizacja do {{tag_name}} jest dostępna!",
|
||||
"error": "Błąd",
|
||||
"plugin_error_uninstall": "Ładowanie {{name}} spowodowało wyjątek, jak pokazano powyżej. Zwykle oznacza to, że plugin wymaga aktualizacji do nowej wersji SteamUI. Sprawdź, czy aktualizacja jest obecna lub rozważ usunięcie go w ustawieniach Decky, w sekcji Pluginy.",
|
||||
"plugin_load_error": {
|
||||
"message": "Błąd ładowania plugin {{name}}",
|
||||
"message": "Błąd ładowania pluginu {{name}}",
|
||||
"toast": "Błąd ładowania {{name}}"
|
||||
},
|
||||
"plugin_uninstall": {
|
||||
@@ -205,6 +205,15 @@
|
||||
"testing_title": "Testowanie"
|
||||
},
|
||||
"Store": {
|
||||
"download_progress_info": {
|
||||
"download_zip": "Pobieranie pluginu",
|
||||
"increment_count": "Zwiększanie liczby pobrań",
|
||||
"installing_plugin": "Instalowanie pluginu",
|
||||
"open_zip": "Otwieranie pliku zip",
|
||||
"parse_zip": "Analizowanie pliku zip",
|
||||
"start": "Inicjalizacja",
|
||||
"uninstalling_previous": "Odinstalowywanie poprzednich kopii"
|
||||
},
|
||||
"store_contrib": {
|
||||
"desc": "Jeśli chcesz przyczynić się do rozwoju Decky Plugin Store, sprawdź repozytorium SteamDeckHomebrew/decky-plugin-template na GitHub. Informacje na temat rozwoju i dystrybucji są dostępne w pliku README.",
|
||||
"label": "Współtworzenie"
|
||||
@@ -236,7 +245,7 @@
|
||||
},
|
||||
"store_testing_cta": "Rozważ przetestowanie nowych pluginów, aby pomóc zespołowi Decky Loader!",
|
||||
"store_testing_warning": {
|
||||
"desc": "Możesz użyć tego kanału sklepu do testowania najnowszych wersji pluginów. Pamiętaj, aby zostawić opinię na GitHub, aby plugin mogła zostać zaktualizowana dla wszystkich użytkowników.",
|
||||
"desc": "Możesz użyć tego kanału sklepu do testowania najnowszych wersji pluginów. Pamiętaj, aby zostawić opinię na GitHub, aby plugin mógł zostać zaktualizowany dla wszystkich użytkowników.",
|
||||
"label": "Witamy w Testowym Kanale Sklepu"
|
||||
}
|
||||
},
|
||||
@@ -253,7 +262,11 @@
|
||||
}
|
||||
},
|
||||
"Testing": {
|
||||
"download": "Pobierz"
|
||||
"download": "Pobierz",
|
||||
"error": "Błąd instalowania PR",
|
||||
"header": "Następujące wersje Decky Loader są zrobione z open third-party Pull Requests. Zespół Decky Loader nie zweryfikował ich działania czy bezpieczeństwa, mogą też być nie aktualne.",
|
||||
"loading": "Ładowanie open Pull Requests...",
|
||||
"start_download_toast": "Pobieranie PR #{{id}}"
|
||||
},
|
||||
"TitleView": {
|
||||
"decky_store_desc": "Otwórz sklep Decky",
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"BranchSelect": {
|
||||
"update_channel": {
|
||||
"label": "Canal de actualização",
|
||||
"label": "Canal de atualização",
|
||||
"prerelease": "Pré-lançamento",
|
||||
"stable": "Estável",
|
||||
"testing": "Em teste"
|
||||
"testing": "Em testes"
|
||||
}
|
||||
},
|
||||
"Developer": {
|
||||
"5secreload": "Vai recarregar em 5 segundos",
|
||||
"disabling": "Desactivando React DevTools",
|
||||
"enabling": "Activando React DevTools"
|
||||
"5secreload": "A recarregar em 5 segundos",
|
||||
"disabling": "Desativar React DevTools",
|
||||
"enabling": "Ativar React DevTools"
|
||||
},
|
||||
"DropdownMultiselect": {
|
||||
"button": {
|
||||
@@ -19,9 +19,9 @@
|
||||
},
|
||||
"FilePickerError": {
|
||||
"errors": {
|
||||
"file_not_found": "O caminho especificado não é válido. Por favor, verifique e insira-o corretamente.",
|
||||
"perm_denied": "Não tem acesso ao diretório especificado. Por favor, verifique se o seu utilizador (deck na Steam Deck) possui as permissões correspondentes para aceder à pasta/ficheiro especificado.",
|
||||
"unknown": "Ocorreu um erro desconhecido. O erro é: {{raw_error}}"
|
||||
"file_not_found": "O caminho especificado não é válido. Por favor, verifica e insere o caminho correto.",
|
||||
"perm_denied": "Não tens acesso ao diretório especificado. Por favor, verifica se o seu utilizador (deck na Steam Deck) tem a permissão correspondente para aceder à pasta/ficheiro especificada(o).",
|
||||
"unknown": "Ocorreu um erro desconhecido. O erro bruto é: {{raw_error}}"
|
||||
}
|
||||
},
|
||||
"FilePickerIndex": {
|
||||
@@ -50,11 +50,11 @@
|
||||
}
|
||||
},
|
||||
"MultiplePluginsInstallModal": {
|
||||
"confirm": "De certeza que queres fazer as seguintes alterações?",
|
||||
"confirm": "Tens a certeza de que pretendes fazer as seguintes alterações?",
|
||||
"description": {
|
||||
"install": "Instalar {{name}} {{version}}",
|
||||
"reinstall": "Reinstalar {{name}} {{version}}",
|
||||
"update": "Actualizar {{name}} para {{version}}"
|
||||
"update": "Atualizar {{name}} para {{version}}"
|
||||
},
|
||||
"ok_button": {
|
||||
"idle": "Confirmar",
|
||||
@@ -70,15 +70,15 @@
|
||||
"reinstall_many": "Reinstalar {{count}} plugins",
|
||||
"reinstall_one": "Reinstalar 1 plugin",
|
||||
"reinstall_other": "Reinstalar {{count}} plugins",
|
||||
"update_many": "Actualizar {{count}} plugins",
|
||||
"update_one": "Actualizar 1 plugin",
|
||||
"update_other": "Actualizar {{count}} plugins"
|
||||
"update_many": "Atualizar {{count}} plugins",
|
||||
"update_one": "Atualizar 1 plugin",
|
||||
"update_other": "Atualizar {{count}} plugins"
|
||||
}
|
||||
},
|
||||
"PluginCard": {
|
||||
"plugin_full_access": "Este plugin tem acesso total à tua Steam Deck.",
|
||||
"plugin_full_access": "Este plugin tem acesso total ao teu Steam Deck.",
|
||||
"plugin_install": "Instalar",
|
||||
"plugin_no_desc": "Não tem descrição.",
|
||||
"plugin_no_desc": "Sem descrição fornecida.",
|
||||
"plugin_version_label": "Versão do plugin"
|
||||
},
|
||||
"PluginInstallModal": {
|
||||
@@ -88,7 +88,7 @@
|
||||
"desc": "De certeza que queres instalar {{artifact}} {{version}}?",
|
||||
"title": "Instalar {{artifact}}"
|
||||
},
|
||||
"no_hash": "Este plugin não tem um hash, estás a instalá-lo por tua conta e risco.",
|
||||
"no_hash": "Este plugin não tem uma hash, estás a instalá-lo por tua conta e risco.",
|
||||
"reinstall": {
|
||||
"button_idle": "Reinstalar",
|
||||
"button_processing": "Reinstalação em curso",
|
||||
@@ -96,24 +96,26 @@
|
||||
"title": "Reinstalar {{artifact}}"
|
||||
},
|
||||
"update": {
|
||||
"button_idle": "Actualizar",
|
||||
"button_processing": "Actualização em curso",
|
||||
"desc": "De certeza que queres actualizar {{artifact}} {{version}}?",
|
||||
"title": "Actualizar {{artifact}}"
|
||||
"button_idle": "Atualizar",
|
||||
"button_processing": "Atualização em curso",
|
||||
"desc": "De certeza que queres atualizar {{artifact}} {{version}}?",
|
||||
"title": "Atualizar {{artifact}}"
|
||||
}
|
||||
},
|
||||
"PluginListIndex": {
|
||||
"freeze": "Congelar atualizações",
|
||||
"hide": "Acesso rápido: Ocultar",
|
||||
"no_plugin": "Nenhum plugin instalado!",
|
||||
"plugin_actions": "Operações de plugin",
|
||||
"reinstall": "Reinstalar",
|
||||
"reload": "Recarregar",
|
||||
"show": "Acesso rápido: Mostrar",
|
||||
"unfreeze": "Permitir atualizações",
|
||||
"uninstall": "Desinstalar",
|
||||
"update_all_many": "Actualizar {{count}} plugins",
|
||||
"update_all_one": "Actualizar 1 plugin",
|
||||
"update_all_other": "Actualizar {{count}} plugins",
|
||||
"update_to": "Actualizar para {{name}}"
|
||||
"update_all_many": "Atualizar {{count}} plugins",
|
||||
"update_all_one": "Atualizar 1 plugin",
|
||||
"update_all_other": "Atualizar {{count}} plugins",
|
||||
"update_to": "Atualizar para {{name}}"
|
||||
},
|
||||
"PluginListLabel": {
|
||||
"hidden": "Oculto do menu de acesso rápido"
|
||||
@@ -122,7 +124,7 @@
|
||||
"decky_title": "Decky",
|
||||
"decky_update_available": "Está disponível uma nova versão de {{tag_name}} !",
|
||||
"error": "Erro",
|
||||
"plugin_error_uninstall": "Houve uma excepção ao carregar {{name}}, como mostrado em cima. Pode ter sido porque o plugin requere a última versão do SteamUI. Verifica se há uma actualização disponível ou desinstala o plugin nas definições do Decky.",
|
||||
"plugin_error_uninstall": "Ao carregar {{name}}, ocorreu uma exceção, como pode ser verificado acima. Pode ter sido porque o plugin requer a última versão do SteamUI. Verifica se há uma atualização disponível ou desinstala o plugin nas definições do Decky.",
|
||||
"plugin_load_error": {
|
||||
"message": "Erro ao carregar o plugin {{name}}",
|
||||
"toast": "Erro ao carregar {{name}}"
|
||||
@@ -133,7 +135,7 @@
|
||||
"title": "Desinstalar {{name}}"
|
||||
},
|
||||
"plugin_update_many": "{{count}} plugins têm actualizações disponíveis!",
|
||||
"plugin_update_one": "1 plugin tem actualizações disponíveis!",
|
||||
"plugin_update_one": "1 plugin tem atualizações disponíveis!",
|
||||
"plugin_update_other": "{{count}} plugins têm actualizações disponíveis!"
|
||||
},
|
||||
"PluginView": {
|
||||
@@ -143,34 +145,34 @@
|
||||
},
|
||||
"RemoteDebugging": {
|
||||
"remote_cef": {
|
||||
"desc": "Permitir acesso não autenticado ao debugger do CEF a qualquer pessoa na tua rede",
|
||||
"label": "Permitir debugging remoto do CEF"
|
||||
"desc": "Permitir acesso não autenticado ao depurador do CEF a qualquer pessoa na tua rede",
|
||||
"label": "Permitir Depuração Remota do CEF"
|
||||
}
|
||||
},
|
||||
"SettingsDeveloperIndex": {
|
||||
"cef_console": {
|
||||
"button": "Abrir consola",
|
||||
"desc": "Abre a consola do CEF. Só é útil para efeitos de debugging. Pode ser perigosa e só deve ser usada se és um desenvolvedor de plugins, ou se foste aqui indicado por um desenvolvedor.",
|
||||
"desc": "Abre a Consola CEF. Apenas útil para fins de depuração. O conteúdo aqui presente pode ser perigoso e só devem ser usadas se fores um desenvolvedor de plugins ou se fores direcionado para aqui por um.",
|
||||
"label": "Consola CEF"
|
||||
},
|
||||
"header": "Outros",
|
||||
"react_devtools": {
|
||||
"desc": "Permite a conecção a um computador que está a correr React DevTools. Mudar esta definição vai recarregar o Steam. Define o endereço de IP antes de activar.",
|
||||
"desc": "Permite a conexão a um computador a correr o React DevTools. Alterar esta definição irá recarregar o Steam. Define o endereço IP antes de ativar.",
|
||||
"ip_label": "IP",
|
||||
"label": "Activar React DevTools"
|
||||
"label": "Ativar React DevTools"
|
||||
},
|
||||
"third_party_plugins": {
|
||||
"button_install": "Instalar",
|
||||
"button_zip": "Navegar",
|
||||
"header": "Plugins de terceiros",
|
||||
"label_desc": "URl",
|
||||
"label_url": "Instalar plugin a partir dum URL",
|
||||
"label_zip": "Instalar plugin a partir dum ficheiro ZIP"
|
||||
"label_desc": "URL",
|
||||
"label_url": "Instalar plugin a partir de um URL",
|
||||
"label_zip": "Instalar plugin a partir de um ficheiro ZIP"
|
||||
},
|
||||
"valve_internal": {
|
||||
"desc1": "Activa o menu interno de programador da Valve.",
|
||||
"desc2": "Não toques em nada deste menu se não souberes a sua função.",
|
||||
"label": "Activar menu interno da Valve"
|
||||
"desc1": "Ativa o menu interno de programador da Valve.",
|
||||
"desc2": "Não toques em nada neste menu, a menos que saibas o que faz.",
|
||||
"label": "Cativar menu interno da Valve"
|
||||
}
|
||||
},
|
||||
"SettingsGeneralIndex": {
|
||||
@@ -193,17 +195,27 @@
|
||||
"header": "Outros"
|
||||
},
|
||||
"updates": {
|
||||
"header": "Actualizações"
|
||||
"header": "Atualizações"
|
||||
}
|
||||
},
|
||||
"SettingsIndex": {
|
||||
"developer_title": "Programador",
|
||||
"general_title": "Geral",
|
||||
"plugins_title": "Plugins"
|
||||
"plugins_title": "Plugins",
|
||||
"testing_title": "Testes"
|
||||
},
|
||||
"Store": {
|
||||
"download_progress_info": {
|
||||
"download_zip": "A transferir o plugin",
|
||||
"increment_count": "A incrementar a contagem de transferências",
|
||||
"installing_plugin": "A instalar o plugin",
|
||||
"open_zip": "A abrir o ficheiro zip",
|
||||
"parse_zip": "A processar o ficheiro zip",
|
||||
"start": "A inicializar",
|
||||
"uninstalling_previous": "A desinstalar a cópia anterior"
|
||||
},
|
||||
"store_contrib": {
|
||||
"desc": "Se queres contribuir com um novo plugin, vai ao repositório SteamDeckHomebrew/decky-plugin-template no GitHub. No README, podes encontrar mais informação sobre desenvolvimento e distribuição.",
|
||||
"desc": "Se quiseres contribuir para a Loja de Plugins do Decky, consulta o repositório SteamDeckHomebrew/decky-plugin-template no GitHub. Encontras informações sobre desenvolvimento e distribuição no README.",
|
||||
"label": "Contribuir"
|
||||
},
|
||||
"store_filter": {
|
||||
@@ -215,21 +227,25 @@
|
||||
},
|
||||
"store_sort": {
|
||||
"label": "Ordenar",
|
||||
"label_def": "Última actualização (mais recente)"
|
||||
"label_def": "Última atualização (mais recente)"
|
||||
},
|
||||
"store_source": {
|
||||
"desc": "O código fonte de cada plugin está disponível no repositório SteamDeckHomebrew/decky-plugin-database no GitHub.",
|
||||
"desc": "Todo o código-fonte dos plugins está disponível no repositório SteamDeckHomebrew/decky-plugin-database no GitHub.",
|
||||
"label": "Código fonte"
|
||||
},
|
||||
"store_tabs": {
|
||||
"about": "Sobre",
|
||||
"alph_asce": "Alfabeticamente (Z-A)",
|
||||
"alph_desc": "Alfabeticamente (A-Z)",
|
||||
"date_asce": "Mais Antigos Primeiro",
|
||||
"date_desc": "Mais Recentes Primeiro",
|
||||
"downloads_asce": "Menos Transferidos Primeiro",
|
||||
"downloads_desc": "Mais Transferidos Primeiro",
|
||||
"title": "Navegar"
|
||||
},
|
||||
"store_testing_cta": "Testa novos plugins e ajuda a equipa do Decky Loader!",
|
||||
"store_testing_warning": {
|
||||
"desc": "Pode usar esta versão da loja para testar versões experimentais de plugins. Certifique-se de deixar feedback no GitHub para que o plugin possa ser atualizado para todos os utilizadores.",
|
||||
"desc": "Podes utilizar este canal da loja para testar versões de plugins de última geração. Não te esqueças de deixar o teufeedback no GitHub para que o plugin possa ser atualizado para todos os utilizadores.",
|
||||
"label": "Bem-vindo ao Canal de Testes da Loja"
|
||||
}
|
||||
},
|
||||
@@ -240,28 +256,35 @@
|
||||
},
|
||||
"store_channel": {
|
||||
"custom": "Personalizada",
|
||||
"default": "Standard",
|
||||
"label": "Canal de loja",
|
||||
"testing": "Em teste"
|
||||
"default": "Padrão",
|
||||
"label": "Canal da loja",
|
||||
"testing": "Em testes"
|
||||
}
|
||||
},
|
||||
"Testing": {
|
||||
"download": "Transferir",
|
||||
"error": "Erro ao instalar PR",
|
||||
"header": "As seguintes versões do Decky Loader estão construidas a partir de Pull Requests de terceiros. A equipa do Decky Loader não verificou as sua funcionalidade ou segurança e as mesmas podem estar desatualizados.",
|
||||
"loading": "A carregar Pull Requests abertos...",
|
||||
"start_download_toast": "A descarregar PR #{{id}}"
|
||||
},
|
||||
"TitleView": {
|
||||
"decky_store_desc": "Abrir a Loja Decky",
|
||||
"settings_desc": "Abrir as Definições Decky"
|
||||
},
|
||||
"Updater": {
|
||||
"decky_updates": "Actualizações do Decky",
|
||||
"no_patch_notes_desc": "sem registo de alterações desta versão",
|
||||
"patch_notes_desc": "Registo de alterações",
|
||||
"decky_updates": "Atualizações do Decky",
|
||||
"no_patch_notes_desc": "sem notas de atualizações para esta versão",
|
||||
"patch_notes_desc": "Notas de atualizações",
|
||||
"updates": {
|
||||
"check_button": "Procurar actualizações",
|
||||
"checking": "Busca de actualizações em curso",
|
||||
"cur_version": "Versão actual: {{ver}}",
|
||||
"install_button": "Instalar actualização",
|
||||
"label": "Actualizações",
|
||||
"lat_version": "Actualizado: a correr {{ver}}",
|
||||
"reloading": "Recarregar",
|
||||
"updating": "Actualização em curso"
|
||||
"check_button": "Procurar atualizações",
|
||||
"checking": "A verificar atualizações",
|
||||
"cur_version": "Versão atual: {{ver}}",
|
||||
"install_button": "Instalar Atualização",
|
||||
"label": "Atualizações",
|
||||
"lat_version": "Atualizado: a executar {{ver}}",
|
||||
"reloading": "Recarregando",
|
||||
"updating": "Atualização em curso"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +186,7 @@ class SandboxedPlugin:
|
||||
|
||||
if "uninstall" in data:
|
||||
self.uninstalling = data.get("uninstall")
|
||||
return
|
||||
|
||||
d: SocketResponseDict = {"type": SocketMessageType.RESPONSE, "res": None, "success": True, "id": data["id"]}
|
||||
try:
|
||||
|
||||
Generated
+98
-98
@@ -1,4 +1,4 @@
|
||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "aiohappyeyeballs"
|
||||
@@ -13,108 +13,108 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
version = "3.10.10"
|
||||
version = "3.10.11"
|
||||
description = "Async http client/server framework (asyncio)"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be7443669ae9c016b71f402e43208e13ddf00912f47f623ee5994e12fc7d4b3f"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b06b7843929e41a94ea09eb1ce3927865387e3e23ebe108e0d0d09b08d25be9"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:333cf6cf8e65f6a1e06e9eb3e643a0c515bb850d470902274239fea02033e9a8"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:274cfa632350225ce3fdeb318c23b4a10ec25c0e2c880eff951a3842cf358ac1"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9e5e4a85bdb56d224f412d9c98ae4cbd032cc4f3161818f692cd81766eee65a"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b606353da03edcc71130b52388d25f9a30a126e04caef1fd637e31683033abd"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab5a5a0c7a7991d90446a198689c0535be89bbd6b410a1f9a66688f0880ec026"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578a4b875af3e0daaf1ac6fa983d93e0bbfec3ead753b6d6f33d467100cdc67b"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8105fd8a890df77b76dd3054cddf01a879fc13e8af576805d667e0fa0224c35d"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3bcd391d083f636c06a68715e69467963d1f9600f85ef556ea82e9ef25f043f7"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fbc6264158392bad9df19537e872d476f7c57adf718944cc1e4495cbabf38e2a"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e48d5021a84d341bcaf95c8460b152cfbad770d28e5fe14a768988c461b821bc"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2609e9ab08474702cc67b7702dbb8a80e392c54613ebe80db7e8dbdb79837c68"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-win32.whl", hash = "sha256:84afcdea18eda514c25bc68b9af2a2b1adea7c08899175a51fe7c4fb6d551257"},
|
||||
{file = "aiohttp-3.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:9c72109213eb9d3874f7ac8c0c5fa90e072d678e117d9061c06e30c85b4cf0e6"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3935f82f6f4a3820270842e90456ebad3af15810cf65932bd24da4463bc0a4c"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:413251f6fcf552a33c981c4709a6bba37b12710982fec8e558ae944bfb2abd38"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1720b4f14c78a3089562b8875b53e36b51c97c51adc53325a69b79b4b48ebcb"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:679abe5d3858b33c2cf74faec299fda60ea9de62916e8b67e625d65bf069a3b7"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79019094f87c9fb44f8d769e41dbb664d6e8fcfd62f665ccce36762deaa0e911"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2fb38c2ed905a2582948e2de560675e9dfbee94c6d5ccdb1301c6d0a5bf092"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a3f00003de6eba42d6e94fabb4125600d6e484846dbf90ea8e48a800430cc142"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1bbb122c557a16fafc10354b9d99ebf2f2808a660d78202f10ba9d50786384b9"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30ca7c3b94708a9d7ae76ff281b2f47d8eaf2579cd05971b5dc681db8caac6e1"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df9270660711670e68803107d55c2b5949c2e0f2e4896da176e1ecfc068b974a"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-win32.whl", hash = "sha256:aafc8ee9b742ce75044ae9a4d3e60e3d918d15a4c2e08a6c3c3e38fa59b92d94"},
|
||||
{file = "aiohttp-3.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:362f641f9071e5f3ee6f8e7d37d5ed0d95aae656adf4ef578313ee585b585959"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-win32.whl", hash = "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628"},
|
||||
{file = "aiohttp-3.10.10-cp312-cp312-win_amd64.whl", hash = "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ad7593bb24b2ab09e65e8a1d385606f0f47c65b5a2ae6c551db67d6653e78c28"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1eb89d3d29adaf533588f209768a9c02e44e4baf832b08118749c5fad191781d"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3fe407bf93533a6fa82dece0e74dbcaaf5d684e5a51862887f9eaebe6372cd79"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50aed5155f819873d23520919e16703fc8925e509abbb1a1491b0087d1cd969e"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f05e9727ce409358baa615dbeb9b969db94324a79b5a5cea45d39bdb01d82e6"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dffb610a30d643983aeb185ce134f97f290f8935f0abccdd32c77bed9388b42"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa6658732517ddabe22c9036479eabce6036655ba87a0224c612e1ae6af2087e"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:741a46d58677d8c733175d7e5aa618d277cd9d880301a380fd296975a9cdd7bc"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e00e3505cd80440f6c98c6d69269dcc2a119f86ad0a9fd70bccc59504bebd68a"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ffe595f10566f8276b76dc3a11ae4bb7eba1aac8ddd75811736a15b0d5311414"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdfcf6443637c148c4e1a20c48c566aa694fa5e288d34b20fcdc58507882fed3"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d183cf9c797a5291e8301790ed6d053480ed94070637bfaad914dd38b0981f67"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:77abf6665ae54000b98b3c742bc6ea1d1fb31c394bcabf8b5d2c1ac3ebfe7f3b"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-win32.whl", hash = "sha256:4470c73c12cd9109db8277287d11f9dd98f77fc54155fc71a7738a83ffcc8ea8"},
|
||||
{file = "aiohttp-3.10.10-cp313-cp313-win_amd64.whl", hash = "sha256:486f7aabfa292719a2753c016cc3a8f8172965cabb3ea2e7f7436c7f5a22a151"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1b66ccafef7336a1e1f0e389901f60c1d920102315a56df85e49552308fc0486"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:acd48d5b80ee80f9432a165c0ac8cbf9253eaddb6113269a5e18699b33958dbb"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3455522392fb15ff549d92fbf4b73b559d5e43dc522588f7eb3e54c3f38beee7"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c3b868724137f713a38376fef8120c166d1eadd50da1855c112fe97954aed8"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:da1dee8948d2137bb51fbb8a53cce6b1bcc86003c6b42565f008438b806cccd8"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5ce2ce7c997e1971b7184ee37deb6ea9922ef5163c6ee5aa3c274b05f9e12fa"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28529e08fde6f12eba8677f5a8608500ed33c086f974de68cc65ab218713a59d"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7db54c7914cc99d901d93a34704833568d86c20925b2762f9fa779f9cd2e70f"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03a42ac7895406220124c88911ebee31ba8b2d24c98507f4a8bf826b2937c7f2"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7e338c0523d024fad378b376a79faff37fafb3c001872a618cde1d322400a572"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:038f514fe39e235e9fef6717fbf944057bfa24f9b3db9ee551a7ecf584b5b480"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:64f6c17757251e2b8d885d728b6433d9d970573586a78b78ba8929b0f41d045a"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:93429602396f3383a797a2a70e5f1de5df8e35535d7806c9f91df06f297e109b"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-win32.whl", hash = "sha256:c823bc3971c44ab93e611ab1a46b1eafeae474c0c844aff4b7474287b75fe49c"},
|
||||
{file = "aiohttp-3.10.10-cp38-cp38-win_amd64.whl", hash = "sha256:54ca74df1be3c7ca1cf7f4c971c79c2daf48d9aa65dea1a662ae18926f5bc8ce"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:01948b1d570f83ee7bbf5a60ea2375a89dfb09fd419170e7f5af029510033d24"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9fc1500fd2a952c5c8e3b29aaf7e3cc6e27e9cfc0a8819b3bce48cc1b849e4cc"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f614ab0c76397661b90b6851a030004dac502e48260ea10f2441abd2207fbcc7"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00819de9e45d42584bed046314c40ea7e9aea95411b38971082cad449392b08c"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05646ebe6b94cc93407b3bf34b9eb26c20722384d068eb7339de802154d61bc5"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:998f3bd3cfc95e9424a6acd7840cbdd39e45bc09ef87533c006f94ac47296090"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9010c31cd6fa59438da4e58a7f19e4753f7f264300cd152e7f90d4602449762"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ea7ffc6d6d6f8a11e6f40091a1040995cdff02cfc9ba4c2f30a516cb2633554"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ef9c33cc5cbca35808f6c74be11eb7f5f6b14d2311be84a15b594bd3e58b5527"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ce0cdc074d540265bfeb31336e678b4e37316849d13b308607efa527e981f5c2"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:597a079284b7ee65ee102bc3a6ea226a37d2b96d0418cc9047490f231dc09fe8"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7789050d9e5d0c309c706953e5e8876e38662d57d45f936902e176d19f1c58ab"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e7f8b04d83483577fd9200461b057c9f14ced334dcb053090cea1da9c8321a91"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-win32.whl", hash = "sha256:c02a30b904282777d872266b87b20ed8cc0d1501855e27f831320f471d54d983"},
|
||||
{file = "aiohttp-3.10.10-cp39-cp39-win_amd64.whl", hash = "sha256:edfe3341033a6b53a5c522c802deb2079eee5cbfbb0af032a55064bd65c73a23"},
|
||||
{file = "aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5077b1a5f40ffa3ba1f40d537d3bec4383988ee51fbba6b74aa8fb1bc466599e"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d6a14a4d93b5b3c2891fca94fa9d41b2322a68194422bef0dd5ec1e57d7d298"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffbfde2443696345e23a3c597049b1dd43049bb65337837574205e7368472177"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b3d9e416774d41813bc02fdc0663379c01817b0874b932b81c7f777f67b217"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b943011b45ee6bf74b22245c6faab736363678e910504dd7531a58c76c9015a"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48bc1d924490f0d0b3658fe5c4b081a4d56ebb58af80a6729d4bd13ea569797a"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e12eb3f4b1f72aaaf6acd27d045753b18101524f72ae071ae1c91c1cd44ef115"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f14ebc419a568c2eff3c1ed35f634435c24ead2fe19c07426af41e7adb68713a"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:72b191cdf35a518bfc7ca87d770d30941decc5aaf897ec8b484eb5cc8c7706f3"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ab2328a61fdc86424ee540d0aeb8b73bbcad7351fb7cf7a6546fc0bcffa0038"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa93063d4af05c49276cf14e419550a3f45258b6b9d1f16403e777f1addf4519"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:30283f9d0ce420363c24c5c2421e71a738a2155f10adbb1a11a4d4d6d2715cfc"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e5358addc8044ee49143c546d2182c15b4ac3a60be01c3209374ace05af5733d"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-win32.whl", hash = "sha256:e1ffa713d3ea7cdcd4aea9cddccab41edf6882fa9552940344c44e59652e1120"},
|
||||
{file = "aiohttp-3.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:778cbd01f18ff78b5dd23c77eb82987ee4ba23408cbed233009fd570dda7e674"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:80ff08556c7f59a7972b1e8919f62e9c069c33566a6d28586771711e0eea4f07"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c8f96e9ee19f04c4914e4e7a42a60861066d3e1abf05c726f38d9d0a466e695"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb8601394d537da9221947b5d6e62b064c9a43e88a1ecd7414d21a1a6fba9c24"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ea224cf7bc2d8856d6971cea73b1d50c9c51d36971faf1abc169a0d5f85a382"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db9503f79e12d5d80b3efd4d01312853565c05367493379df76d2674af881caa"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0f449a50cc33f0384f633894d8d3cd020e3ccef81879c6e6245c3c375c448625"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82052be3e6d9e0c123499127782a01a2b224b8af8c62ab46b3f6197035ad94e9"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20063c7acf1eec550c8eb098deb5ed9e1bb0521613b03bb93644b810986027ac"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:489cced07a4c11488f47aab1f00d0c572506883f877af100a38f1fedaa884c3a"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ea9b3bab329aeaa603ed3bf605f1e2a6f36496ad7e0e1aa42025f368ee2dc07b"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ca117819d8ad113413016cb29774b3f6d99ad23c220069789fc050267b786c16"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2dfb612dcbe70fb7cdcf3499e8d483079b89749c857a8f6e80263b021745c730"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9b615d3da0d60e7d53c62e22b4fd1c70f4ae5993a44687b011ea3a2e49051b8"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-win32.whl", hash = "sha256:29103f9099b6068bbdf44d6a3d090e0a0b2be6d3c9f16a070dd9d0d910ec08f9"},
|
||||
{file = "aiohttp-3.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:236b28ceb79532da85d59aa9b9bf873b364e27a0acb2ceaba475dc61cffb6f3f"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7480519f70e32bfb101d71fb9a1f330fbd291655a4c1c922232a48c458c52710"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f65267266c9aeb2287a6622ee2bb39490292552f9fbf851baabc04c9f84e048d"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7400a93d629a0608dc1d6c55f1e3d6e07f7375745aaa8bd7f085571e4d1cee97"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f34b97e4b11b8d4eb2c3a4f975be626cc8af99ff479da7de49ac2c6d02d35725"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e7b825da878464a252ccff2958838f9caa82f32a8dbc334eb9b34a026e2c636"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9f92a344c50b9667827da308473005f34767b6a2a60d9acff56ae94f895f385"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f1ab987a27b83c5268a17218463c2ec08dbb754195113867a27b166cd6087"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1dc0f4ca54842173d03322793ebcf2c8cc2d34ae91cc762478e295d8e361e03f"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7ce6a51469bfaacff146e59e7fb61c9c23006495d11cc24c514a455032bcfa03"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aad3cd91d484d065ede16f3cf15408254e2469e3f613b241a1db552c5eb7ab7d"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f4df4b8ca97f658c880fb4b90b1d1ec528315d4030af1ec763247ebfd33d8b9a"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2e4e18a0a2d03531edbc06c366954e40a3f8d2a88d2b936bbe78a0c75a3aab3e"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ce66780fa1a20e45bc753cda2a149daa6dbf1561fc1289fa0c308391c7bc0a4"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-win32.whl", hash = "sha256:a919c8957695ea4c0e7a3e8d16494e3477b86f33067478f43106921c2fef15bb"},
|
||||
{file = "aiohttp-3.10.11-cp312-cp312-win_amd64.whl", hash = "sha256:b5e29706e6389a2283a91611c91bf24f218962717c8f3b4e528ef529d112ee27"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:703938e22434d7d14ec22f9f310559331f455018389222eed132808cd8f44127"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9bc50b63648840854e00084c2b43035a62e033cb9b06d8c22b409d56eb098413"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f0463bf8b0754bc744e1feb61590706823795041e63edf30118a6f0bf577461"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6c6dec398ac5a87cb3a407b068e1106b20ef001c344e34154616183fe684288"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcaf2d79104d53d4dcf934f7ce76d3d155302d07dae24dff6c9fffd217568067"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25fd5470922091b5a9aeeb7e75be609e16b4fba81cdeaf12981393fb240dd10e"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbde2ca67230923a42161b1f408c3992ae6e0be782dca0c44cb3206bf330dee1"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:249c8ff8d26a8b41a0f12f9df804e7c685ca35a207e2410adbd3e924217b9006"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:878ca6a931ee8c486a8f7b432b65431d095c522cbeb34892bee5be97b3481d0f"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8663f7777ce775f0413324be0d96d9730959b2ca73d9b7e2c2c90539139cbdd6"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6cd3f10b01f0c31481fba8d302b61603a2acb37b9d30e1d14e0f5a58b7b18a31"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4e8d8aad9402d3aa02fdc5ca2fe68bcb9fdfe1f77b40b10410a94c7f408b664d"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38e3c4f80196b4f6c3a85d134a534a56f52da9cb8d8e7af1b79a32eefee73a00"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-win32.whl", hash = "sha256:fc31820cfc3b2863c6e95e14fcf815dc7afe52480b4dc03393c4873bb5599f71"},
|
||||
{file = "aiohttp-3.10.11-cp313-cp313-win_amd64.whl", hash = "sha256:4996ff1345704ffdd6d75fb06ed175938c133425af616142e7187f28dc75f14e"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74baf1a7d948b3d640badeac333af581a367ab916b37e44cf90a0334157cdfd2"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:473aebc3b871646e1940c05268d451f2543a1d209f47035b594b9d4e91ce8339"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c2f746a6968c54ab2186574e15c3f14f3e7f67aef12b761e043b33b89c5b5f95"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d110cabad8360ffa0dec8f6ec60e43286e9d251e77db4763a87dcfe55b4adb92"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0099c7d5d7afff4202a0c670e5b723f7718810000b4abcbc96b064129e64bc7"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0316e624b754dbbf8c872b62fe6dcb395ef20c70e59890dfa0de9eafccd2849d"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a5f7ab8baf13314e6b2485965cbacb94afff1e93466ac4d06a47a81c50f9cca"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c891011e76041e6508cbfc469dd1a8ea09bc24e87e4c204e05f150c4c455a5fa"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9208299251370ee815473270c52cd3f7069ee9ed348d941d574d1457d2c73e8b"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:459f0f32c8356e8125f45eeff0ecf2b1cb6db1551304972702f34cd9e6c44658"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:14cdc8c1810bbd4b4b9f142eeee23cda528ae4e57ea0923551a9af4820980e39"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:971aa438a29701d4b34e4943e91b5e984c3ae6ccbf80dd9efaffb01bd0b243a9"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9a309c5de392dfe0f32ee57fa43ed8fc6ddf9985425e84bd51ed66bb16bce3a7"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-win32.whl", hash = "sha256:9ec1628180241d906a0840b38f162a3215114b14541f1a8711c368a8739a9be4"},
|
||||
{file = "aiohttp-3.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:9c6e0ffd52c929f985c7258f83185d17c76d4275ad22e90aa29f38e211aacbec"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc493a2e5d8dc79b2df5bec9558425bcd39aff59fc949810cbd0832e294b106"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3e70f24e7d0405be2348da9d5a7836936bf3a9b4fd210f8c37e8d48bc32eca6"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968b8fb2a5eee2770eda9c7b5581587ef9b96fbdf8dcabc6b446d35ccc69df01"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deef4362af9493d1382ef86732ee2e4cbc0d7c005947bd54ad1a9a16dd59298e"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:686b03196976e327412a1b094f4120778c7c4b9cff9bce8d2fdfeca386b89829"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bf6d027d9d1d34e1c2e1645f18a6498c98d634f8e373395221121f1c258ace8"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:099fd126bf960f96d34a760e747a629c27fb3634da5d05c7ef4d35ef4ea519fc"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c73c4d3dae0b4644bc21e3de546530531d6cdc88659cdeb6579cd627d3c206aa"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c5580f3c51eea91559db3facd45d72e7ec970b04528b4709b1f9c2555bd6d0b"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fdf6429f0caabfd8a30c4e2eaecb547b3c340e4730ebfe25139779b9815ba138"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d97187de3c276263db3564bb9d9fad9e15b51ea10a371ffa5947a5ba93ad6777"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0acafb350cfb2eba70eb5d271f55e08bd4502ec35e964e18ad3e7d34d71f7261"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c13ed0c779911c7998a58e7848954bd4d63df3e3575f591e321b19a2aec8df9f"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-win32.whl", hash = "sha256:22b7c540c55909140f63ab4f54ec2c20d2635c0289cdd8006da46f3327f971b9"},
|
||||
{file = "aiohttp-3.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:7b26b1551e481012575dab8e3727b16fe7dd27eb2711d2e63ced7368756268fb"},
|
||||
{file = "aiohttp-3.10.11.tar.gz", hash = "sha256:9dc2b8f3dcab2e39e0fa309c8da50c3b55e6f34ab25f1a71d3288f24924d33a7"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aiohappyeyeballs = ">=2.3.0"
|
||||
aiosignal = ">=1.1.2"
|
||||
async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""}
|
||||
async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""}
|
||||
attrs = ">=17.3.0"
|
||||
frozenlist = ">=1.1.1"
|
||||
multidict = ">=4.5,<7.0"
|
||||
@@ -317,13 +317,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.4"
|
||||
version = "3.1.5"
|
||||
description = "A very fast and expressive template engine."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
|
||||
{file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
|
||||
{file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"},
|
||||
{file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1006,4 +1006,4 @@ propcache = ">=0.2.0"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.10,<3.13"
|
||||
content-hash = "81a35e932aea2fecab78f82f12cc8ab435cfcda5e1fe20acb42cb95542b4608f"
|
||||
content-hash = "3c9488709e61f3aa21ab47ceb9c677927ce770d8e1e327602a1a6afb09164475"
|
||||
|
||||
@@ -16,7 +16,7 @@ include = [
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.10,<3.13"
|
||||
|
||||
aiohttp = "^3.9.5"
|
||||
aiohttp = "^3.10.11"
|
||||
aiohttp-jinja2 = "^1.5.1"
|
||||
aiohttp-cors = "^0.7.0"
|
||||
watchdog = "^4"
|
||||
|
||||
@@ -11,45 +11,57 @@
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, poetry2nix }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
poetry2nix,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
p2n = (poetry2nix.lib.mkPoetry2Nix { inherit pkgs; });
|
||||
in {
|
||||
devShells.default = (p2n.mkPoetryEnv {
|
||||
projectDir = self + "/backend";
|
||||
# pyinstaller fails to compile so precompiled it is
|
||||
overrides = p2n.overrides.withDefaults (final: prev: {
|
||||
pyinstaller = prev.pyinstaller.override { preferWheel = true; };
|
||||
pyright = null;
|
||||
});
|
||||
}).env.overrideAttrs (oldAttrs: {
|
||||
shellHook = ''
|
||||
PYTHONPATH=`which python`
|
||||
FILE=.vscode/settings.json
|
||||
if [ -f "$FILE" ]; then
|
||||
jq --arg pythonpath "$PYTHONPATH" '.["python.defaultInterpreterPath"] = $pythonpath' $FILE > "$FILE.tmp" && mv "$FILE.tmp" "$FILE"
|
||||
else
|
||||
echo "{\"python.defaultInterpreterPath\": \"$PYTHONPATH\"}" > "$FILE"
|
||||
fi
|
||||
'';
|
||||
UV_USE_IO_URING = 0; # work around node#48444
|
||||
buildInputs = with pkgs; [
|
||||
nodejs_22
|
||||
nodePackages.pnpm
|
||||
poetry
|
||||
jq
|
||||
# fixes local pyright not being able to see the pythonpath properly.
|
||||
(pkgs.writeShellScriptBin "pyright" ''
|
||||
${pkgs.pyright}/bin/pyright --pythonpath `which python3` "$@" '')
|
||||
(pkgs.writeShellScriptBin "pyright-langserver" ''
|
||||
${pkgs.pyright}/bin/pyright-langserver --pythonpath `which python3` "$@" '')
|
||||
(pkgs.writeShellScriptBin "pyright-python" ''
|
||||
${pkgs.pyright}/bin/pyright-python --pythonpath `which python3` "$@" '')
|
||||
(pkgs.writeShellScriptBin "pyright-python-langserver" ''
|
||||
${pkgs.pyright}/bin/pyright-python-langserver --pythonpath `which python3` "$@" '')
|
||||
];
|
||||
});
|
||||
});
|
||||
in
|
||||
{
|
||||
devShells.default =
|
||||
(p2n.mkPoetryEnv {
|
||||
projectDir = self + "/backend";
|
||||
# pyinstaller fails to compile so precompiled it is
|
||||
overrides = p2n.overrides.withDefaults (
|
||||
final: prev: {
|
||||
pyinstaller = prev.pyinstaller.override { preferWheel = true; };
|
||||
pyright = null;
|
||||
}
|
||||
);
|
||||
}).env.overrideAttrs
|
||||
(oldAttrs: {
|
||||
shellHook = ''
|
||||
PYTHONPATH=`which python`
|
||||
FILE=.vscode/settings.json
|
||||
if [ -f "$FILE" ]; then
|
||||
jq --arg pythonpath "$PYTHONPATH" '.["python.defaultInterpreterPath"] = $pythonpath' $FILE > "$FILE.tmp" && mv "$FILE.tmp" "$FILE"
|
||||
else
|
||||
echo "{\"python.defaultInterpreterPath\": \"$PYTHONPATH\"}" > "$FILE"
|
||||
fi
|
||||
'';
|
||||
UV_USE_IO_URING = 0; # work around node#48444
|
||||
nativeBuildInputs = with pkgs; [
|
||||
python311Packages.setuptools
|
||||
];
|
||||
buildInputs = with pkgs; [
|
||||
nodejs_22
|
||||
nodePackages.pnpm
|
||||
poetry
|
||||
jq
|
||||
# fixes local pyright not being able to see the pythonpath properly.
|
||||
(pkgs.writeShellScriptBin "pyright" ''${pkgs.pyright}/bin/pyright --pythonpath `which python3` "$@" '')
|
||||
(pkgs.writeShellScriptBin "pyright-langserver" ''${pkgs.pyright}/bin/pyright-langserver --pythonpath `which python3` "$@" '')
|
||||
(pkgs.writeShellScriptBin "pyright-python" ''${pkgs.pyright}/bin/pyright-python --pythonpath `which python3` "$@" '')
|
||||
(pkgs.writeShellScriptBin "pyright-python-langserver" ''${pkgs.pyright}/bin/pyright-python-langserver --pythonpath `which python3` "$@" '')
|
||||
];
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@decky/ui": "^4.8.1",
|
||||
"@decky/ui": "^4.8.3",
|
||||
"compare-versions": "^6.1.1",
|
||||
"filesize": "^10.1.2",
|
||||
"i18next": "^23.11.5",
|
||||
|
||||
Generated
+9
-9
@@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@decky/ui':
|
||||
specifier: ^4.8.1
|
||||
version: 4.8.1
|
||||
specifier: ^4.8.3
|
||||
version: 4.8.3
|
||||
compare-versions:
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.1
|
||||
@@ -218,8 +218,8 @@ packages:
|
||||
'@decky/api@1.1.1':
|
||||
resolution: {integrity: sha512-R5fkBRHBt5QIQY7Q0AlbVIhlIZ/nTzwBOoi8Rt4Go2fjFnoMKPInCJl6cPjXzimGwl2pyqKJgY6VnH6ar0XrHQ==}
|
||||
|
||||
'@decky/ui@4.8.1':
|
||||
resolution: {integrity: sha512-lM4jdeyHjIbxHWxDBhbk+GQvdIT50p6RW9DC+oWSWXlaNWU/iG+8aUAcnfxygFkTP43EkCgjFASsYTfB55CMXA==}
|
||||
'@decky/ui@4.8.3':
|
||||
resolution: {integrity: sha512-Y1KciazgvKqMEVBGrWFCTGOqgVi5sHbcQNoCZRMbPpcI0U3j7udl6mkfe/NBa16oRDZ03ljS41SmrAgKAAt/pA==}
|
||||
|
||||
'@esbuild/aix-ppc64@0.20.2':
|
||||
resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
|
||||
@@ -870,8 +870,8 @@ packages:
|
||||
cross-fetch@4.0.0:
|
||||
resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==}
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
cross-spawn@7.0.6:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
css-select@5.1.0:
|
||||
@@ -2295,7 +2295,7 @@ snapshots:
|
||||
|
||||
'@decky/api@1.1.1': {}
|
||||
|
||||
'@decky/ui@4.8.1': {}
|
||||
'@decky/ui@4.8.3': {}
|
||||
|
||||
'@esbuild/aix-ppc64@0.20.2':
|
||||
optional: true
|
||||
@@ -2843,7 +2843,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
cross-spawn@7.0.6:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
shebang-command: 2.0.0
|
||||
@@ -3028,7 +3028,7 @@ snapshots:
|
||||
|
||||
foreground-child@3.2.0:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.3
|
||||
cross-spawn: 7.0.6
|
||||
signal-exit: 4.1.0
|
||||
|
||||
fs-extra@11.2.0:
|
||||
|
||||
@@ -128,9 +128,17 @@ interface DeckyStateContext extends PublicDeckyState {
|
||||
closeActivePlugin(): void;
|
||||
}
|
||||
|
||||
const DeckyStateContext = createContext<DeckyStateContext>(null as any);
|
||||
const DeckyStateContext = createContext<DeckyStateContext | null>(null);
|
||||
|
||||
export const useDeckyState = () => useContext(DeckyStateContext);
|
||||
export const useDeckyState = () => {
|
||||
const deckyState = useContext(DeckyStateContext);
|
||||
|
||||
if (deckyState === null) {
|
||||
throw new Error('useDeckyState needs a parent DeckyStateContext');
|
||||
}
|
||||
|
||||
return deckyState;
|
||||
};
|
||||
|
||||
interface Props {
|
||||
deckyState: DeckyState;
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
import { ButtonItem, ErrorBoundary, Focusable, PanelSection, PanelSectionRow } from '@decky/ui';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { FC, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaEyeSlash } from 'react-icons/fa';
|
||||
|
||||
import { Plugin } from '../plugin';
|
||||
import { useDeckyState } from './DeckyState';
|
||||
import NotificationBadge from './NotificationBadge';
|
||||
import { useQuickAccessVisible } from './QuickAccessVisibleState';
|
||||
import TitleView from './TitleView';
|
||||
|
||||
const PluginView: FC = () => {
|
||||
const { hiddenPlugins } = useDeckyState();
|
||||
const { plugins, updates, activePlugin, pluginOrder, setActivePlugin, closeActivePlugin } = useDeckyState();
|
||||
const { plugins, hiddenPlugins, updates, activePlugin, pluginOrder, setActivePlugin, closeActivePlugin } =
|
||||
useDeckyState();
|
||||
const visible = useQuickAccessVisible();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [pluginList, setPluginList] = useState<Plugin[]>(
|
||||
plugins.sort((a, b) => pluginOrder.indexOf(a.name) - pluginOrder.indexOf(b.name)),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setPluginList(plugins.sort((a, b) => pluginOrder.indexOf(a.name) - pluginOrder.indexOf(b.name)));
|
||||
const pluginList = useMemo(() => {
|
||||
console.log('updating PluginView after changes');
|
||||
|
||||
return [...plugins]
|
||||
.sort((a, b) => pluginOrder.indexOf(a.name) - pluginOrder.indexOf(b.name))
|
||||
.filter((p) => p.content)
|
||||
.filter(({ name }) => !hiddenPlugins.includes(name));
|
||||
}, [plugins, pluginOrder]);
|
||||
|
||||
if (activePlugin) {
|
||||
@@ -43,20 +42,17 @@ const PluginView: FC = () => {
|
||||
}}
|
||||
>
|
||||
<PanelSection>
|
||||
{pluginList
|
||||
.filter((p) => p.content)
|
||||
.filter(({ name }) => !hiddenPlugins.includes(name))
|
||||
.map(({ name, icon }) => (
|
||||
<PanelSectionRow key={name}>
|
||||
<ButtonItem layout="below" onClick={() => setActivePlugin(name)}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
{icon}
|
||||
<div>{name}</div>
|
||||
<NotificationBadge show={updates?.has(name)} style={{ top: '-5px', right: '-5px' }} />
|
||||
</div>
|
||||
</ButtonItem>
|
||||
</PanelSectionRow>
|
||||
))}
|
||||
{pluginList.map(({ name, icon }) => (
|
||||
<PanelSectionRow key={name}>
|
||||
<ButtonItem layout="below" onClick={() => setActivePlugin(name)}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
{icon}
|
||||
<div>{name}</div>
|
||||
<NotificationBadge show={updates?.has(name)} style={{ top: '-5px', right: '-5px' }} />
|
||||
</div>
|
||||
</ButtonItem>
|
||||
</PanelSectionRow>
|
||||
))}
|
||||
{hiddenPlugins.length > 0 && (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', fontSize: '0.8rem', marginTop: '10px' }}>
|
||||
<FaEyeSlash />
|
||||
|
||||
@@ -3,7 +3,7 @@ import { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaCheck, FaDownload } from 'react-icons/fa';
|
||||
|
||||
import { InstallType } from '../../plugin';
|
||||
import { InstallType, InstallTypeTranslationMapping } from '../../plugin';
|
||||
|
||||
interface MultiplePluginsInstallModalProps {
|
||||
requests: { name: string; version: string; hash: string; install_type: InstallType }[];
|
||||
@@ -12,13 +12,7 @@ interface MultiplePluginsInstallModalProps {
|
||||
closeModal?(): void;
|
||||
}
|
||||
|
||||
// values are the JSON keys used in the translation file
|
||||
const InstallTypeTranslationMapping = {
|
||||
[InstallType.INSTALL]: 'install',
|
||||
[InstallType.REINSTALL]: 'reinstall',
|
||||
[InstallType.UPDATE]: 'update',
|
||||
} as const satisfies Record<InstallType, string>;
|
||||
|
||||
// IMPORTANT! Keep in sync with `t(...)` comments below
|
||||
type TitleTranslationMapping = 'mixed' | (typeof InstallTypeTranslationMapping)[InstallType];
|
||||
|
||||
const MultiplePluginsInstallModal: FC<MultiplePluginsInstallModalProps> = ({
|
||||
@@ -70,6 +64,8 @@ const MultiplePluginsInstallModal: FC<MultiplePluginsInstallModalProps> = ({
|
||||
if (requests.every(({ install_type }) => install_type === InstallType.INSTALL)) return 'install';
|
||||
if (requests.every(({ install_type }) => install_type === InstallType.REINSTALL)) return 'reinstall';
|
||||
if (requests.every(({ install_type }) => install_type === InstallType.UPDATE)) return 'update';
|
||||
if (requests.every(({ install_type }) => install_type === InstallType.DOWNGRADE)) return 'downgrade';
|
||||
if (requests.every(({ install_type }) => install_type === InstallType.OVERWRITE)) return 'overwrite';
|
||||
return 'mixed';
|
||||
}, [requests]);
|
||||
|
||||
@@ -86,14 +82,35 @@ const MultiplePluginsInstallModal: FC<MultiplePluginsInstallModalProps> = ({
|
||||
onCancel={async () => {
|
||||
await onCancel();
|
||||
}}
|
||||
strTitle={<div>{t(`MultiplePluginsInstallModal.title.${installTypeGrouped}`, { count: requests.length })}</div>}
|
||||
strOKButtonText={t(`MultiplePluginsInstallModal.ok_button.${loading ? 'loading' : 'idle'}`)}
|
||||
strTitle={
|
||||
<div>
|
||||
{
|
||||
// IMPORTANT! These comments are not cosmetic and are needed for `extracttext` task to work
|
||||
// t('MultiplePluginsInstallModal.title.install', { count: n })
|
||||
// t('MultiplePluginsInstallModal.title.reinstall', { count: n })
|
||||
// t('MultiplePluginsInstallModal.title.update', { count: n })
|
||||
// t('MultiplePluginsInstallModal.title.downgrade', { count: n })
|
||||
// t('MultiplePluginsInstallModal.title.overwrite', { count: n })
|
||||
// t('MultiplePluginsInstallModal.title.mixed', { count: n })
|
||||
t(`MultiplePluginsInstallModal.title.${installTypeGrouped}`, { count: requests.length })
|
||||
}
|
||||
</div>
|
||||
}
|
||||
strOKButtonText={
|
||||
loading ? t('MultiplePluginsInstallModal.ok_button.loading') : t('MultiplePluginsInstallModal.ok_button.idle')
|
||||
}
|
||||
>
|
||||
<div>
|
||||
{t('MultiplePluginsInstallModal.confirm')}
|
||||
<ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: '4px' }}>
|
||||
{requests.map(({ name, version, install_type, hash }, i) => {
|
||||
const installTypeStr = InstallTypeTranslationMapping[install_type];
|
||||
// IMPORTANT! These comments are not cosmetic and are needed for `extracttext` task to work
|
||||
// t('MultiplePluginsInstallModal.description.install')
|
||||
// t('MultiplePluginsInstallModal.description.reinstall')
|
||||
// t('MultiplePluginsInstallModal.description.update')
|
||||
// t('MultiplePluginsInstallModal.description.downgrade')
|
||||
// t('MultiplePluginsInstallModal.description.overwrite')
|
||||
const description = t(`MultiplePluginsInstallModal.description.${installTypeStr}`, {
|
||||
name,
|
||||
version,
|
||||
|
||||
@@ -2,13 +2,13 @@ import { ConfirmModal, Navigation, ProgressBarWithInfo, QuickAccessTab } from '@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import TranslationHelper, { TranslationClass } from '../../utils/TranslationHelper';
|
||||
import { InstallType, InstallTypeTranslationMapping } from '../../plugin';
|
||||
|
||||
interface PluginInstallModalProps {
|
||||
artifact: string;
|
||||
version: string;
|
||||
hash: string;
|
||||
installType: number;
|
||||
installType: InstallType;
|
||||
onOK(): void;
|
||||
onCancel(): void;
|
||||
closeModal?(): void;
|
||||
@@ -44,6 +44,8 @@ const PluginInstallModal: FC<PluginInstallModalProps> = ({
|
||||
};
|
||||
}, []);
|
||||
|
||||
const installTypeTranslationKey = InstallTypeTranslationMapping[installType];
|
||||
|
||||
return (
|
||||
<ConfirmModal
|
||||
bOKDisabled={loading}
|
||||
@@ -59,12 +61,15 @@ const PluginInstallModal: FC<PluginInstallModalProps> = ({
|
||||
}}
|
||||
strTitle={
|
||||
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', width: '100%' }}>
|
||||
<TranslationHelper
|
||||
transClass={TranslationClass.PLUGIN_INSTALL_MODAL}
|
||||
transText="title"
|
||||
i18nArgs={{ artifact: artifact }}
|
||||
installType={installType}
|
||||
/>
|
||||
{
|
||||
// IMPORTANT! These comments are not cosmetic and are needed for `extracttext` task to work
|
||||
// t('PluginInstallModal.install.title')
|
||||
// t('PluginInstallModal.reinstall.title')
|
||||
// t('PluginInstallModal.update.title')
|
||||
// t('PluginInstallModal.downgrade.title')
|
||||
// t('PluginInstallModal.overwrite.title')
|
||||
t(`PluginInstallModal.${installTypeTranslationKey}.title`, { artifact: artifact })
|
||||
}
|
||||
{loading && (
|
||||
<div style={{ marginLeft: 'auto' }}>
|
||||
<ProgressBarWithInfo
|
||||
@@ -80,33 +85,44 @@ const PluginInstallModal: FC<PluginInstallModalProps> = ({
|
||||
strOKButtonText={
|
||||
loading ? (
|
||||
<div>
|
||||
<TranslationHelper
|
||||
transClass={TranslationClass.PLUGIN_INSTALL_MODAL}
|
||||
transText="button_processing"
|
||||
installType={installType}
|
||||
/>
|
||||
{
|
||||
// IMPORTANT! These comments are not cosmetic and are needed for `extracttext` task to work
|
||||
// t('PluginInstallModal.install.button_processing')
|
||||
// t('PluginInstallModal.reinstall.button_processing')
|
||||
// t('PluginInstallModal.update.button_processing')
|
||||
// t('PluginInstallModal.downgrade.button_processing')
|
||||
// t('PluginInstallModal.overwrite.button_processing')
|
||||
t(`PluginInstallModal.${installTypeTranslationKey}.button_processing`)
|
||||
}
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<TranslationHelper
|
||||
transClass={TranslationClass.PLUGIN_INSTALL_MODAL}
|
||||
transText="button_idle"
|
||||
installType={installType}
|
||||
/>
|
||||
{
|
||||
// IMPORTANT! These comments are not cosmetic and are needed for `extracttext` task to work
|
||||
// t('PluginInstallModal.install.button_idle')
|
||||
// t('PluginInstallModal.reinstall.button_idle')
|
||||
// t('PluginInstallModal.update.button_idle')
|
||||
// t('PluginInstallModal.downgrade.button_idle')
|
||||
// t('PluginInstallModal.overwrite.button_idle')
|
||||
t(`PluginInstallModal.${installTypeTranslationKey}.button_idle`)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<TranslationHelper
|
||||
transClass={TranslationClass.PLUGIN_INSTALL_MODAL}
|
||||
transText="desc"
|
||||
i18nArgs={{
|
||||
{
|
||||
// IMPORTANT! These comments are not cosmetic and are needed for `extracttext` task to work
|
||||
// t('PluginInstallModal.install.desc')
|
||||
// t('PluginInstallModal.reinstall.desc')
|
||||
// t('PluginInstallModal.update.desc')
|
||||
// t('PluginInstallModal.downgrade.desc')
|
||||
// t('PluginInstallModal.overwrite.desc')
|
||||
t(`PluginInstallModal.${installTypeTranslationKey}.desc`, {
|
||||
artifact: artifact,
|
||||
version: version,
|
||||
}}
|
||||
installType={installType}
|
||||
/>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
{hash == 'False' && <span style={{ color: 'red' }}>{t('PluginInstallModal.no_hash')}</span>}
|
||||
</ConfirmModal>
|
||||
|
||||
@@ -1,18 +1,32 @@
|
||||
import { ButtonItem, Dropdown, Focusable, PanelSectionRow, SingleDropdownOption, SuspensefulImage } from '@decky/ui';
|
||||
import { CSSProperties, FC, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaArrowDown, FaArrowUp, FaCheck, FaDownload, FaRecycle } from 'react-icons/fa';
|
||||
|
||||
import { InstallType } from '../../plugin';
|
||||
import { StorePlugin, StorePluginVersion, requestPluginInstall } from '../../store';
|
||||
import { InstallType, Plugin } from '../../plugin';
|
||||
import { StorePlugin, requestPluginInstall } from '../../store';
|
||||
import ExternalLink from '../ExternalLink';
|
||||
|
||||
interface PluginCardProps {
|
||||
plugin: StorePlugin;
|
||||
storePlugin: StorePlugin;
|
||||
installedPlugin: Plugin | undefined;
|
||||
}
|
||||
|
||||
const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
|
||||
const PluginCard: FC<PluginCardProps> = ({ storePlugin, installedPlugin }) => {
|
||||
const [selectedOption, setSelectedOption] = useState<number>(0);
|
||||
const root = plugin.tags.some((tag) => tag === 'root');
|
||||
const installedVersionIndex = storePlugin.versions.findIndex((version) => version.name === installedPlugin?.version);
|
||||
const installType = // This assumes index in options is inverse to update order (i.e. newer updates are first)
|
||||
installedPlugin && selectedOption < installedVersionIndex
|
||||
? InstallType.UPDATE
|
||||
: installedPlugin && selectedOption === installedVersionIndex
|
||||
? InstallType.REINSTALL
|
||||
: installedPlugin && selectedOption > installedVersionIndex
|
||||
? InstallType.DOWNGRADE
|
||||
: installedPlugin // can happen if installed version is not in store
|
||||
? InstallType.OVERWRITE
|
||||
: InstallType.INSTALL;
|
||||
|
||||
const root = storePlugin.tags.some((tag) => tag === 'root');
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -43,7 +57,7 @@ const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
|
||||
height: '200px',
|
||||
objectFit: 'cover',
|
||||
}}
|
||||
src={plugin.image_url}
|
||||
src={storePlugin.image_url}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
@@ -69,7 +83,7 @@ const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
|
||||
width: '90%',
|
||||
}}
|
||||
>
|
||||
{plugin.name}
|
||||
{storePlugin.name}
|
||||
</span>
|
||||
<span
|
||||
className="deckyStoreCardAuthor"
|
||||
@@ -78,7 +92,7 @@ const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
|
||||
fontSize: '1em',
|
||||
}}
|
||||
>
|
||||
{plugin.author}
|
||||
{storePlugin.author}
|
||||
</span>
|
||||
<span
|
||||
className="deckyStoreCardDescription"
|
||||
@@ -91,8 +105,8 @@ const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
|
||||
display: '-webkit-box',
|
||||
}}
|
||||
>
|
||||
{plugin.description ? (
|
||||
plugin.description
|
||||
{storePlugin.description ? (
|
||||
storePlugin.description
|
||||
) : (
|
||||
<span>
|
||||
<i style={{ color: '#666' }}>{t('PluginCard.plugin_no_desc')}</i>
|
||||
@@ -141,18 +155,49 @@ const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
|
||||
bottomSeparator="none"
|
||||
layout="below"
|
||||
onClick={() =>
|
||||
requestPluginInstall(plugin.name, plugin.versions[selectedOption], InstallType.INSTALL)
|
||||
requestPluginInstall(storePlugin.name, storePlugin.versions[selectedOption], installType)
|
||||
}
|
||||
>
|
||||
<span className="deckyStoreCardInstallText">{t('PluginCard.plugin_install')}</span>
|
||||
<span
|
||||
className="deckyStoreCardInstallText"
|
||||
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '5px' }}
|
||||
>
|
||||
{installType === InstallType.UPDATE ? (
|
||||
<>
|
||||
<FaArrowUp /> {t('PluginCard.plugin_update')}
|
||||
</>
|
||||
) : installType === InstallType.REINSTALL ? (
|
||||
<>
|
||||
<FaRecycle /> {t('PluginCard.plugin_reinstall')}
|
||||
</>
|
||||
) : installType === InstallType.DOWNGRADE ? (
|
||||
<>
|
||||
<FaArrowDown /> {t('PluginCard.plugin_downgrade')}
|
||||
</>
|
||||
) : installType === InstallType.OVERWRITE ? (
|
||||
<>
|
||||
<FaDownload /> {t('PluginCard.plugin_overwrite')}
|
||||
</>
|
||||
) : (
|
||||
// installType === InstallType.INSTALL (also fallback)
|
||||
<>
|
||||
<FaDownload /> {t('PluginCard.plugin_install')}
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
</ButtonItem>
|
||||
</div>
|
||||
<div className="deckyStoreCardVersionContainer" style={{ minWidth: '130px' }}>
|
||||
<Dropdown
|
||||
rgOptions={
|
||||
plugin.versions.map((version: StorePluginVersion, index) => ({
|
||||
storePlugin.versions.map((version, index) => ({
|
||||
data: index,
|
||||
label: version.name,
|
||||
label: (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
|
||||
{version.name}
|
||||
{installedPlugin && installedVersionIndex === index ? <FaCheck /> : null}
|
||||
</div>
|
||||
),
|
||||
})) as SingleDropdownOption[]
|
||||
}
|
||||
menuLabel={t('PluginCard.plugin_version_label') as string}
|
||||
|
||||
@@ -14,6 +14,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import logo from '../../../assets/plugin_store.png';
|
||||
import Logger from '../../logger';
|
||||
import { SortDirections, SortOptions, Store, StorePlugin, getPluginList, getStore } from '../../store';
|
||||
import { useDeckyState } from '../DeckyState';
|
||||
import ExternalLink from '../ExternalLink';
|
||||
import PluginCard from './PluginCard';
|
||||
|
||||
@@ -104,6 +105,8 @@ const BrowseTab: FC<{ setPluginCount: Dispatch<SetStateAction<number | null>> }>
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const { plugins: installedPlugins } = useDeckyState();
|
||||
|
||||
return (
|
||||
<>
|
||||
<style>{`
|
||||
@@ -235,7 +238,12 @@ const BrowseTab: FC<{ setPluginCount: Dispatch<SetStateAction<number | null>> }>
|
||||
plugin.tags.some((tag: string) => tag.toLowerCase().includes(searchFieldValue.toLowerCase()))
|
||||
);
|
||||
})
|
||||
.map((plugin: StorePlugin) => <PluginCard plugin={plugin} />)
|
||||
.map((plugin: StorePlugin) => (
|
||||
<PluginCard
|
||||
storePlugin={plugin}
|
||||
installedPlugin={installedPlugins.find((installedPlugin) => installedPlugin.name === plugin.name)}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -79,9 +79,17 @@ class ErrorBoundaryHook extends Logger {
|
||||
this.setState(stateClone);
|
||||
return null;
|
||||
}
|
||||
if (this.state.error) {
|
||||
// yoinked from valve error boundary
|
||||
if (this.state.error && this.props.errorKey == this.state.lastErrorKey) {
|
||||
const store = Object.getPrototypeOf(this)?.constructor?.sm_ErrorReportingStore || errorReportingStore;
|
||||
return (
|
||||
|
||||
return void 0 !== this.props.fallback ? (
|
||||
'function' == typeof this.props.fallback ? (
|
||||
this.props.fallback(this.state.error.error)
|
||||
) : (
|
||||
this.props.fallback
|
||||
)
|
||||
) : (
|
||||
<DeckyErrorBoundary
|
||||
error={this.state.error}
|
||||
errorKey={this.props.errorKey}
|
||||
|
||||
@@ -146,9 +146,11 @@ class PluginLoader extends Logger {
|
||||
});
|
||||
|
||||
this.routerHook.addRoute('/decky/store', () => (
|
||||
<WithSuspense route={true}>
|
||||
<StorePage />
|
||||
</WithSuspense>
|
||||
<DeckyStateContextProvider deckyState={this.deckyState}>
|
||||
<WithSuspense route={true}>
|
||||
<StorePage />
|
||||
</WithSuspense>
|
||||
</DeckyStateContextProvider>
|
||||
));
|
||||
this.routerHook.addRoute('/decky/settings', () => {
|
||||
return (
|
||||
|
||||
@@ -18,8 +18,20 @@ export enum InstallType {
|
||||
INSTALL,
|
||||
REINSTALL,
|
||||
UPDATE,
|
||||
DOWNGRADE,
|
||||
OVERWRITE,
|
||||
}
|
||||
|
||||
// values are the JSON keys used in the translation file
|
||||
// IMPORTANT! keep in sync with `t(...)` comments where this is used
|
||||
export const InstallTypeTranslationMapping = {
|
||||
[InstallType.INSTALL]: 'install',
|
||||
[InstallType.REINSTALL]: 'reinstall',
|
||||
[InstallType.UPDATE]: 'update',
|
||||
[InstallType.DOWNGRADE]: 'downgrade',
|
||||
[InstallType.OVERWRITE]: 'overwrite',
|
||||
} as const satisfies Record<InstallType, string>;
|
||||
|
||||
type installPluginArgs = [
|
||||
artifact: string,
|
||||
name?: string,
|
||||
|
||||
@@ -68,27 +68,6 @@ export async function getPluginList(
|
||||
await setSetting('store', Store.Default);
|
||||
store = Store.Default;
|
||||
}
|
||||
switch (+store) {
|
||||
case Store.Default:
|
||||
storeURL = 'https://plugins.deckbrew.xyz/plugins';
|
||||
break;
|
||||
case Store.Testing:
|
||||
storeURL = 'https://testing.deckbrew.xyz/plugins';
|
||||
break;
|
||||
case Store.Custom:
|
||||
storeURL = customURL;
|
||||
break;
|
||||
default:
|
||||
console.error('Somehow you ended up without a standard URL, using the default URL.');
|
||||
storeURL = 'https://plugins.deckbrew.xyz/plugins';
|
||||
break;
|
||||
return fetch(storeURL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'X-Decky-Version': version.current,
|
||||
},
|
||||
}).then((r) => r.json());
|
||||
}
|
||||
switch (+store) {
|
||||
case Store.Default:
|
||||
storeURL = 'https://plugins.deckbrew.xyz/plugins';
|
||||
|
||||
@@ -2,11 +2,9 @@ import { FC } from 'react';
|
||||
import { Translation } from 'react-i18next';
|
||||
|
||||
import Logger from '../logger';
|
||||
import { InstallType } from '../plugin';
|
||||
|
||||
export enum TranslationClass {
|
||||
PLUGIN_LOADER = 'PluginLoader',
|
||||
PLUGIN_INSTALL_MODAL = 'PluginInstallModal',
|
||||
DEVELOPER = 'Developer',
|
||||
}
|
||||
|
||||
@@ -19,7 +17,7 @@ interface TranslationHelperProps {
|
||||
|
||||
const logger = new Logger('TranslationHelper');
|
||||
|
||||
const TranslationHelper: FC<TranslationHelperProps> = ({ transClass, transText, i18nArgs = null, installType = 0 }) => {
|
||||
const TranslationHelper: FC<TranslationHelperProps> = ({ transClass, transText, i18nArgs = null }) => {
|
||||
return (
|
||||
<Translation>
|
||||
{(t, {}) => {
|
||||
@@ -28,21 +26,6 @@ const TranslationHelper: FC<TranslationHelperProps> = ({ transClass, transText,
|
||||
return i18nArgs
|
||||
? t(TranslationClass.PLUGIN_LOADER + '.' + transText, i18nArgs)
|
||||
: t(TranslationClass.PLUGIN_LOADER + '.' + transText);
|
||||
case TranslationClass.PLUGIN_INSTALL_MODAL:
|
||||
switch (installType) {
|
||||
case InstallType.INSTALL:
|
||||
return i18nArgs
|
||||
? t(TranslationClass.PLUGIN_INSTALL_MODAL + '.install.' + transText, i18nArgs)
|
||||
: t(TranslationClass.PLUGIN_INSTALL_MODAL + '.install.' + transText);
|
||||
case InstallType.REINSTALL:
|
||||
return i18nArgs
|
||||
? t(TranslationClass.PLUGIN_INSTALL_MODAL + '.reinstall.' + transText, i18nArgs)
|
||||
: t(TranslationClass.PLUGIN_INSTALL_MODAL + '.reinstall.' + transText);
|
||||
case InstallType.UPDATE:
|
||||
return i18nArgs
|
||||
? t(TranslationClass.PLUGIN_INSTALL_MODAL + '.update.' + transText, i18nArgs)
|
||||
: t(TranslationClass.PLUGIN_INSTALL_MODAL + '.update.' + transText);
|
||||
}
|
||||
case TranslationClass.DEVELOPER:
|
||||
return i18nArgs
|
||||
? t(TranslationClass.DEVELOPER + '.' + transText, i18nArgs)
|
||||
|
||||
Reference in New Issue
Block a user