diff --git a/tarok/lib/constants.dart b/tarok/lib/constants.dart index 71f04b0..98e974a 100644 --- a/tarok/lib/constants.dart +++ b/tarok/lib/constants.dart @@ -31,12 +31,14 @@ DiscordRPC rpc = DiscordRPC( applicationId: '1175161862086721616', ); -const BACKEND_URL = +String BACKEND_URL = kReleaseMode ? "https://palcka.si/api" : "http://localhost:8080"; -const WS_URL = - kReleaseMode ? "wss://palcka.si/api/ws" : "ws://localhost:8080/ws"; -const LOBBY_WS_URL = - kReleaseMode ? "wss://palcka.si/api/lobby" : "ws://localhost:8080/lobby"; +String WS_URL = kReleaseMode + ? "${BACKEND_URL.replaceAll("https://", "wss://").replaceAll("http://", "ws://")}/ws" + : "ws://localhost:8080/ws"; +String LOBBY_WS_URL = kReleaseMode + ? "${BACKEND_URL.replaceAll("https://", "wss://").replaceAll("http://", "ws://")}/lobby" + : "ws://localhost:8080/lobby"; const RELEASE = "0.1.2"; bool OMOGOCI_STOCKSKIS_PREDLOGE = true; bool SLEPI_TAROK = false; @@ -46,6 +48,7 @@ bool PREMOVE = false; bool DEVELOPER_MODE = false; bool SKISFANG = false; bool DISCORD_RPC = true; +bool RED_FILTER = true; String THEME = ""; Locale LOCALE = Get.deviceLocale ?? const Locale("sl", "SI"); @@ -66,6 +69,16 @@ final Player player = Player(); final dio = Dio(); const storage = FlutterSecureStorage(); +void parseBackendUrls() { + if (BACKEND_URL == "") BACKEND_URL = "https://palcka.si/api"; + WS_URL = kReleaseMode + ? "${BACKEND_URL.replaceAll("https://", "wss://").replaceAll("http://", "ws://")}/ws" + : "ws://localhost:8080/ws"; + LOBBY_WS_URL = kReleaseMode + ? "${BACKEND_URL.replaceAll("https://", "wss://").replaceAll("http://", "ws://")}/lobby" + : "ws://localhost:8080/lobby"; +} + class CardWidget { const CardWidget( {required this.position, required this.widget, required this.angle}); diff --git a/tarok/lib/game/game.dart b/tarok/lib/game/game.dart index cc01aff..a298db9 100644 --- a/tarok/lib/game/game.dart +++ b/tarok/lib/game/game.dart @@ -1810,7 +1810,7 @@ class Game extends StatelessWidget { ), ), ), - if (!controller.turn.value) + if (!controller.turn.value && RED_FILTER) Container( color: Colors.red.withAlpha(120), height: cardSize, diff --git a/tarok/lib/internationalization/languages.dart b/tarok/lib/internationalization/languages.dart index bb06cfe..ee74eca 100644 --- a/tarok/lib/internationalization/languages.dart +++ b/tarok/lib/internationalization/languages.dart @@ -432,6 +432,12 @@ class Messages extends Translations { "Radelci are given to all players whenever a game of at least beggar is played (or klop). Radelci are represented by small circles (✪). Each radelc can double one's points in one of the future games. In case the game difference is positive, it doubles the total sum of the game and deletes itself. In case the game difference is not positive, it doubles the total sum of the game and doesn't delete itself. At the end of entire game, -40 is given for each unused radelc.", "quiet_predictions": "Players, if not too sure of their chances, may also opt into \"quiet\" predictions, where they don't predict, yet in the end make the predictions. In the case they don't make the prediction, nothing is written, but if they make it, half points of the normal prediction are received. Quiet predictions cannot be predicted.", + "toggle_red_filter": "Toggle red filter", + "toggle_red_filter_desc": + "Toggle red filter above cards. The filter shows the card's validity to play. This setting applies only to the time when it is not your move. Red filter will still be shown when having to play.", + "api_url": "API URL", + "api_url_desc": + "ATTENTION! If not sure, what you're doing, don't change the defaults here. Improper configuration can open the door to attackers, which can afterwards hijack your session token and manage your account. As Palčka is an open-source program, anybody can host the server. In case one would want to play on their server, the API URL may be changed here. The default URL is https://palcka.si/api. Due to the CORS policy, it is possible that URL change might not work.", }, "fr_FR": { "login": "Connexion", @@ -869,6 +875,12 @@ class Messages extends Translations { "Radelci are given to all players whenever a game of at least beggar is played (or klop). Radelci are represented by small circles (✪). Each radelc can double one's points in one of the future games. In case the game difference is positive, it doubles the total sum of the game and deletes itself. In case the game difference is not positive, it doubles the total sum of the game and doesn't delete itself. At the end of entire game, -40 is given for each unused radelc.", "quiet_predictions": "Players, if not too sure of their chances, may also opt into \"quiet\" predictions, where they don't predict, yet in the end make the predictions. In the case they don't make the prediction, nothing is written, but if they make it, half points of the normal prediction are received. Quiet predictions cannot be predicted.", + "toggle_red_filter": "Toggle red filter", + "toggle_red_filter_desc": + "Toggle red filter above cards. The filter shows the card's validity to play. This setting applies only to the time when it is not your move. Red filter will still be shown when having to play.", + "api_url": "API URL", + "api_url_desc": + "ATTENTION! If not sure, what you're doing, don't change the defaults here. Improper configuration can open the door to attackers, which can afterwards hijack your session token and manage your account. As Palčka is an open-source program, anybody can host the server. In case one would want to play on their server, the API URL may be changed here. The default URL is https://palcka.si/api. Due to the CORS policy, it is possible that URL change might not work.", }, "sl_SI": { "login": "Prijava", @@ -1296,6 +1308,12 @@ class Messages extends Translations { "Radelci so dani vsem igralcem, ko se je igralo vsaj berača (ali klopa). Radelci so zastopani z manjšimi krogci (✪). Vsak radelc lahko podvoji točke igralcem v bodočih igrah. V primeru, da je igra pozitivna, radelc podvoji skupni seštevek igre in se izbriše. V primeru, da igra ni pozitivna, podvoji skupni seštevek igre in se ne izbriše. Na koncu celotne igre se za vsak neporabljen radelc odšteje 40 točk.", "quiet_predictions": "Če igralci niso dovolj prepričani v možnosti za izvedbe določene napovedi, lahko še vedno delajo t. i. \"tihe\" napovedi, kjer ničesar ne napovejo, a konec koncev še vedno naredijo napoved. V primeru, da ne naredijo tihe napovedi se ničesar ne piše, a če jo naredijo, dobijo polovico točk originalne napovedi. Tihe napovedi ne morejo biti napovedane.", + "toggle_red_filter": "Preklopi rdeči filter", + "toggle_red_filter_desc": + "Izklopi oz. vključi rdeči filter nad kartami, ki prikazuje veljavnost kart. Velja samo za vmesni čas, ko ni vaš čas za igranje.", + "api_url": "URL naslov API-ja", + "api_url_desc": + "POZOR! Če niste prepričani, kaj delate, ne spreminjajte. To lahko odpre možnost za napadalce, ki lahko ukradejo prijavni piškotek, če boste spreminjali to vrednost. Ker je Palčka odprtokoden program lahko kdorkoli gosti strežnik. Če si kdo želi slučajno igrati na lastnem strežniku, lahko tukaj spremeni API naslov, ki je privzeto https://palcka.si/api. Na spletu je možno, da ne deluje zaradi CORS politike.", } }; } diff --git a/tarok/lib/main.dart b/tarok/lib/main.dart index 1c0805b..6e698b8 100644 --- a/tarok/lib/main.dart +++ b/tarok/lib/main.dart @@ -79,10 +79,16 @@ void main() async { SOUNDS_ENABLED = prefs.getBool("sounds") ?? true; DEVELOPER_MODE = prefs.getBool("developer_mode") ?? false; DISCORD_RPC = prefs.getBool("discordRpc") ?? true; + RED_FILTER = prefs.getBool("red_filter") ?? true; NEXT_ROUND_DELAY = prefs.getInt("next_round_delay") ?? 10; BOT_DELAY = prefs.getInt("bot_delay") ?? 500; CARD_CLEANUP_DELAY = prefs.getInt("card_cleanup_delay") ?? 1000; + if (kReleaseMode) { + BACKEND_URL = prefs.getString("api_url") ?? "https://palcka.si/api"; + parseBackendUrls(); + } + if (!kIsWeb && (Platform.isLinux || Platform.isWindows) && DISCORD_RPC) { DiscordRPC.initialize(); rpc.start(autoRegister: true); diff --git a/tarok/lib/settings.dart b/tarok/lib/settings.dart index a711b33..036d980 100644 --- a/tarok/lib/settings.dart +++ b/tarok/lib/settings.dart @@ -33,8 +33,12 @@ class Settings extends StatefulWidget { } class _SettingsState extends State { + TextEditingController controller = TextEditingController(); + @override Widget build(BuildContext context) { + controller.text = BACKEND_URL; + return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, @@ -68,6 +72,19 @@ class _SettingsState extends State { title: Text("dark_mode".tr), description: Text("use_dark_mode".tr), ), + SettingsTile.switchTile( + onToggle: (value) async { + final SharedPreferences prefs = + await SharedPreferences.getInstance(); + await prefs.setBool("red_filter", value); + RED_FILTER = prefs.getBool("red_filter") ?? true; + setState(() {}); + }, + initialValue: RED_FILTER, + leading: const Icon(Icons.filter), + title: Text("toggle_red_filter".tr), + description: Text("toggle_red_filter_desc".tr), + ), ], ), SettingsSection( @@ -369,6 +386,37 @@ class _SettingsState extends State { title: Text("developer_mode".tr), description: Text("developer_mode_desc".tr), ), + SettingsTile( + title: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("api_url".tr), + const SizedBox( + height: 10, + ), + Text( + "api_url_desc".tr, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.normal, + ), + ), + TextField( + controller: controller, + onSubmitted: (String s) async { + final SharedPreferences prefs = + await SharedPreferences.getInstance(); + await prefs.setString("api_url", controller.text); + BACKEND_URL = prefs.getString("api_url") ?? + "https://palcka.si/api"; + parseBackendUrls(); + setState(() {}); + }, + ), + ], + ), + ), if (!BARVIC && !BERAC) SettingsTile.switchTile( onToggle: (value) async {