diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..1d21b2f
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,26 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "lldb",
+ "request": "launch",
+ "name": "Debug",
+ "cargo": {
+ "args": [
+ "build",
+ "--bin=anime-game-launcher",
+ "--package=anime-game-launcher"
+ ],
+ "filter": {
+ "name": "anime-game-launcher",
+ "kind": "bin"
+ }
+ },
+ "args": [],
+ "cwd": "${workspaceFolder}"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9a05611..374b6d2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+- Added rules approving dialog to the first run window
+- Added game settings section
+- Added game sessions manager
+- Added `LAUNCHER_FOLDER` variable support.
+ Using this you can specify root path where the launcher stores `config.json` and other files
+- Added patch repository mirror
+
+### Changed
+
+- Improved launcher logo rendering quality
+- Reworked entry rows in the settings
+
+### Fixed
+
+- Fixed wine tools running using proton builds
+- Fixed sandboxed game running (sounds are broken for now)
+
+## [3.5.2] - 17.04.2023
+
+### Added
+
- Added arguments and symlinks editor to sandbox settings
### Fixed
@@ -203,7 +224,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
-[unreleased]: https://github.com/an-anime-team/an-anime-game-launcher/compare/3.5.1...next
+[unreleased]: https://github.com/an-anime-team/an-anime-game-launcher/compare/3.5.2...next
+[3.5.2]: https://github.com/an-anime-team/an-anime-game-launcher/compare/3.5.1...3.5.2
[3.5.1]: https://github.com/an-anime-team/an-anime-game-launcher/compare/3.5.0...3.5.1
[3.5.0]: https://github.com/an-anime-team/an-anime-game-launcher/compare/3.4.1...3.5.0
[3.4.1]: https://github.com/an-anime-team/an-anime-game-launcher/compare/3.4.0...3.4.1
diff --git a/Cargo.lock b/Cargo.lock
index 7d51a4c..565254a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -40,8 +40,8 @@ dependencies = [
[[package]]
name = "anime-game-core"
-version = "1.7.1"
-source = "git+https://github.com/an-anime-team/anime-game-core?tag=1.7.1#8978728ce5d94aec5c6aecfe470e45fc43d5b522"
+version = "1.8.0"
+source = "git+https://github.com/an-anime-team/anime-game-core?tag=1.8.0#dbb9008bcdd6a7b8026567ff35417671a77c740e"
dependencies = [
"anyhow",
"bzip2",
@@ -65,7 +65,7 @@ dependencies = [
[[package]]
name = "anime-game-launcher"
-version = "3.5.2"
+version = "3.6.0"
dependencies = [
"anime-launcher-sdk",
"anyhow",
@@ -87,8 +87,8 @@ dependencies = [
[[package]]
name = "anime-launcher-sdk"
-version = "1.0.6"
-source = "git+https://github.com/an-anime-team/anime-launcher-sdk?tag=1.0.6#2a8272c1afdd006925c150ac480a82be645f4b52"
+version = "1.2.1"
+source = "git+https://github.com/an-anime-team/anime-launcher-sdk?tag=1.2.1#f7bddd1d2fde4dcc7d04bda9e4d9160a5bc88218"
dependencies = [
"anime-game-core",
"anyhow",
@@ -2065,9 +2065,9 @@ checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "relm4"
-version = "0.6.0-alpha.2"
+version = "0.6.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7acc5e3ddd682eeb0ca33da36b821fc907017c6d7758b09ce280247b0b0ea8cd"
+checksum = "f169f698ce2e487eed2306898fcf262224a287d0e81480db4190e74cfec412cf"
dependencies = [
"async-trait",
"flume",
@@ -2083,9 +2083,9 @@ dependencies = [
[[package]]
name = "relm4-macros"
-version = "0.6.0-alpha.2"
+version = "0.6.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8525ce12dcd7d2a9e9070d84b8b885600eccd0a143df6712ce34a87d001a8b7"
+checksum = "7fa06febb3685960e7c1c44e21e44a3829325940b31d1e91391a43c32020c201"
dependencies = [
"proc-macro2",
"quote",
diff --git a/Cargo.toml b/Cargo.toml
index 61d37f4..005f69c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "anime-game-launcher"
-version = "3.5.2"
+version = "3.6.0"
description = "Anime Game launcher"
authors = ["Nikita Podvirnyy "]
license = "GPL-3.0"
@@ -17,13 +17,13 @@ glib-build-tools = "0.17"
[dependencies.anime-launcher-sdk]
git = "https://github.com/an-anime-team/anime-launcher-sdk"
-tag = "1.0.6"
+tag = "1.2.1"
features = ["all", "genshin"]
# path = "../anime-launcher-sdk" # ! for dev purposes only
[dependencies]
-relm4 = { version = "0.6.0-alpha.2", features = ["macros", "libadwaita"] }
+relm4 = { version = "0.6.0-beta.1", features = ["macros", "libadwaita"] }
gtk = { package = "gtk4", version = "0.6", features = ["v4_8"] }
adw = { package = "libadwaita", version = "0.3", features = ["v1_2"] }
diff --git a/README.md b/README.md
index f7e36fd..a09084f 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,8 @@ instead of the actual name of the game, to avoid search engine parsing.
To see the installation guides, please visit the wiki page [here](https://github.com/an-anime-team/an-anime-game-launcher/wiki/Installation)
+Lutris integration described [here](https://github.com/an-anime-team/an-anime-game-launcher/wiki/Installation#-lutris)
+
## Chinese version support
This should be automatically enabled if you're using zh_cn (Chinese) as your system language. If you're not using it - you can change the game edition in the launcher settings
diff --git a/assets/locales/common.ftl b/assets/locales/common.ftl
index f02c290..f1cb86e 100644
--- a/assets/locales/common.ftl
+++ b/assets/locales/common.ftl
@@ -19,5 +19,5 @@ ru-ru = Русский
de-de = Deutsch
es-es = Español
fr-fr = Français
-tr-tr = Türk
+tr-tr = Türkçe
zh-cn = 简体中文
diff --git a/assets/locales/de/errors.ftl b/assets/locales/de/errors.ftl
index 89ae284..e868165 100644
--- a/assets/locales/de/errors.ftl
+++ b/assets/locales/de/errors.ftl
@@ -6,7 +6,7 @@ debug-file-opening-error = Debug-Datei konnte nicht geöffnet werden
wish-url-search-failed = Kein Wünsche URL gefunden
wish-url-opening-error = Wünsche URL konnte nicht geöffnet werden
-wine-run-error = Failed to run {$executable} executable using wine
+wine-run-error = Ausführung von {$executable} mit wine fehlgeschlagen
game-launching-failed = Spiel konnte nicht gestartet werden
failed-get-selected-wine = Die ausgewählte Wine version konnte nicht abgerufen werden.
@@ -44,4 +44,12 @@ game-patching-error = Spiel konnte nicht gepatcht werden
# Sandbox
-documentation-url-open-failed = Failed to open documentation URL
+documentation-url-open-failed = Dokumentations-URL kann nicht geöffnet werden
+
+# Game
+
+game-session-add-failed = Spielsitzung konnte nicht hinzugefügt werden
+game-session-update-failed = Spielsitzung konnte nicht aktualisiert werden
+game-session-remove-failed = Spielsitzung konnte nicht entfernt werden
+game-session-set-current-failed = Aktuelle Spielsitzung konnte nicht eingestellt werden
+game-session-apply-failed = Spielsitzung konnte nicht angewendet werden
diff --git a/assets/locales/de/first_run.ftl b/assets/locales/de/first_run.ftl
index d82bd1f..f304f3d 100644
--- a/assets/locales/de/first_run.ftl
+++ b/assets/locales/de/first_run.ftl
@@ -21,8 +21,13 @@ tos-violation-warning-message =
Sollte dies der Fall sein, würde Ihr Konto gegen die TOS verstoßen, {company-name}/{company-alter-name} sind frei zu tun, was sie wollen. Inklusive Ban.
- Wenn Sie sich des Risikos bewusst sind, das mit dem Versuch, das Spiel inoffiziell zu spielen, verbunden ist, drücken Sie auf OK und lassen Sie uns die Welt von Teyvat erforschen!
+ Wenn Sie sich über das Risiko bewusst sind das mit dem versuchen des Spiels spielen in inoffizieller Weise verbunden ist dann drücken Sie OK um fortzufahren.
+tos-dialog-title = Sind Sie sicher, dass Sie verstehen, was wir sagen?
+tos-dialog-message =
+ 1. Veröffentlichen Sie keine Informationen über dieses Projekt
+ 2. Missbrauchen Sie es nicht durch die Verwendung von Mods
+ 3. Stellen Sie Fragen nur in unserem Discord oder auf dem Matrix-Server
dependencies = Abhängigkeiten
missing-dependencies-title = Sie vermissen einige Abhängigkeiten!
@@ -36,14 +41,14 @@ show-all-folders-subtitle = Zusätzliche Pfadauswahl-Einstellungen anzeigen. Tu
runners-folder = Runners-Ordner
dxvks-folder = DXVKs-Ordner
wine-prefix-folder = Wine prefix-Ordner
-global-game-installation-folder = Global game version installation folder
-chinese-game-installation-folder = Chinese game version installation folder
+global-game-installation-folder = Installationsordner der globalen Spielversion
+chinese-game-installation-folder = Installationsordner der chinesischen Spielversion
fps-unlocker-folder = FPS Unlocker Ordner
components-index = Komponentenverzeichnis
patch-folder = Patch-Ordner
temp-folder = Temp-Ordner
-migrate = Migrate
+migrate = Migrieren
select-voice-packages = Sprachpakete auswählen
diff --git a/assets/locales/de/game.ftl b/assets/locales/de/game.ftl
new file mode 100644
index 0000000..9ed52df
--- /dev/null
+++ b/assets/locales/de/game.ftl
@@ -0,0 +1,7 @@
+game-sessions = Spielsitzungen
+
+active-sessions = Aktive Sitzung
+active-session-description = Derzeit ausgewählte Spielsitzung. Aktualisiert nach jedem Spielstart
+
+update-session = Sitzung mit aktuellen Wine prefix Registrierungswerten aktualisieren
+delete-session = Sitzung löschen
diff --git a/assets/locales/de/general.ftl b/assets/locales/de/general.ftl
index f329d3b..be93eb4 100644
--- a/assets/locales/de/general.ftl
+++ b/assets/locales/de/general.ftl
@@ -7,22 +7,22 @@ update-background-description = Lädt das offizielle Hintergrundbild herunter f
launcher-language = Launcher Sprache
launcher-language-description = Gilt nach Neustart
-game-edition = Game edition
+game-edition = Spiel-Edition
global = Global
china = China
-game-environment = Game environment
-game-environment-description = Get specific features like additional payment methods
+game-environment = Spielumgebung
+game-environment-description = Spezielle Funktionen wie zusätzliche Zahlungsmöglichkeiten
game-voiceovers = Spiel Sprachen
-game-voiceovers-description = List of downloaded game voiceovers. You can select them in the game settings
+game-voiceovers-description = Liste der heruntergeladenen Sprachausgabe für das Spiel. Sie können diese in den Spieleinstellungen auswählen
english = Englisch
japanese = Japanisch
korean = Koreanisch
chinese = Chinesisch
-migrate-installation = Migrate installation
-migrate-installation-description = Open special window where you can change your game installation folder
+migrate-installation = Installation migrieren
+migrate-installation-description = Öffnet ein spezielles Fenster, in dem Sie den Installationsordner Ihres Spiels ändern können
repair-game = Spiel Reparieren
status = Status
@@ -64,11 +64,11 @@ wine-version = Wine version
wine-recommended-description = Nur empfohlene wine versionen anzeigen
wine-tools = Wine tools
-command-line = Command line
-registry-editor = Registry editor
+command-line = Befehlszeile
+registry-editor = Registrierungs-Editor
explorer = Explorer
task-manager = Task manager
-configuration = Configuration
+configuration = Konfiguration
debugger = Debugger
dxvk-version = DXVK version
diff --git a/assets/locales/de/main.ftl b/assets/locales/de/main.ftl
index e2c9a86..a337589 100644
--- a/assets/locales/de/main.ftl
+++ b/assets/locales/de/main.ftl
@@ -22,6 +22,7 @@ continue = Weiter
exit = Beenden
check = Überprüfen
restart = Neustarten
+agree = Einverstanden
loading-data = Laden Daten
@@ -49,8 +50,8 @@ components-index-updated = Kompontentenverzeichnis würde aktualisiert
launch = Starten
-migrate-folders = Migrate folders
-migrate-folders-tooltip = Update game folders structure
+migrate-folders = Ordner migrieren
+migrate-folders-tooltip = Spielordnerstruktur aktualisieren
apply-patch = Patch anwenden
download-wine = Wine Herunterladen
create-prefix = Prefix erstellen
diff --git a/assets/locales/de/sandbox.ftl b/assets/locales/de/sandbox.ftl
index de61f49..67cc377 100644
--- a/assets/locales/de/sandbox.ftl
+++ b/assets/locales/de/sandbox.ftl
@@ -1,28 +1,28 @@
sandbox = Sandbox
-sandbox-description = Run the game in isolated environment, preventing it from accessing your personal data
+sandbox-description = Führen Sie das Spiel in einer isolierten Umgebung aus, damit es nicht auf Ihre persönlichen Daten zugreifen kann.
-enable-sandboxing = Enable sandboxing
-enable-sandboxing-description = Run the game in read-only copy of your root filesystem
+enable-sandboxing = Sandboxing aktivieren
+enable-sandboxing-description = Starten Sie das Spiel in einer schreibgeschützten Kopie Ihres Root-Dateisystems
-hide-home-directory = Hide home directory
-hide-home-directory-description = Isolate your /home, /var/home/$USER, and $HOME folders from the game
+hide-home-directory = Home-Verzeichnis ausblenden
+hide-home-directory-description = Isolieren Sie Ihre Ordner /home, /var/home/$USER und $HOME vom Spiel
hostname = Hostname
-additional-arguments = Additional arguments
+additional-arguments = Zusätzliche Argumente
-private-directories = Private directories
-private-directories-description = These folders will be replaced by an empty virtual filesystem (tmpfs), and their original content will not be available to sandboxed game
+private-directories = Private Verzeichnisse
+private-directories-description = Diese Ordner werden durch ein leeres virtuelles Dateisystem (tmpfs) ersetzt, und ihr ursprünglicher Inhalt ist für das Spiel in der Sandbox nicht verfügbar.
-path = Path
+path = Pfad
-shared-directories = Shared directories
-shared-directories-description = These directories will be symlinked to directories in your host system
+shared-directories = Geteilte Verzeichnisse
+shared-directories-description = Diese Verzeichnisse werden mit Verzeichnissen in Ihrem Host-System verlinkt
-original-path = Original path
-new-path = New path
+original-path = Ursprünglicher Pfad
+new-path = Neuer Pfad
-read-only = Read-only
-read-only-description = Forbid game to write any data to this directory
+read-only = Schreibgeschützt
+read-only-description = Dem Spiel verbieten, Daten in dieses Verzeichnis zu schreiben
symlinks = Symlinks
-symlinks-description = Symlink original path to the new one inside of your sandbox
+symlinks-description = Verknüpfen Sie den ursprünglichen Pfad mit dem neuen Pfad innerhalb Ihrer Sandbox
diff --git a/assets/locales/en/errors.ftl b/assets/locales/en/errors.ftl
index f790d04..04ef2b2 100644
--- a/assets/locales/en/errors.ftl
+++ b/assets/locales/en/errors.ftl
@@ -45,3 +45,11 @@ game-patching-error = Failed to patch game
# Sandbox
documentation-url-open-failed = Failed to open documentation URL
+
+# Game
+
+game-session-add-failed = Failed to add game session
+game-session-update-failed = Failed to update game session
+game-session-remove-failed = Failed to remove game session
+game-session-set-current-failed = Failed to set current game session
+game-session-apply-failed = Failed to apply game session
diff --git a/assets/locales/en/first_run.ftl b/assets/locales/en/first_run.ftl
index 9ab26c6..23b5a30 100644
--- a/assets/locales/en/first_run.ftl
+++ b/assets/locales/en/first_run.ftl
@@ -21,7 +21,13 @@ tos-violation-warning-message =
If this happens, as your account would be disobeying TOS, {company-name}/{company-alter-name} are free to do what they want. Including banning.
- If you understand the risk of trying to play the game in an unofficial capacity, press OK and let's go researching the world of Teyvat!
+ If you understand the risk of trying to play the game in an unofficial capacity, press OK to continue
+
+tos-dialog-title = Are you sure you understand what we want to say?
+tos-dialog-message =
+ 1. Don't publish any information about this project
+ 2. Don't abuse it by using some modded clients and so
+ 3. Ask questions exceptionally in our discord or matrix server
dependencies = Dependencies
diff --git a/assets/locales/en/game.ftl b/assets/locales/en/game.ftl
new file mode 100644
index 0000000..bdd098a
--- /dev/null
+++ b/assets/locales/en/game.ftl
@@ -0,0 +1,7 @@
+game-sessions = Game sessions
+
+active-sessions = Active session
+active-session-description = Currently selected game session. Updates after each game launch
+
+update-session = Update session using current wine prefix registry values
+delete-session = Delete session
diff --git a/assets/locales/en/main.ftl b/assets/locales/en/main.ftl
index f36da46..f448ac1 100644
--- a/assets/locales/en/main.ftl
+++ b/assets/locales/en/main.ftl
@@ -22,6 +22,7 @@ continue = Continue
exit = Exit
check = Check
restart = Restart
+agree = Agree
loading-data = Loading data
diff --git a/assets/locales/es/errors.ftl b/assets/locales/es/errors.ftl
index a8369ba..435d988 100755
--- a/assets/locales/es/errors.ftl
+++ b/assets/locales/es/errors.ftl
@@ -45,3 +45,11 @@ game-patching-error = Fallo al parchear el juego
# Sandbox
documentation-url-open-failed = Failed to open documentation URL
+
+# Game
+
+game-session-add-failed = Fallo al añadir sesión de juego
+game-session-update-failed = Fallo al actualizar sesión de juego
+game-session-remove-failed = Fallo al eliminar sesión de juego
+game-session-set-current-failed = Fallo al establecer sesión de juego actual
+game-session-apply-failed = Fallo al aplicar sesión de juego
diff --git a/assets/locales/es/first_run.ftl b/assets/locales/es/first_run.ftl
index 4dff8d1..270cfd9 100755
--- a/assets/locales/es/first_run.ftl
+++ b/assets/locales/es/first_run.ftl
@@ -23,6 +23,11 @@ tos-violation-warning-message =
Si entiendes los riesgos de intentar jugar el juego de manera extraoficial, presiona OK y ¡exploremos el vasto mundo de Teyvat!
+tos-dialog-title = ¿Estás seguro de entender lo que queremos decir?
+tos-dialog-message =
+ 1. No publiques información sobre este proyecto
+ 2. No abuses de él usando clientes modificados o cosas similares
+ 3. Haz preguntas exclusivamente en nuestro canal de Discord o de Matrix
dependencies = Dependencias
missing-dependencies-title = ¡Te faltan algunas dependencias!
diff --git a/assets/locales/es/game.ftl b/assets/locales/es/game.ftl
new file mode 100644
index 0000000..bf98a04
--- /dev/null
+++ b/assets/locales/es/game.ftl
@@ -0,0 +1,7 @@
+game-sessions = Sesiones de juego
+
+active-sessions = Sesión activa
+active-session-description = La sesión de juego actualmente seleccionada. Se actualiza cada vez que se lanza el juego.
+
+update-session = Actualizar la sesión con los valores actuales del registro del prefijo de Wine
+delete-session = Eliminar sesión
diff --git a/assets/locales/es/main.ftl b/assets/locales/es/main.ftl
index d1c6483..481bcc8 100755
--- a/assets/locales/es/main.ftl
+++ b/assets/locales/es/main.ftl
@@ -22,6 +22,7 @@ continue = Continuar
exit = Salir
check = Comprobar
restart = Reiniciar
+agree = Aceptar
loading-data = Cargando datos
diff --git a/assets/locales/es/sandbox.ftl b/assets/locales/es/sandbox.ftl
index e6a241e..530e1fe 100644
--- a/assets/locales/es/sandbox.ftl
+++ b/assets/locales/es/sandbox.ftl
@@ -8,7 +8,7 @@ hide-home-directory = Esconder el directorio home
hide-home-directory-description = Aisla las carpetas /home, /var/home/$USER, y $HOME del juego
hostname = Nombre del host
-additional-arguments = Additional arguments
+additional-arguments = Argumentos adicionales
private-directories = Directorios privados
private-directories-description = Estas carpetas serán reemplazadas por un sistema de archivos virtual (tmpfs) vacío, y su contenido real no será accesible al juego aislado
@@ -24,5 +24,5 @@ new-path = Nueva ruta
read-only = Sólo lectura
read-only-description = Le prohibe al juego escribir datos en este directorio
-symlinks = Symlinks
-symlinks-description = Symlink original path to the new one inside of your sandbox
+symlinks = Enlaces simbólicos
+symlinks-description = Enlaza la ruta original a la nueva dentro de tu entorno aislado
diff --git a/assets/locales/fr/errors.ftl b/assets/locales/fr/errors.ftl
index 0e4ac5d..ebcd1ad 100644
--- a/assets/locales/fr/errors.ftl
+++ b/assets/locales/fr/errors.ftl
@@ -45,3 +45,11 @@ game-patching-error = Le patch du jeu a échoué
# Sandbox
documentation-url-open-failed = Failed to open documentation URL
+
+# Game
+
+game-session-add-failed = Imposible d'ajouter la session de jeu
+game-session-update-failed = Imposible de mettre à jour la session de jeu
+game-session-remove-failed = Imposible de supprimer la session de jeu
+game-session-set-current-failed = Imposible de sélectionner la session de jeu par défaut
+game-session-apply-failed = Imposible d'appliquer la session de jeu
diff --git a/assets/locales/fr/first_run.ftl b/assets/locales/fr/first_run.ftl
index 42cc3b7..869c96b 100644
--- a/assets/locales/fr/first_run.ftl
+++ b/assets/locales/fr/first_run.ftl
@@ -23,6 +23,11 @@ tos-violation-warning-message =
Si vous comprenez ces risques, appuyez sur "Continuer" pour venir explorer le monde de Teyvat !
+tos-dialog-title = Are you sure you understand what we want to say?
+tos-dialog-message =
+ 1. Don't publish any information about this project
+ 2. Don't abuse it by using some modded clients and so
+ 3. Ask questions exceptionally in our discord or matrix server
dependencies = Dépendances
missing-dependencies-title = Il vous manque des dépendances !
diff --git a/assets/locales/fr/game.ftl b/assets/locales/fr/game.ftl
new file mode 100644
index 0000000..31af0dd
--- /dev/null
+++ b/assets/locales/fr/game.ftl
@@ -0,0 +1,7 @@
+game-sessions = Sessions de jeu
+
+active-sessions = Session active
+active-session-description = Session actuellement sélectionnée en jeu. Mis à jour à chaque lancement du jeu
+
+update-session = Mettre à jour la session depuis les valeurs du registre du préfixe wine
+delete-session = Supprimer la session
diff --git a/assets/locales/fr/main.ftl b/assets/locales/fr/main.ftl
index f473b7d..9dadf2f 100644
--- a/assets/locales/fr/main.ftl
+++ b/assets/locales/fr/main.ftl
@@ -22,6 +22,7 @@ continue = Continuer
exit = Quitter
check = Vérifier
restart = Redémarer
+agree = Agree
loading-data = Chargement des données
diff --git a/assets/locales/ru/errors.ftl b/assets/locales/ru/errors.ftl
index 7f144ca..d242777 100644
--- a/assets/locales/ru/errors.ftl
+++ b/assets/locales/ru/errors.ftl
@@ -45,3 +45,11 @@ game-patching-error = Не удалось установить патч игры
# Sandbox
documentation-url-open-failed = Не удалось открыть ссылку с документацией
+
+# Game
+
+game-session-add-failed = Не удалось добавить игровую сессию
+game-session-update-failed = Не удалось обновить игровую сессию
+game-session-remove-failed = Не удалось удалить игровую сессию
+game-session-set-current-failed = Не удалось выбрать игровую сессию
+game-session-apply-failed = Не удалось применить игровую сессию
diff --git a/assets/locales/ru/first_run.ftl b/assets/locales/ru/first_run.ftl
index 760df53..9521144 100644
--- a/assets/locales/ru/first_run.ftl
+++ b/assets/locales/ru/first_run.ftl
@@ -23,8 +23,13 @@ tos-violation-warning-message =
Если это произойдёт - поскольку ваша учетная запись будет нарушать правила, {company-name}/{company-alter-name} будут свободы делать то, что захотят, включая блокировку вашего аккаунта.
- Если вы осознаёте риск использования неофициальных средств игры - нажмите "Продолжить" и отправляйтесь исследовать мир Тейвата!
+ Если вы осознаёте риск использования неофициальных средств игры - нажмите "Продолжить"
+tos-dialog-title = Вы точно уверены что понимаете что мы хотим сказать?
+tos-dialog-message =
+ 1. Не публикуйте никакой информации о проекте
+ 2. Не используйте его совместно с модифицированными клиентами и тому подобным
+ 3. Задавайте вопросы исключительно на нашем discord или matrix сервере
dependencies = Зависимости
missing-dependencies-title = У вас не установлены некоторые компоненты!
diff --git a/assets/locales/ru/game.ftl b/assets/locales/ru/game.ftl
new file mode 100644
index 0000000..8baddaa
--- /dev/null
+++ b/assets/locales/ru/game.ftl
@@ -0,0 +1,7 @@
+game-sessions = Игровые сессии
+
+active-sessions = Активная сессия
+active-session-description = Выбранная игровая сессия. Обновляется после каждого запуска игры
+
+update-session = Обновить сессию используя значения реестра из префикса Wine
+delete-session = Удалить сессию
diff --git a/assets/locales/ru/main.ftl b/assets/locales/ru/main.ftl
index 1cb3861..04debfe 100644
--- a/assets/locales/ru/main.ftl
+++ b/assets/locales/ru/main.ftl
@@ -22,6 +22,7 @@ continue = Продолжить
exit = Выйти
check = Проверить
restart = Перезапустить
+agree = Подтвердить
loading-data = Загрузка данных
diff --git a/assets/locales/tr/enhancements.ftl b/assets/locales/tr/enhancements.ftl
index 61206b2..77f9393 100644
--- a/assets/locales/tr/enhancements.ftl
+++ b/assets/locales/tr/enhancements.ftl
@@ -1,13 +1,13 @@
wine = Wine
synchronization = Senkronizasyon
-wine-sync-description = içerde dönen Wine eventleri senkronize etmek için kullanılan teknoloji
+wine-sync-description = Arkaplanda gerçekleşen Wine olaylarını senkronize etmek için kullanılan teknoloji
-language = dil
-wine-lang-description = Wine için kullanılan dil klavye sorunlarını çözmek için kullanılabilir
+language = Dil
+wine-lang-description = Wine için kullanılan dil, klavye sorunlarını çözmek için kullanılabilir
system = Sistem
-borderless-window = Köşesiz pencere
+borderless-window = Köşesiz Pencere
virtual-desktop = Sanal Masaüstü
game = Oyun
@@ -15,30 +15,30 @@ game = Oyun
hud = HUD
fsr = FSR
-fsr-description = Oyunu mönitör boyutunuza büyütür daha düşük bir çözünürlük seçmek için oyun içinde alt + enter tuşlarına basın
+fsr-description = Oyunu monitör boyutunuza büyütür. Daha düşük bir çözünürlük seçmek için oyun içinde alt + enter tuşlarına basın
ultra-quality = Ultra kalite
quality = Kalite
balanced = Dengeli
performance = Performans
-gamemode = Oyunmodu
-gamemode-description = Oyunu diğer işlemlerden daha öne koyarak performansı arttırır
+gamemode = Oyun modu
+gamemode-description = Oyunun işlem önceliğini arttırarak performansı arttırır
gamescope = Gamescope
-gamescope-description = Gamescope Valve tarafından geliştirilmiş bir araçtır oyunları izole edilmiş bir Xwayland içinde açmanıza yarar
+gamescope-description = Gamescope, oyunları izole edilmiş bir Xwayland içinde açmanıza yarayan Valve tarafından geliştirilmiş araçtır.
discord-rpc = Discord RPC
-discord-rpc-description = Discord RPC Discorda şuanda oyun oynadığınızın bilgisini vermenize yarar bu sayede arkadaşlarınıza şuanda oyun oynadığınızı gösterebilirsiniz
+discord-rpc-description = Discord RPC, Discord'a şu anda oyun oynadığınızı bildirmenizi sağlar. Bu sayede arkadaşlarınıza şu anda oyun oynadığınızı gösterebilirsiniz
title = Başlık
description = Açıklama
fps-unlocker = FPS kilidi açıcı
enabled = Açık
-fps-unlocker-description = kare renderlama limitasyonunu kaldırır fakat oyunun anti hile sistemi tarafından tespit edilebilir
+fps-unlocker-description = Kare işleme sınırlamasını kaldırır, fakat oyunun anti-hile sistemi tarafından tespit edilebilir
power-saving = Güç tasarrufu
-power-saving-description = Alt tab attığınızda oyunun fps limitini 10 a çeker ve oyuna verilen işlem önceliğini azaltır
+power-saving-description = Pencere değiştirdiğinizde oyunun kare sınırını 10'a indirir ve oyuna verilen işlem önceliğini azaltır
monitor = Monitör
monitor-description = Oyunu çalıştırmak istediğiniz monitör sayısı
diff --git a/assets/locales/tr/errors.ftl b/assets/locales/tr/errors.ftl
index 6a66ead..5959e36 100644
--- a/assets/locales/tr/errors.ftl
+++ b/assets/locales/tr/errors.ftl
@@ -1,12 +1,12 @@
-launcher-folder-opening-error = Failed to open launcher folder
+launcher-folder-opening-error = İstemci dosyasını açma başarısız oldu
game-folder-opening-error = Oyun dosyasını açma başarısız oldu
config-file-opening-error = Config dosyasını açma başarısız oldu
debug-file-opening-error = Debug dosyasını açma başarısız oldu
-wish-url-search-failed = Dilekler urlsi bulunamadı
-wish-url-opening-error = Dilekler urlsi açılamadı
+wish-url-search-failed = Dileklerin URL'si bulunamadı
+wish-url-opening-error = Dileklerin URL'si açılamadı
-wine-run-error = Failed to run {$executable} executable using wine
+wine-run-error = Wine kullanarak {$executable} programı çalıştırılamadı
game-launching-failed = Oyunu açma başarısız oldu
failed-get-selected-wine = Seçilen Wine versiyonunu alma başarısız oldu
@@ -19,18 +19,18 @@ integrity-files-getting-error = Dosyaların bütünlüğü kontrol edilemedi
background-downloading-failed = Arkaplan fotoğrafını indirme başarısız oldu
components-index-sync-failed = Bileşenler dizini senkronizasyonu başarısız oldu
components-index-verify-failed = Bileşenler dizini doğrulanamadı
-config-update-error = Configi kaydetme başarısız oldu
+config-update-error = Config'i kaydetme başarısız oldu
wine-prefix-update-failed = Wine prefixini güncelleme başarısız oldu
dxvk-install-failed = DXVK indirilemedi
voice-package-deletion-error = Ses dosyasını silme başarısız oldu
-game-diff-finding-error = Oyun diffini bulma başarısız oldu
+game-diff-finding-error = Oyun diff'ini bulma başarısız oldu
patch-info-fetching-error = Yama bilgilerini toplama başarısız oldu
launcher-state-updating-error = İstemci durumunu güncelleme başarısız oldu
package-not-available = Paket mevcut değil: {$package}
wine-download-error = Wine indirme başarısız oldu
-wine-unpack-errror = Wine dosyadan çıkarmak başarısız oldu
+wine-unpack-errror = Wine dosyadan çıkarma başarısız oldu
wine-install-failed = Wine kurma başarısız oldu
dxvk-download-error = DXVK indirilemedi
dxvk-unpack-error = DXVK paketten çıkarılamadı
@@ -44,4 +44,12 @@ game-patching-error = Yamayı uygulamada sorun çıktı
# Sandbox
-documentation-url-open-failed = Failed to open documentation URL
+documentation-url-open-failed = Belgelemenin URL'si açılamadı
+
+# Game
+
+game-session-add-failed = Oyun oturumu eklenemedi
+game-session-update-failed = Oyun oturumu güncellenemedi
+game-session-remove-failed = Oyun oturumu kaldırılamadı
+game-session-set-current-failed = Oyun oturumu seçilemedi
+game-session-apply-failed = Oyun oturumu uygulanamadı
diff --git a/assets/locales/tr/first_run.ftl b/assets/locales/tr/first_run.ftl
index cb61eea..6054343 100644
--- a/assets/locales/tr/first_run.ftl
+++ b/assets/locales/tr/first_run.ftl
@@ -1,31 +1,36 @@
welcome = Merhaba
welcome-page-message =
- Merhaba bir anime oyunu istemcisine hoş geldiniz
+ Merhaba, bir anime oyunu istemcisine hoş geldiniz
- Oyunu çalıştırmadan önce bazı şeyler hazırlamamız ve varsayılan bileşenleri indirmemiz gerekiyor.
+ Oyunu çalıştırmadan önce bazı şeyleri hazırlamamız ve varsayılan bileşenleri indirmemiz gerekiyor.
tos-violation-warning = Kullanım şartlarının ihlali uyarısı
tos-violation-warning-message =
- Bu başlatıcı, resmi olmayan bir araçtır ve hiçbir şekilde {company-name} veya {company-alter-name} ile ilgili değildir.
+ Bu başlatıcı, resmi olmayan bir araçtır ve hiçbir şekilde {company-name} veya {company-alter-name} ile ilgili değildir.
- Bu araç, Linux'ta {game-name} oynamayı kolaylaştırmak için tasarlanmıştır ve yalnızca oyunu daha az güçlükle yüklemek ve çalıştırmak amacıyla oluşturulmuştur.
+ Bu araç, Linux'ta {game-name} oynamayı kolaylaştırmak için tasarlanmıştır ve yalnızca oyunu daha az güçlükle yüklemek ve çalıştırmak amacıyla oluşturulmuştur.
- Bunu, mevcut bileşenleri kullanarak ve deneyimi kullanıcı için basit hale getirerek yapar.
+ Bunu, mevcut bileşenleri kullanarak ve deneyimi kullanıcı için basit hale getirerek yapar.
- Ancak burada kullanılan bazı bileşenler, {game-name} için {company-name} Hizmet Şartlarını ihlal ediyor olabilir.
+ Ancak burada kullanılan bazı bileşenler, {game-name} için {company-name} Hizmet Şartlarını ihlal ediyor olabilir.
- Bu başlatıcıyı kullanıyorsanız, {game-name} hesabınız {company-name}/{company-alter-name} tarafından TOS uyumlu değil olarak tanımlanacaktır.
+ Bu başlatıcıyı kullanıyorsanız, {game-name} hesabınız {company-name}/{company-alter-name} tarafından TOS uyumlu değil olarak tanımlanacaktır.
- Böyle bir durumda, hesabınız Hizmet Koşullarına uymayacağından, {company-name}/{company-alter-name} istediğini yapmakta özgürdür. Banlamak dahil.
+ Böyle bir durumda, hesabınız Hizmet Koşullarına uymayacağından, {company-name}/{company-alter-name} istediğini yapmakta özgürdür. Banlamak dahil.
- Oyunu gayri resmi bir sıfatla oynamaya çalışmanın riskini anlıyorsanız, Tamam'a basın ve Haydi Teyvat dünyasını araştırmaya başlayalım!
+ Eğer oyunu illegal yollarla oynamanın riskini anlıyorsanız, Tamam'a tıklayın
+tos-dialog-title = Ne demek istediğimizi anlayabildiniz mi?
+tos-dialog-message =
+ 1. Bu proje hakkında herhangi bir bilgi paylaşmayın.
+ 2. Modlanmış istemciler vb. ile suistimal etmeyin.
+ 3. Sorularınızı sadece Discord veya Matrix sunucumuzda sorun.
-dependencies = Bağlılıklar
-missing-dependencies-title = Bazı bağlılıklar bulunamadı!
+dependencies = Bağımlılıklar
+missing-dependencies-title = Bazı bağımlılıklar bulunamadı!
missing-dependencies-message = Kurulum işlemine devam etmeden önce bazı paketleri sisteminize kurmalısınız.
@@ -34,24 +39,24 @@ choose-default-paths = Varsayılan yolları seç
show-all-folders = Ne yaptığımı biliyorum
show-all-folders-subtitle = Ek yol seçimi ayarlarını göster. Dediğimi yap...
runners-folder = Başlatıcılar(Runnerlar) klasörü
-dxvks-folder = DXVKnın klasörü
-wine-prefix-folder = Wine prefixnin klasörü
-global-game-installation-folder = Global game version installation folder
-chinese-game-installation-folder = Chinese game version installation folder
-fps-unlocker-folder = FPS Unlocker folder
+dxvks-folder = DXVK'nin klasörü
+wine-prefix-folder = Wine prefix'inin klasörü
+global-game-installation-folder = Evrensel oyun sürümünü yükleme klasörü
+chinese-game-installation-folder = Oyun'un Çin sürümünü yükleme klasörü
+fps-unlocker-folder = FPS Unlocker klasörü
components-index = Bileşenlerin dizini
patch-folder = Yama klasörü
temp-folder = "Geçici" klasörü
-migrate = Migrate
+migrate = Aktarma
select-voice-packages = Ses paketlerini seç
download-components = Bileşenleri indir
-download-dxvk = DXVKyı İndir
-apply-dxvk = DXVKyı uygula
+download-dxvk = DXVK'yi İndir
+apply-dxvk = DXVK'yi uygula
finish = Bitir
diff --git a/assets/locales/tr/game.ftl b/assets/locales/tr/game.ftl
new file mode 100644
index 0000000..d5e6bdf
--- /dev/null
+++ b/assets/locales/tr/game.ftl
@@ -0,0 +1,7 @@
+game-sessions = Oyun oturumları
+
+active-sessions = Geçerli oturum
+active-session-description = Şu anda geçerli oyun oturumu. Oyunu her açtığınızda güncellenir
+
+update-session = Oturumu, geçerli wine prefix'inin girdi değerleriyle güncelleyin
+delete-session = Oturumu kaldır
diff --git a/assets/locales/tr/gamescope.ftl b/assets/locales/tr/gamescope.ftl
index 6486f36..221969c 100644
--- a/assets/locales/tr/gamescope.ftl
+++ b/assets/locales/tr/gamescope.ftl
@@ -10,4 +10,4 @@ nis-description = DLSS teknolojisine düşük maliyetli bir alternatif olarak Nv
other-settings = Diğer ayarlar
framerate-limit = Kare hızı limiti
-unfocused-framerate-limit = Odakta değilken ki Kare hızı limiti
+unfocused-framerate-limit = Odakta değilken kare hızı limiti
diff --git a/assets/locales/tr/general.ftl b/assets/locales/tr/general.ftl
index 3703943..8b697bf 100644
--- a/assets/locales/tr/general.ftl
+++ b/assets/locales/tr/general.ftl
@@ -5,43 +5,43 @@ update-background = Arkaplan imajını güncelle
update-background-description = İstemci için resmi arka plan resmini indirin. Bunun yerine özel resminizi kullanmak için devre dışı bırakabilirsiniz.
launcher-language = İstemci dili
-launcher-language-description = Restart attıktan sonra uygulanır
+launcher-language-description = Yeniden başlattıktan sonra uygulanır
-game-edition = Game edition
-global = Global
-china = China
+game-edition = Oyun Sürümü
+global = Evrensel
+china = Çin
-game-environment = Game environment
-game-environment-description = Get specific features like additional payment methods
+game-environment = Oyun ortamı
+game-environment-description = Ek ödeme yöntemleri gibi özelliklere erişin
game-voiceovers = Oyun içi sesler
-game-voiceovers-description = List of downloaded game voiceovers. You can select them in the game settings
+game-voiceovers-description = İndirilmiş oyun seslendirmeleri listesi. Oyun içi ayarlardan seçebilirsiniz
english = İngilizce
japanese = Japonca
korean = Korece
chinese = Çince
-migrate-installation = Migrate installation
-migrate-installation-description = Open special window where you can change your game installation folder
+migrate-installation = Yüklemeyi aktar
+migrate-installation-description = Oyun yükleme yerini değiştirebileceğiniz özel pencereyi açın
repair-game = Oyunu tamir et
status = Durum
game-version = Oyun versiyonu
-game-not-installed = inik değil
+game-not-installed = Yüklü değil
game-predownload-available = Güncelleme önceden indirilebilir: {$old} -> {$new}
game-update-available = Güncelleme mevcut: {$old} -> {$new}
-game-outdated = Oyun çok eski bu yüzden güncellenemez. En son sürüm: {$latest}
+game-outdated = Oyun çok eski, bu yüzden güncellenemez. En son sürüm: {$latest}
player-patch-version = Ana yama versiyonu
-player-patch-version-description = Oyunu linuxda oynamanıza izin veren ana yama
+player-patch-version-description = Oyunu Linux'ta oynamanıza izin veren ana yama
xlua-patch-version = Xlua yama versiyonu
-xlua-patch-version-description = Eski bilgisayarlarda performansı arttıran ve bir kaç sorunu düzelten ekstra yama
+xlua-patch-version-description = Eski bilgisayarlarda performansı arttıran ve birkaç sorunu düzelten ekstra yama
patch-not-available = Mevcut değil
-patch-not-available-tooltip = Yama sunucularına erişelemiyor
+patch-not-available-tooltip = Yama sunucularına erişilemiyor
patch-outdated = zamanı geçmiş ({$current})
patch-outdated-tooltip = Yamanın zamanı geçmiş: {$current} -> {$latest}
@@ -55,7 +55,7 @@ patch-not-applied-tooltip = Yama uygulanmamış
apply-xlua-patch = Xlua yamasını uygula
ask-superuser-permissions = Yönetici izinlerini sor
-ask-superuser-permissions-description = İstemci yöneticini iznini hostunuzun dosyalarını güncellemek için otomatik olarak kullanıcaktır. Buna flatpak versiyonunda gerek yoktur
+ask-superuser-permissions-description = İstemci yönetici iznini hostunuzun dosyalarını güncellemek için otomatik olarak kullanacaktır. Buna flatpak versiyonunda gerek yoktur
selected-version = Seçilmiş versiyon
recommended-only = Sadece önerilenler
@@ -63,14 +63,14 @@ recommended-only = Sadece önerilenler
wine-version = Wine versiyonu
wine-recommended-description = Sadece önerilen wine versiyonlarını göster
-wine-tools = Wine tools
-command-line = Command line
-registry-editor = Registry editor
-explorer = Explorer
-task-manager = Task manager
-configuration = Configuration
-debugger = Debugger
+wine-tools = Wine araçları
+command-line = Komut istemi
+registry-editor = Girdi düzenleyicisi
+explorer = Dosya gezgini
+task-manager = Görev yöneticisi
+configuration = Konfigürasyon
+debugger = Debug aracı
dxvk-version = DXVK versiyonu
-dxvk-selection-disabled = DXVK özelliği Wine grup tercihleriniz yüzünden devre dışı
+dxvk-selection-disabled = DXVK özelliği Wine grup tercihlerinizden dolayı devre dışı
dxvk-recommended-description = Sadece önerilen dxvk versiyonlarını göster
diff --git a/assets/locales/tr/main.ftl b/assets/locales/tr/main.ftl
index 0dd70c6..2e39067 100644
--- a/assets/locales/tr/main.ftl
+++ b/assets/locales/tr/main.ftl
@@ -4,13 +4,13 @@ default = Varsayılan
details = Detaylar
width = Genişlik
-height = Uzunlul
+height = Uzunluk
# Menu items
launcher-folder = İstemci dosyası
game-folder = Oyun dosyası
-config-file = Config dosyaso
+config-file = Config dosyası
debug-file = Debug dosyası
wish-url = Dilekleri aç
about = Hakkında
@@ -21,17 +21,18 @@ save = Kaydet
continue = Devam et
exit = Çıkış yap
check = Kontrol et
-restart = Tekrardan başlat
+restart = Tekrardan başlat
+agree = Onayla
loading-data = Bilgiler yükleniyor
-downloading-background-picture = Arkaplan dosyasi indiriliyor
+downloading-background-picture = Arkaplan dosyası indiriliyor
updating-components-index = Bileşenlerin dizini güncelleniyor
loading-game-version = Oyun sürümü yükleniyor
loading-patch-status = Yama durumu yükleniyor
loading-launcher-state = İstemci durumu yükleniyor
loading-launcher-state--game = Loading launcher state: oyun versiyonu doğrulanıyor
-loading-launcher-state--voice = Loading launcher state: {$locale} dublaj doğrulanıyor
+loading-launcher-state--voice = Loading launcher state: {$locale} seslendirme doğrulanıyor
loading-launcher-state--patch = Loading launcher state: indirilmiş yamanın durumu yükleniyor
@@ -40,17 +41,17 @@ downloading = İndiriliyor
unpacking = Paketten çıkartılıyor
verifying-files = Dosyalar Doğrulanıyor
repairing-files = Dosyalar tamir ediliyor
-migrating-folders = Migrating folders
-applying-hdiff = Applying hdiff patches
-removing-outdated = Removing outdated files
+migrating-folders = Dosyalar aktarılıyor
+applying-hdiff = Hdiff yamaları uygulanıyor
+removing-outdated = Eskimiş dosyalar kaldırılıyor
-components-index-updated = Components index was updated
+components-index-updated = Bileşenlerin dizini güncellendi
launch = Çalıştır
-migrate-folders = Migrate folders
-migrate-folders-tooltip = Update game folders structure
+migrate-folders = Dosyaları aktar
+migrate-folders-tooltip = Oyun dosyaları yapısını güncelle
apply-patch = Yamayı uygula
download-wine = Wine indir
create-prefix = Prefix oluştur
diff --git a/assets/locales/tr/sandbox.ftl b/assets/locales/tr/sandbox.ftl
index de61f49..76bf92e 100644
--- a/assets/locales/tr/sandbox.ftl
+++ b/assets/locales/tr/sandbox.ftl
@@ -1,28 +1,28 @@
-sandbox = Sandbox
-sandbox-description = Run the game in isolated environment, preventing it from accessing your personal data
+sandbox = Sanallaştırma
+sandbox-description = Oyunu kişisel verilerinize erişemeyeceği, izole bir ortamda çalıştırın
-enable-sandboxing = Enable sandboxing
-enable-sandboxing-description = Run the game in read-only copy of your root filesystem
+enable-sandboxing = Sanallaştırmayı aktifleştir
+enable-sandboxing-description = Oyunu root dosya sisteminizin salt-okunur kopyasında çalıştırın
-hide-home-directory = Hide home directory
-hide-home-directory-description = Isolate your /home, /var/home/$USER, and $HOME folders from the game
+hide-home-directory = Home dizinini gizle
+hide-home-directory-description = /home, /var/home/$USER, ve $HOME klasörlerini oyundan gizle
-hostname = Hostname
-additional-arguments = Additional arguments
+hostname = Host adı
+additional-arguments = Ek argümanlar
-private-directories = Private directories
-private-directories-description = These folders will be replaced by an empty virtual filesystem (tmpfs), and their original content will not be available to sandboxed game
+private-directories = Özel dizinler
+private-directories-description = Bu klasörler boş bir sanal dosya sistemiyle değiştirilecektir (tmpfs), ve orijinal içeriklerine sanallaştırılmış oyun erişemeyecektir
-path = Path
+path = Yol
-shared-directories = Shared directories
-shared-directories-description = These directories will be symlinked to directories in your host system
+shared-directories = Paylaşılmış dizinler
+shared-directories-description = Bu dizinlerden host sisteminizin dizinlerine kısayol oluşturulacaktır
-original-path = Original path
-new-path = New path
+original-path = Orijinal yol
+new-path = Yeni yol
-read-only = Read-only
-read-only-description = Forbid game to write any data to this directory
+read-only = Salt-okunur
+read-only-description = Oyunun bu dizinde veri oluşturmasını yasakla
-symlinks = Symlinks
-symlinks-description = Symlink original path to the new one inside of your sandbox
+symlinks = Kısayollar
+symlinks-description = Orijinal yoldan sanal ortamın içindeki yenisine kısayol oluştur
diff --git a/assets/locales/zh-cn/errors.ftl b/assets/locales/zh-cn/errors.ftl
index 4026f9b..49ffcc3 100644
--- a/assets/locales/zh-cn/errors.ftl
+++ b/assets/locales/zh-cn/errors.ftl
@@ -45,3 +45,11 @@ game-patching-error = 应用游戏补丁失败
# Sandbox
documentation-url-open-failed = Failed to open documentation URL
+
+# Game
+
+game-session-add-failed = Failed to add game session
+game-session-update-failed = Failed to update game session
+game-session-remove-failed = Failed to remove game session
+game-session-set-current-failed = Failed to set current game session
+game-session-apply-failed = Failed to apply game session
diff --git a/assets/locales/zh-cn/first_run.ftl b/assets/locales/zh-cn/first_run.ftl
index 234ffe4..66eca2f 100644
--- a/assets/locales/zh-cn/first_run.ftl
+++ b/assets/locales/zh-cn/first_run.ftl
@@ -23,6 +23,11 @@ tos-violation-warning-message =
如果你了解并接受通过非官方许可方式玩这款游戏所带来的风险,请单击“确定”。让我们一直抢过提瓦特大陆吧!
+tos-dialog-title = Are you sure you understand what we want to say?
+tos-dialog-message =
+ 1. Don't publish any information about this project
+ 2. Don't abuse it by using some modded clients and so
+ 3. Ask questions exceptionally in our discord or matrix server
dependencies = 依赖
missing-dependencies-title = 你缺少某些依赖组件
diff --git a/assets/locales/zh-cn/game.ftl b/assets/locales/zh-cn/game.ftl
new file mode 100644
index 0000000..bdd098a
--- /dev/null
+++ b/assets/locales/zh-cn/game.ftl
@@ -0,0 +1,7 @@
+game-sessions = Game sessions
+
+active-sessions = Active session
+active-session-description = Currently selected game session. Updates after each game launch
+
+update-session = Update session using current wine prefix registry values
+delete-session = Delete session
diff --git a/assets/locales/zh-cn/main.ftl b/assets/locales/zh-cn/main.ftl
index 93e83f1..c1e6d30 100644
--- a/assets/locales/zh-cn/main.ftl
+++ b/assets/locales/zh-cn/main.ftl
@@ -22,6 +22,7 @@ continue = 继续
exit = 退出
check = 检查
restart = 重启
+agree = Agree
loading-data = 正在加载数据
diff --git a/assets/locales/zh-cn/sandbox.ftl b/assets/locales/zh-cn/sandbox.ftl
index 11a9617..9714308 100644
--- a/assets/locales/zh-cn/sandbox.ftl
+++ b/assets/locales/zh-cn/sandbox.ftl
@@ -8,7 +8,7 @@ hide-home-directory = 隐藏家目录
hide-home-directory-description = 将 /home、 /var/home/$USER 和 $HOME 目录与游戏隔离
hostname = 主机名
-additional-arguments = Additional arguments
+additional-arguments = 额外参数
private-directories = 隐私目录
private-directories-description = 这些目录将会被空的虚拟文件系统(tmpfs)替代,其中的原始内容不可被沙盒中的游戏访问
@@ -24,5 +24,5 @@ new-path = 新路径
read-only = 只读
read-only-description = 禁止游戏向此目录写入任何数据
-symlinks = Symlinks
-symlinks-description = Symlink original path to the new one inside of your sandbox
+symlinks = 软链接
+symlinks-description = 软链接原始路径到沙盒里的新路径
diff --git a/fluentscan.py b/fluentscan.py
old mode 100644
new mode 100755
index cf05b5e..1f3e632
--- a/fluentscan.py
+++ b/fluentscan.py
@@ -5,51 +5,118 @@
import os
import sys
+import glob
+import re
-path = "assets/locales/" + sys.argv[1] + "/"
+valid_commands = ["diff", "unused", "missing"]
+
+if len(sys.argv) < 3:
+ print(f"Command format: ./fluentscan.py [command] [locale]\nAvailable commands: {valid_commands}")
+
+ sys.exit()
+
+if sys.argv[1] not in valid_commands:
+ print(f"Invalid command \"{sys.argv[1]}\". Available commands: {valid_commands}")
+
+ sys.exit()
+
+path = "assets/locales/" + sys.argv[2] + "/"
+
+try:
+ open(path + "/main.ftl", "r").close()
+
+except:
+ print(f"{path} does not exist")
+
+ sys.exit()
+
+all_entries = {}
+
+def dict_compare(d1, d2):
+ d1_keys = set(d1.keys())
+ d2_keys = set(d2.keys())
+
+ shared_keys = d1_keys.intersection(d2_keys)
+
+ added = d1_keys - d2_keys
+ removed = d2_keys - d1_keys
+
+ same = set(o for o in shared_keys if d1[o] == d2[o])
+
+ return added, removed, same
+
+def to_dict(text):
+ result={}
+
+ for i in text:
+ if " =" in i:
+ try:
+ result[i.split()[0]] = ' '.join(i.split()[2:])
+
+ except:
+ pass
+
+ elif i:
+ result[list(result.keys())[-1]] += i
+
+ return result
+
+def get_line_num(text,pattern):
+ line = 1
+
+ for i in text.split("\n"):
+ if pattern in i:
+ return line
+
+ line += 1
for filename in os.listdir("assets/locales/en"):
with open(os.path.join("assets/locales/en", filename), 'r') as locale_file:
created_locale = open(path + filename)
- def to_dict(text):
- result={}
+ expected = to_dict(locale_file)
+ expected2 = to_dict(created_locale)
- for i in text:
- if " = " in i:
- try:
- result[i.split()[0]] = ' '.join(i.split()[2:])
+ all_entries.update(expected)
- except:
- pass
+ added, removed, same = dict_compare(expected, expected2)
- elif i:
- result[list(result.keys())[-1]] += i
+ if sys.argv[1] == "unused" or sys.argv[1] == "missing":
+ files = glob.glob("src/**/*.rs", recursive=True)
- return result
+ used = []
+ vars = {}
- def dict_compare(d1, d2):
- d1_keys = set(d1.keys())
- d2_keys = set(d2.keys())
+ for i in files:
+ with open(i, "r") as script:
+ text = script.read()
- shared_keys = d1_keys.intersection(d2_keys)
+ if sys.argv[1] == "unused":
+ for j in expected:
+ if f"\"{j}\"" in text:
+ used.append(j)
- added = d1_keys - d2_keys
- removed = d2_keys - d1_keys
+ elif sys.argv[1] == "missing":
+ for j in text.split():
+ # TODO: ignore comments
+ if 'tr("' in j:
+ index = j.find('tr("')
- modified = {o : (d1[o], d2[o]) for o in shared_keys if d1[o] != d2[o]}
+ var_name = re.sub('[^\\w-]+', '', j[index:].replace('tr("', '').replace("Some", ""))
- same = set(o for o in shared_keys if d1[o] == d2[o])
+ # TODO: index multiple matches
+ vars[var_name] = [script.name, get_line_num(text,var_name)]
- return added, removed, modified, same
+ if sys.argv[1] == "unused":
+ for i in expected:
+ if i not in used:
+ print(f"[{locale_file.name}]\n"
+ " [Unused]\n"
+ f" {i}")
- expected=to_dict(locale_file)
- expected2=to_dict(created_locale)
+ continue
- # TODO: why modified is not used?
- added, removed, modified, same = dict_compare(expected, expected2)
-
- if added or removed or same:
+ if (added or removed or same) and sys.argv[1] == "diff":
print(f"[{created_locale.name[15:]}]")
if added:
@@ -72,3 +139,14 @@ for filename in os.listdir("assets/locales/en"):
print(f" {i} = {expected[i]}")
print("")
+
+if sys.argv[1] == "missing":
+ added, removed, same = dict_compare(vars, all_entries)
+
+ if not added:
+ print("Nothing is missing")
+
+ for i in added:
+ print(f"[{vars[i][0]}, line {vars[i][1]}]\n"
+ " [Missing]\n"
+ f" {i}")
diff --git a/src/ui/about.rs b/src/ui/about.rs
index 9e0105e..becfe0d 100644
--- a/src/ui/about.rs
+++ b/src/ui/about.rs
@@ -51,10 +51,12 @@ impl SimpleComponent for AboutDialog {
]),
add_credit_section: (Some("An Anime Team"), &[
+ "Nikita Podvirnyy https://github.com/krypt0nn",
"@Marie https://github.com/Mar0xy",
"@lane https://github.com/laurinneff",
"@jiro-too https://github.com/jiro-too",
- "@cybik https://github.com/cybik"
+ "@cybik https://github.com/cybik",
+ "@mkrsym1 https://github.com/mkrsym1"
]),
set_artists: &[
@@ -66,7 +68,8 @@ impl SimpleComponent for AboutDialog {
"Deutsch — @Marie https://github.com/Mar0xy",
"Español — Lautaro Garavano https://github.com/Rattlehead15",
"Français — @zeGolem https://github.com/zeGolem",
- "Türk — @Kaozix https://github.com/Kaozix1776",
+ "Türkçe — @Kaozix https://github.com/Kaozix1776",
+ "Türkçe — Kayra Nachfolger https://github.com/kayranachfolger",
"简体中文 — Caibin Chen https://github.com/tigersoldier"
].join("\n"),
@@ -85,13 +88,25 @@ impl SimpleComponent for AboutDialog {
"Added
",
"",
- "- Added arguments and symlinks editor to sandbox settings
",
+ "- Added rules approving dialog to the first run window
",
+ "- Added game settings section
",
+ "- Added game sessions manager
",
+ "- Added `LAUNCHER_FOLDER` variable support
",
+ "- Added patch repository mirror
",
+ "
",
+
+ "Changed
",
+
+ "",
+ "- Improved launcher logo rendering quality
",
+ "- Reworked entry rows in the settings
",
"
",
"Fixed
",
"",
- "- Fixed game running issue if you have spaces in paths
",
+ "- Fixed wine tools running using proton builds
",
+ "- Fixed sandboxed game running (sounds are broken for now)
",
"
",
].join("\n"),
diff --git a/src/ui/first_run/tos_warning.rs b/src/ui/first_run/tos_warning.rs
index 08ae5b1..364632b 100644
--- a/src/ui/first_run/tos_warning.rs
+++ b/src/ui/first_run/tos_warning.rs
@@ -8,6 +8,8 @@ use anime_launcher_sdk::is_available;
use crate::i18n::*;
use super::main::FirstRunAppMsg;
+use super::main::MAIN_WINDOW;
+
pub struct TosWarningApp;
#[derive(Debug, Clone)]
@@ -86,11 +88,34 @@ impl SimpleAsyncComponent for TosWarningApp {
match msg {
#[allow(unused_must_use)]
TosWarningAppMsg::Continue => {
- if is_available("git") && is_available("xdelta3") {
- sender.output(Self::Output::ScrollToDefaultPaths);
- } else {
- sender.output(Self::Output::ScrollToDependencies);
- }
+ let dialog = adw::MessageDialog::new(
+ unsafe { MAIN_WINDOW.as_ref() },
+ Some(&tr("tos-dialog-title")),
+ Some(&tr("tos-dialog-message"))
+ );
+
+ dialog.add_responses(&[
+ ("exit", &tr("exit")),
+ ("continue", &tr("agree"))
+ ]);
+
+ dialog.connect_response(None, move |_, response| {
+ match response {
+ "exit" => relm4::main_application().quit(),
+
+ "continue" => {
+ if is_available("git") && is_available("xdelta3") {
+ sender.output(Self::Output::ScrollToDefaultPaths);
+ } else {
+ sender.output(Self::Output::ScrollToDependencies);
+ }
+ }
+
+ _ => unreachable!()
+ }
+ });
+
+ dialog.show();
}
TosWarningAppMsg::Exit => relm4::main_application().quit()
diff --git a/src/ui/main/mod.rs b/src/ui/main/mod.rs
index c4039ce..b16c679 100644
--- a/src/ui/main/mod.rs
+++ b/src/ui/main/mod.rs
@@ -220,13 +220,15 @@ impl SimpleComponent for App {
set_visible: model.loading.is_none(),
add = &adw::PreferencesGroup {
+ set_margin_top: 48,
+
#[watch]
set_visible: model.style == LauncherStyle::Modern,
- gtk::Image {
+ gtk::Picture {
set_resource: Some("/org/app/images/icon.png"),
set_vexpand: true,
- set_margin_top: 48
+ set_content_fit: gtk::ContentFit::ScaleDown
},
gtk::Label {
@@ -253,6 +255,8 @@ impl SimpleComponent for App {
set_visible: model.downloading,
set_vexpand: true,
+ set_margin_top: 48,
+ set_margin_bottom: 48,
add = model.progress_bar.widget(),
},
@@ -273,6 +277,12 @@ impl SimpleComponent for App {
#[watch]
set_visible: !model.downloading,
+ #[watch]
+ set_margin_bottom: match model.style {
+ LauncherStyle::Modern => 48,
+ LauncherStyle::Classic => 0
+ },
+
set_vexpand: true,
gtk::Box {
@@ -547,11 +557,11 @@ impl SimpleComponent for App {
.detach());
}
- let group = RelmActionGroup::::new();
+ let mut group = RelmActionGroup::::new();
// TODO: reduce code somehow
- group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| {
+ group.add_action::(RelmAction::new_stateless(clone!(@strong sender => move |_| {
if let Err(err) = open::that(LAUNCHER_FOLDER.as_path()) {
sender.input(AppMsg::Toast {
title: tr("launcher-folder-opening-error"),
@@ -562,7 +572,7 @@ impl SimpleComponent for App {
}
})));
- group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| {
+ group.add_action::(RelmAction::new_stateless(clone!(@strong sender => move |_| {
let path = match Config::get() {
Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(),
Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(),
@@ -578,7 +588,7 @@ impl SimpleComponent for App {
}
})));
- group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| {
+ group.add_action::(RelmAction::new_stateless(clone!(@strong sender => move |_| {
if let Ok(file) = config_file() {
if let Err(err) = open::that(file) {
sender.input(AppMsg::Toast {
@@ -591,7 +601,7 @@ impl SimpleComponent for App {
}
})));
- group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| {
+ group.add_action::(RelmAction::new_stateless(clone!(@strong sender => move |_| {
if let Err(err) = open::that(crate::DEBUG_FILE.as_os_str()) {
sender.input(AppMsg::Toast {
title: tr("debug-file-opening-error"),
@@ -602,7 +612,7 @@ impl SimpleComponent for App {
}
})));
- group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| {
+ group.add_action::(RelmAction::new_stateless(clone!(@strong sender => move |_| {
std::thread::spawn(clone!(@strong sender => move || {
let config = Config::get().unwrap_or_else(|_| CONFIG.clone());
@@ -662,7 +672,7 @@ impl SimpleComponent for App {
}));
})));
- group.add_action::(&RelmAction::new_stateless(move |_| {
+ group.add_action::(RelmAction::new_stateless(move |_| {
about_dialog_broker.send(AboutDialogMsg::Show);
}));
@@ -709,10 +719,8 @@ impl SimpleComponent for App {
description: if changes.is_empty() {
None
} else {
- let max_len = changes.iter().map(|line| line.len()).max().unwrap_or(80);
-
Some(changes.into_iter()
- .map(|line| format!("- {line}{}", " ".repeat(max_len - line.len())))
+ .map(|line| format!("- {line}"))
.collect::>()
.join("\n"))
}
diff --git a/src/ui/preferences/environment.rs b/src/ui/preferences/environment.rs
index 6cdf707..c7ceb70 100644
--- a/src/ui/preferences/environment.rs
+++ b/src/ui/preferences/environment.rs
@@ -16,10 +16,10 @@ struct Variable {
#[relm4::factory(async)]
impl AsyncFactoryComponent for Variable {
type Init = (String, String);
- type Input = EnvironmentMsg;
- type Output = EnvironmentMsg;
+ type Input = EnvironmentAppMsg;
+ type Output = EnvironmentAppMsg;
type CommandOutput = ();
- type ParentInput = EnvironmentMsg;
+ type ParentInput = EnvironmentAppMsg;
type ParentWidget = adw::PreferencesGroup;
view! {
@@ -33,16 +33,12 @@ impl AsyncFactoryComponent for Variable {
set_valign: gtk::Align::Center,
connect_clicked[sender, index] => move |_| {
- sender.input(EnvironmentMsg::Remove(index.clone()));
+ sender.output(EnvironmentAppMsg::Remove(index.clone()));
}
}
}
}
- fn output_to_parent_input(output: Self::Output) -> Option {
- Some(output)
- }
-
async fn init_model(
init: Self::Init,
_index: &DynamicIndex,
@@ -54,8 +50,8 @@ impl AsyncFactoryComponent for Variable {
}
}
- async fn update(&mut self, msg: Self::Input, sender: AsyncFactorySender) {
- sender.output(msg);
+ fn forward_to_parent(output: Self::Output) -> Option {
+ Some(output)
}
}
@@ -67,7 +63,7 @@ pub struct EnvironmentApp {
}
#[derive(Debug, Clone)]
-pub enum EnvironmentMsg {
+pub enum EnvironmentAppMsg {
Add,
Remove(DynamicIndex)
}
@@ -75,7 +71,7 @@ pub enum EnvironmentMsg {
#[relm4::component(async, pub)]
impl SimpleAsyncComponent for EnvironmentApp {
type Init = ();
- type Input = EnvironmentMsg;
+ type Input = EnvironmentAppMsg;
type Output = ();
view! {
@@ -110,6 +106,20 @@ impl SimpleAsyncComponent for EnvironmentApp {
add = &adw::PreferencesGroup {
set_title: &tr("new-variable"),
+ #[wrap(Some)]
+ set_header_suffix = >k::Button {
+ add_css_class: "flat",
+
+ set_valign: gtk::Align::Center,
+
+ adw::ButtonContent {
+ set_icon_name: "list-add-symbolic",
+ set_label: &tr("add")
+ },
+
+ connect_clicked => EnvironmentAppMsg::Add
+ },
+
#[local_ref]
name_entry -> adw::EntryRow {
set_title: &tr("name")
@@ -118,16 +128,6 @@ impl SimpleAsyncComponent for EnvironmentApp {
#[local_ref]
value_entry -> adw::EntryRow {
set_title: &tr("value")
- },
-
- gtk::Button {
- set_label: &tr("add"),
- add_css_class: "pill",
-
- set_margin_top: 8,
- set_halign: gtk::Align::Start,
-
- connect_clicked => EnvironmentMsg::Add
}
},
@@ -166,12 +166,12 @@ impl SimpleAsyncComponent for EnvironmentApp {
async fn update(&mut self, msg: Self::Input, _sender: AsyncComponentSender) {
match msg {
- EnvironmentMsg::Add => {
- if let Ok(mut config) = Config::get() {
- let name = self.name_entry.text().trim().to_string();
- let value = self.value_entry.text().trim().to_string();
+ EnvironmentAppMsg::Add => {
+ let name = self.name_entry.text().trim().to_string();
+ let value = self.value_entry.text().trim().to_string();
- if !name.is_empty() && !value.is_empty() {
+ if !name.is_empty() && !value.is_empty() {
+ if let Ok(mut config) = Config::get() {
self.name_entry.set_text("");
self.value_entry.set_text("");
@@ -184,7 +184,7 @@ impl SimpleAsyncComponent for EnvironmentApp {
}
}
- EnvironmentMsg::Remove(index) => {
+ EnvironmentAppMsg::Remove(index) => {
if let Ok(mut config) = Config::get() {
if let Some(var) = self.variables.guard().get(index.current_index()) {
config.game.environment.remove(&var.key);
diff --git a/src/ui/preferences/game.rs b/src/ui/preferences/game.rs
new file mode 100644
index 0000000..b02e268
--- /dev/null
+++ b/src/ui/preferences/game.rs
@@ -0,0 +1,285 @@
+use relm4::prelude::*;
+use relm4::component::*;
+use relm4::factory::*;
+
+use adw::prelude::*;
+
+use anime_launcher_sdk::sessions::SessionsExt;
+use anime_launcher_sdk::genshin::sessions::Sessions;
+
+use super::main::PreferencesAppMsg;
+
+use crate::i18n::tr;
+use crate::*;
+
+#[derive(Debug)]
+struct GameSession {
+ name: String,
+ description: Option
+}
+
+#[relm4::factory(async)]
+impl AsyncFactoryComponent for GameSession {
+ type Init = GameSession;
+ type Input = GameAppMsg;
+ type Output = GameAppMsg;
+ type CommandOutput = ();
+ type ParentInput = GameAppMsg;
+ type ParentWidget = adw::PreferencesGroup;
+
+ view! {
+ root = adw::ActionRow {
+ set_title: &self.name,
+
+ set_subtitle: match &self.description {
+ Some(description) => description.as_str(),
+ None => ""
+ },
+
+ add_suffix = >k::Button {
+ set_icon_name: "view-refresh-symbolic-symbolic",
+ add_css_class: "flat",
+
+ set_tooltip_text: Some(&tr("update-session")),
+
+ set_valign: gtk::Align::Center,
+
+ connect_clicked[sender, index] => move |_| {
+ sender.output(GameAppMsg::UpdateSession(index.clone()));
+ }
+ },
+
+ add_suffix = >k::Button {
+ set_icon_name: "user-trash-symbolic",
+ add_css_class: "flat",
+
+ set_tooltip_text: Some(&tr("delete-session")),
+
+ set_valign: gtk::Align::Center,
+
+ connect_clicked[sender, index] => move |_| {
+ sender.output(GameAppMsg::RemoveSession(index.clone()));
+ }
+ }
+ }
+ }
+
+ async fn init_model(
+ init: Self::Init,
+ _index: &DynamicIndex,
+ _sender: AsyncFactorySender,
+ ) -> Self {
+ init
+ }
+
+ fn forward_to_parent(output: Self::Output) -> Option {
+ Some(output)
+ }
+}
+
+pub struct GameApp {
+ sessions: AsyncFactoryVecDeque,
+
+ sessions_names: Vec,
+
+ sessions_combo: adw::ComboRow,
+ session_name_entry: adw::EntryRow
+}
+
+#[derive(Debug, Clone)]
+pub enum GameAppMsg {
+ AddSession,
+ UpdateSession(DynamicIndex),
+ RemoveSession(DynamicIndex),
+ SetCurrent(u32),
+ UpdateCombo
+}
+
+#[relm4::component(async, pub)]
+impl SimpleAsyncComponent for GameApp {
+ type Init = ();
+ type Input = GameAppMsg;
+ type Output = PreferencesAppMsg;
+
+ view! {
+ adw::PreferencesPage {
+ set_title: &tr("game"),
+ set_icon_name: Some("applications-games-symbolic"),
+
+ add = &adw::PreferencesGroup {
+ set_title: &tr("game-sessions"),
+
+ #[local_ref]
+ sessions_combo -> adw::ComboRow {
+ set_title: &tr("active-sessions"),
+ set_subtitle: &tr("active-session-description"),
+
+ connect_selected_notify[sender] => move |row| sender.input(GameAppMsg::SetCurrent(row.selected()))
+ }
+ },
+
+ add = &adw::PreferencesGroup {
+ #[local_ref]
+ session_name_entry -> adw::EntryRow {
+ set_title: &tr("name"),
+
+ add_suffix = >k::Button {
+ set_icon_name: "list-add-symbolic",
+ add_css_class: "flat",
+
+ set_valign: gtk::Align::Center,
+
+ connect_clicked => GameAppMsg::AddSession
+ }
+ }
+ },
+
+ #[local_ref]
+ add = sessions -> adw::PreferencesGroup {},
+ }
+ }
+
+ async fn init(
+ _init: Self::Init,
+ root: Self::Root,
+ sender: AsyncComponentSender,
+ ) -> AsyncComponentParts {
+ tracing::info!("Initializing game settings");
+
+ let mut model = Self {
+ sessions: AsyncFactoryVecDeque::new(adw::PreferencesGroup::new(), sender.input_sender()),
+
+ sessions_names: Vec::new(),
+
+ sessions_combo: adw::ComboRow::new(),
+ session_name_entry: adw::EntryRow::new()
+ };
+
+ for (name, _) in Sessions::list().unwrap_or_default() {
+ model.sessions.guard().push_back(GameSession {
+ name: name.clone(),
+ description: None
+ });
+ }
+
+ let sessions = model.sessions.widget();
+
+ let sessions_combo = &model.sessions_combo;
+ let session_name_entry = &model.session_name_entry;
+
+ let widgets = view_output!();
+
+ sender.input(GameAppMsg::UpdateCombo);
+
+ AsyncComponentParts { model, widgets }
+ }
+
+ async fn update(&mut self, msg: Self::Input, sender: AsyncComponentSender) {
+ match msg {
+ GameAppMsg::AddSession => {
+ let name = self.session_name_entry.text().trim().to_string();
+
+ if !name.is_empty() {
+ if let Ok(config) = Config::get() {
+ self.session_name_entry.set_text("");
+
+ match Sessions::update(name.clone(), config.get_wine_prefix_path()) {
+ Ok(()) => {
+ self.sessions.guard().push_back(GameSession {
+ name,
+ description: None
+ });
+
+ sender.input(GameAppMsg::UpdateCombo);
+ }
+
+ #[allow(unused_must_use)]
+ Err(err) => {
+ sender.output(PreferencesAppMsg::Toast {
+ title: tr("game-session-add-failed"),
+ description: Some(err.to_string())
+ });
+ }
+ }
+ }
+ }
+ }
+
+ GameAppMsg::UpdateSession(index) => {
+ if let Some(session) = self.sessions.guard().get(index.current_index()) {
+ if let Ok(config) = Config::get() {
+ #[allow(unused_must_use)]
+ if let Err(err) = Sessions::update(session.name.clone(), config.get_wine_prefix_path()) {
+ sender.output(PreferencesAppMsg::Toast {
+ title: tr("game-session-update-failed"),
+ description: Some(err.to_string())
+ });
+ }
+ }
+ }
+ }
+
+ GameAppMsg::RemoveSession(index) => {
+ if let Some(session) = self.sessions.guard().get(index.current_index()) {
+ match Sessions::remove(&session.name) {
+ Ok(()) => sender.input(GameAppMsg::UpdateCombo),
+
+ #[allow(unused_must_use)]
+ Err(err) => {
+ sender.output(PreferencesAppMsg::Toast {
+ title: tr("game-session-remove-failed"),
+ description: Some(err.to_string())
+ });
+
+ return;
+ }
+ }
+ }
+
+ self.sessions.guard().remove(index.current_index());
+ }
+
+ GameAppMsg::SetCurrent(id) => {
+ if let Some(name) = self.sessions_names.get(id as usize) {
+ if let Ok(config) = Config::get() {
+ #[allow(unused_must_use)]
+ if let Err(err) = Sessions::set_current(name.to_owned()) {
+ sender.output(PreferencesAppMsg::Toast {
+ title: tr("game-session-set-current-failed"),
+ description: Some(err.to_string())
+ });
+
+ // Prevent session applying
+ return;
+ }
+
+ #[allow(unused_must_use)]
+ if let Err(err) = Sessions::apply(name.to_owned(), config.get_wine_prefix_path()) {
+ sender.output(PreferencesAppMsg::Toast {
+ title: tr("game-session-apply-failed"),
+ description: Some(err.to_string())
+ });
+ }
+ }
+ }
+ }
+
+ GameAppMsg::UpdateCombo => {
+ let sessions = Sessions::get_sessions().unwrap_or_default();
+
+ self.sessions_names = sessions.sessions.into_keys().collect::>();
+
+ let mut selected = 0;
+
+ for (i, name) in self.sessions_names.iter().enumerate() {
+ if sessions.current.as_ref() == Some(name) {
+ selected = i as u32;
+ }
+ }
+
+ self.sessions_combo.set_model(Some(>k::StringList::new(&self.sessions_names.iter().map(|name: &String| name.as_str()).collect::>())));
+ self.sessions_combo.set_selected(selected);
+ }
+ }
+ }
+}
diff --git a/src/ui/preferences/general.rs b/src/ui/preferences/general.rs
index 9376a68..749f4d9 100644
--- a/src/ui/preferences/general.rs
+++ b/src/ui/preferences/general.rs
@@ -84,10 +84,6 @@ impl AsyncFactoryComponent for VoicePackageComponent {
}
}
- fn output_to_parent_input(output: Self::Output) -> Option {
- Some(output)
- }
-
async fn init_model(
init: Self::Init,
_index: &DynamicIndex,
@@ -105,6 +101,10 @@ impl AsyncFactoryComponent for VoicePackageComponent {
sender.output(msg);
}
+
+ fn forward_to_parent(output: Self::Output) -> Option {
+ Some(output)
+ }
}
pub struct GeneralApp {
@@ -1035,7 +1035,8 @@ impl SimpleAsyncComponent for GeneralApp {
let config = Config::get().unwrap_or_else(|_| CONFIG.clone());
if let Ok(Some(wine)) = config.get_selected_wine() {
- let result = wine.to_wine(config.components.path, Some(config.game.wine.builds.join(&wine.name)))
+ let result = wine
+ .to_wine(config.components.path, Some(config.game.wine.builds.join(&wine.name)))
.with_prefix(config.game.wine.prefix)
.with_loader(WineLoader::Current)
.with_arch(WineArch::Win64)
diff --git a/src/ui/preferences/main.rs b/src/ui/preferences/main.rs
index 7665219..213e6b4 100644
--- a/src/ui/preferences/main.rs
+++ b/src/ui/preferences/main.rs
@@ -15,6 +15,7 @@ use crate::i18n::tr;
use super::general::*;
use super::enhancements::*;
+use super::game::*;
use super::sandbox::*;
use super::environment::*;
@@ -23,6 +24,7 @@ pub static mut PREFERENCES_WINDOW: Option = None;
pub struct PreferencesApp {
general: AsyncController,
enhancements: AsyncController,
+ game: AsyncController,
sandbox: AsyncController,
environment: AsyncController
}
@@ -69,6 +71,7 @@ impl SimpleAsyncComponent for PreferencesApp {
add = model.general.widget(),
add = model.enhancements.widget(),
+ add = model.game.widget(),
add = model.sandbox.widget(),
add = model.environment.widget(),
@@ -101,6 +104,10 @@ impl SimpleAsyncComponent for PreferencesApp {
.launch(())
.detach(),
+ game: GameApp::builder()
+ .launch(())
+ .detach(),
+
sandbox: SandboxApp::builder()
.launch(())
.forward(sender.input_sender(), std::convert::identity),
diff --git a/src/ui/preferences/mod.rs b/src/ui/preferences/mod.rs
index c066563..3ab11c5 100644
--- a/src/ui/preferences/mod.rs
+++ b/src/ui/preferences/mod.rs
@@ -1,6 +1,7 @@
pub mod main;
pub mod general;
pub mod enhancements;
+pub mod game;
pub mod sandbox;
pub mod environment;
pub mod gamescope;
diff --git a/src/ui/preferences/sandbox.rs b/src/ui/preferences/sandbox.rs
index 8283b23..1a9c474 100644
--- a/src/ui/preferences/sandbox.rs
+++ b/src/ui/preferences/sandbox.rs
@@ -7,6 +7,7 @@ use adw::prelude::*;
use anime_launcher_sdk::is_available;
use super::main::PreferencesAppMsg;
+
use crate::i18n::tr;
use crate::*;
@@ -41,16 +42,12 @@ macro_rules! impl_directory {
set_valign: gtk::Align::Center,
connect_clicked[sender, index] => move |_| {
- sender.input($msg(index.clone()));
+ sender.output($msg(index.clone()));
}
}
}
}
- fn output_to_parent_input(output: Self::Output) -> Option {
- Some(output)
- }
-
async fn init_model(
init: Self::Init,
_index: &DynamicIndex,
@@ -62,8 +59,8 @@ macro_rules! impl_directory {
}
}
- async fn update(&mut self, msg: Self::Input, sender: AsyncFactorySender) {
- sender.output(msg);
+ fn forward_to_parent(output: Self::Output) -> Option {
+ Some(output)
}
}
}
@@ -197,8 +194,10 @@ impl SimpleAsyncComponent for SandboxApp {
},
add_suffix = >k::Button {
- set_valign: gtk::Align::Center,
set_icon_name: "dialog-information-symbolic",
+ add_css_class: "flat",
+
+ set_valign: gtk::Align::Center,
connect_clicked[sender] => move |_| {
if let Err(err) = open::that("https://man.archlinux.org/man/bwrap.1") {
@@ -218,17 +217,16 @@ impl SimpleAsyncComponent for SandboxApp {
#[local_ref]
private_path_entry -> adw::EntryRow {
- set_title: &tr("path")
- },
+ set_title: &tr("path"),
- gtk::Button {
- set_label: &tr("add"),
- add_css_class: "pill",
+ add_suffix = >k::Button {
+ set_icon_name: "list-add-symbolic",
+ add_css_class: "flat",
- set_margin_top: 8,
- set_halign: gtk::Align::Start,
-
- connect_clicked => SandboxAppMsg::AddPrivate
+ set_valign: gtk::Align::Center,
+
+ connect_clicked => SandboxAppMsg::AddPrivate
+ }
}
},
@@ -239,6 +237,20 @@ impl SimpleAsyncComponent for SandboxApp {
set_title: &tr("shared-directories"),
set_description: Some(&tr("shared-directories-description")),
+ #[wrap(Some)]
+ set_header_suffix = >k::Button {
+ add_css_class: "flat",
+
+ set_valign: gtk::Align::Center,
+
+ adw::ButtonContent {
+ set_icon_name: "list-add-symbolic",
+ set_label: &tr("add")
+ },
+
+ connect_clicked => SandboxAppMsg::AddShared
+ },
+
#[local_ref]
shared_path_from_entry -> adw::EntryRow {
set_title: &tr("original-path")
@@ -257,16 +269,6 @@ impl SimpleAsyncComponent for SandboxApp {
add_suffix = read_only_switch -> gtk::Switch {
set_valign: gtk::Align::Center
}
- },
-
- gtk::Button {
- set_label: &tr("add"),
- add_css_class: "pill",
-
- set_margin_top: 8,
- set_halign: gtk::Align::Start,
-
- connect_clicked => SandboxAppMsg::AddShared
}
},
@@ -277,6 +279,20 @@ impl SimpleAsyncComponent for SandboxApp {
set_title: &tr("symlinks"),
set_description: Some(&tr("symlinks-description")),
+ #[wrap(Some)]
+ set_header_suffix = >k::Button {
+ add_css_class: "flat",
+
+ set_valign: gtk::Align::Center,
+
+ adw::ButtonContent {
+ set_icon_name: "list-add-symbolic",
+ set_label: &tr("add")
+ },
+
+ connect_clicked => SandboxAppMsg::AddSymlink
+ },
+
#[local_ref]
symlink_path_from_entry -> adw::EntryRow {
set_title: &tr("original-path")
@@ -285,16 +301,6 @@ impl SimpleAsyncComponent for SandboxApp {
#[local_ref]
symlink_path_to_entry -> adw::EntryRow {
set_title: &tr("new-path")
- },
-
- gtk::Button {
- set_label: &tr("add"),
- add_css_class: "pill",
-
- set_margin_top: 8,
- set_halign: gtk::Align::Start,
-
- connect_clicked => SandboxAppMsg::AddSymlink
}
},