diff --git a/.run/Sanmill-dev.run.xml b/.run/Sanmill-dev.run.xml
new file mode 100644
index 00000000..c143d152
--- /dev/null
+++ b/.run/Sanmill-dev.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/Sanmill-monkey.run.xml b/.run/Sanmill-monkey.run.xml
new file mode 100644
index 00000000..d3f4b9a2
--- /dev/null
+++ b/.run/Sanmill-monkey.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/Sanmill-profile.run.xml b/.run/Sanmill-profile.run.xml
new file mode 100644
index 00000000..05d4dfd5
--- /dev/null
+++ b/.run/Sanmill-profile.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/Sanmill-release.run.xml b/.run/Sanmill-release.run.xml
new file mode 100644
index 00000000..983a17e1
--- /dev/null
+++ b/.run/Sanmill-release.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/Sanmill.run.xml b/.run/Sanmill.run.xml
new file mode 100644
index 00000000..c03f8656
--- /dev/null
+++ b/.run/Sanmill.run.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/Template Flutter.run.xml b/.run/Template Flutter.run.xml
new file mode 100644
index 00000000..f1bc2d08
--- /dev/null
+++ b/.run/Template Flutter.run.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000..84ad841a
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,60 @@
+{
+ // 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": [
+ {
+ "name": "Sanmill",
+ "type": "dart",
+ "request": "launch",
+ "cwd": "src/ui/flutter_app",
+ "program": "lib/main.dart"
+ },
+ {
+ "name": "Sanmill: Attach to Device",
+ "type": "dart",
+ "request": "attach"
+ },
+ {
+ "name": "Sanmill-dev",
+ "type": "dart",
+ "request": "launch",
+ "cwd": "src/ui/flutter_app",
+ "program": "lib/main.dart",
+ "args": [
+ "--dart-define",
+ "dev_mode=true",
+ "--dart-define",
+ "catcher=false"
+ ]
+ },
+ {
+ "name": "Sanmill-monkey",
+ "type": "dart",
+ "request": "launch",
+ "cwd": "src/ui/flutter_app",
+ "program": "lib/main.dart",
+ "args": [
+ "--dart-define",
+ "monkey_test=true"
+ ]
+ },
+ {
+ "name": "Sanmill-profile",
+ "type": "dart",
+ "request": "launch",
+ "cwd": "src/ui/flutter_app",
+ "program": "lib/main.dart",
+ "flutterMode": "profile"
+ },
+ {
+ "name": "Sanmill-release",
+ "type": "dart",
+ "request": "launch",
+ "cwd": "src/ui/flutter_app",
+ "program": "lib/main.dart",
+ "flutterMode": "release"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Readme.md b/Readme.md
index 61c922ef..38f3cade 100644
--- a/Readme.md
+++ b/Readme.md
@@ -71,6 +71,21 @@ Use Qt Creator to open `millgame.pro` , or use Visual Studio to open `millgame.s
Run `./flutter-init.sh` , copy `src/ui/flutter_app/android/key.properties.example` to `src/ui/flutter_app/android/key.properties`, modify it, and then use Android Studio or Visual Studio Code to open `src/ui/flutter_app` to build Flutter App.
+We use compile time enviornmet configs to enable specific parts of the code:
+
+* `monkey_test` to prepare the app for monkey tests (references to external sites are going to be disabled)
+* `dev_mode` to show the developer mode without needing to enable it first
+* `catcher` to controll the use of catcher (this is on by default and needs to be disabled when needed)
+
+all enviornment configs can be combined and take a value of bool like:
+
+```shell
+flutter run --dart-define catcher=false dev_mode=true
+```
+
+For ease of use some launch configs vor VS-Code and IntelliJ IDEA are available. Just select the
+needed one in the `Run and Debug` or `Run/Debug Configurations` tab.
+
## Understanding the code base and participating in the project
Sanmill's improvement over the last couple of years has been a great community effort. There are a few ways to help contribute to its growth.
diff --git a/src/ui/flutter_app/lib/main.dart b/src/ui/flutter_app/lib/main.dart
index 6a999b5e..c3fa63cb 100644
--- a/src/ui/flutter_app/lib/main.dart
+++ b/src/ui/flutter_app/lib/main.dart
@@ -30,6 +30,7 @@ import 'package:sanmill/generated/intl/l10n.dart';
import 'package:sanmill/models/display.dart';
import 'package:sanmill/screens/navigation_home_screen.dart';
import 'package:sanmill/services/audios.dart';
+import 'package:sanmill/services/enviornment_config.dart';
import 'package:sanmill/services/language_info.dart';
import 'package:sanmill/services/storage/storage.dart';
import 'package:sanmill/services/storage/storage_v1.dart';
@@ -37,39 +38,30 @@ import 'package:sanmill/shared/constants.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
part 'package:sanmill/services/catcher.dart';
+part 'package:sanmill/services/init_system_ui.dart';
Future main() async {
+ debugPrint('Enviornment [catcher]: ${EnvironmentConfig.catcher}');
+ debugPrint('Enviornment [dev_mode]: ${EnvironmentConfig.devMode}');
+ debugPrint('Enviornment [monkey_test]: ${EnvironmentConfig.monkeyTest}');
+
await LocalDatabaseService.initStorage();
await DatabaseV1.migrateDB();
- final catcher = Catcher(
- rootWidget: const BetterFeedback(
- child: SanmillApp(),
- //localeOverride: Locale(Resources.of().languageCode),
- ),
- ensureInitialized: true,
- );
- await _initCatcher(catcher);
+ _initUI();
- debugPrint(window.physicalSize.toString());
- debugPrint(Constants.windowAspectRatio.toString());
-
- SystemChrome.setPreferredOrientations(
- [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown],
- );
-
- if (Platform.isAndroid && isLargeScreen) {
- SystemChrome.setSystemUIOverlayStyle(
- const SystemUiOverlayStyle(
- statusBarColor: Colors.transparent,
- statusBarBrightness: Brightness.light,
- statusBarIconBrightness: Brightness.dark,
- systemNavigationBarColor: Colors.black,
- systemNavigationBarIconBrightness: Brightness.dark,
+ if (EnvironmentConfig.catcher) {
+ final catcher = Catcher(
+ rootWidget: const BetterFeedback(
+ child: SanmillApp(),
+ //localeOverride: Locale(Resources.of().languageCode),
),
+ ensureInitialized: true,
);
- } else if (isSmallScreen) {
- SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
+
+ await _initCatcher(catcher);
+ } else {
+ runApp(const SanmillApp());
}
}
@@ -83,8 +75,6 @@ class SanmillApp extends StatelessWidget {
final globalScaffoldKey = GlobalKey();
Audios.loadSounds();
- setSpecialCountryAndRegion(context);
-
return ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenDisplay,
builder: (BuildContext context, Box displayBox, _) {
@@ -95,7 +85,7 @@ class SanmillApp extends StatelessWidget {
return MaterialApp(
/// Add navigator key from Catcher.
/// It will be used to navigate user to report page or to show dialog.
- navigatorKey: Catcher.navigatorKey,
+ navigatorKey: EnvironmentConfig.catcher ? Catcher.navigatorKey : null,
key: globalScaffoldKey,
navigatorObservers: [routeObserver],
localizationsDelegates: S.localizationsDelegates,
@@ -104,25 +94,22 @@ class SanmillApp extends StatelessWidget {
theme: AppTheme.lightThemeData,
darkTheme: AppTheme.darkThemeData,
debugShowCheckedModeBanner: false,
- home: const _Home(),
+ home: Builder(
+ builder: (context) {
+ setSpecialCountryAndRegion(context);
+
+ return Scaffold(
+ body: DoubleBackToCloseApp(
+ snackBar: SnackBar(
+ content: Text(S.of(context).tapBackAgainToLeave),
+ ),
+ child: const NavigationHomeScreen(),
+ ),
+ );
+ },
+ ),
);
},
);
}
}
-
-class _Home extends StatelessWidget {
- const _Home({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- body: DoubleBackToCloseApp(
- snackBar: SnackBar(
- content: Text(S.of(context).tapBackAgainToLeave),
- ),
- child: const NavigationHomeScreen(),
- ),
- );
- }
-}
diff --git a/src/ui/flutter_app/lib/models/temporary.dart b/src/ui/flutter_app/lib/models/temporary.dart
index 077f46e8..f19cb797 100644
--- a/src/ui/flutter_app/lib/models/temporary.dart
+++ b/src/ui/flutter_app/lib/models/temporary.dart
@@ -16,6 +16,8 @@
along with this program. If not, see .
*/
+import 'package:sanmill/services/enviornment_config.dart';
+
/// Temporary data model
///
/// holds temporary runtime data that isn't yet or shouldn't be saved to the LocalDatabase
@@ -23,5 +25,5 @@ class Temp {
const Temp._();
/// represents a temporary value for Preferences.developerMode
- static bool developerMode = false;
+ static bool developerMode = EnvironmentConfig.devMode;
}
diff --git a/src/ui/flutter_app/lib/screens/game_settings/game_settings_page.dart b/src/ui/flutter_app/lib/screens/game_settings/game_settings_page.dart
index 36ec8bbc..01174d9b 100644
--- a/src/ui/flutter_app/lib/screens/game_settings/game_settings_page.dart
+++ b/src/ui/flutter_app/lib/screens/game_settings/game_settings_page.dart
@@ -25,6 +25,7 @@ import 'package:sanmill/generated/intl/l10n.dart';
import 'package:sanmill/models/preferences.dart';
import 'package:sanmill/models/temporary.dart';
import 'package:sanmill/screens/env_page.dart';
+import 'package:sanmill/services/enviornment_config.dart';
import 'package:sanmill/services/storage/storage.dart';
import 'package:sanmill/shared/settings/settings_card.dart';
import 'package:sanmill/shared/settings/settings_list_tile.dart';
diff --git a/src/ui/flutter_app/lib/screens/game_settings/reset_settings_alert.dart b/src/ui/flutter_app/lib/screens/game_settings/reset_settings_alert.dart
index 63dcd7e7..3261c561 100644
--- a/src/ui/flutter_app/lib/screens/game_settings/reset_settings_alert.dart
+++ b/src/ui/flutter_app/lib/screens/game_settings/reset_settings_alert.dart
@@ -25,7 +25,10 @@ class _ResetSettingsAlert extends StatelessWidget {
Future _restore(BuildContext context) async {
Navigator.pop(context);
- if (!LocalDatabaseService.preferences.developerMode) {
+
+ // TODO: we should probably enable database deletion in monkey tests
+ //as the new storage backend supports deletion without needing an app restart
+ if (!EnvironmentConfig.monkeyTest) {
await LocalDatabaseService.resetStorage();
}
}
diff --git a/src/ui/flutter_app/lib/screens/navigation_home_screen.dart b/src/ui/flutter_app/lib/screens/navigation_home_screen.dart
index 7a1b1291..20aef7d4 100644
--- a/src/ui/flutter_app/lib/screens/navigation_home_screen.dart
+++ b/src/ui/flutter_app/lib/screens/navigation_home_screen.dart
@@ -36,6 +36,7 @@ import 'package:sanmill/screens/help_screen.dart';
import 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
import 'package:sanmill/screens/rule_settings/rule_settings_page.dart';
import 'package:sanmill/services/engine/engine.dart';
+import 'package:sanmill/services/enviornment_config.dart';
import 'package:sanmill/services/storage/storage.dart';
import 'package:sanmill/shared/constants.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
@@ -103,7 +104,7 @@ class _NavigationHomeScreenState extends State {
} else if (drawerIndex == DrawerIndex.personalization) {
screenView = PersonalizationSettingsPage();
} else if (drawerIndex == DrawerIndex.feedback &&
- !LocalDatabaseService.preferences.developerMode) {
+ !EnvironmentConfig.monkeyTest) {
if (Platform.isWindows) {
debugPrint("flutter_email_sender does not support Windows.");
//_launchFeedback();
@@ -128,10 +129,10 @@ class _NavigationHomeScreenState extends State {
});
}
} else if (drawerIndex == DrawerIndex.Help &&
- !LocalDatabaseService.preferences.developerMode) {
+ !EnvironmentConfig.monkeyTest) {
screenView = HelpScreen();
} else if (drawerIndex == DrawerIndex.About &&
- !LocalDatabaseService.preferences.developerMode) {
+ !EnvironmentConfig.monkeyTest) {
screenView = AboutPage();
} else {
//do in your way......
diff --git a/src/ui/flutter_app/lib/services/enviornment_config.dart b/src/ui/flutter_app/lib/services/enviornment_config.dart
new file mode 100644
index 00000000..68afbef9
--- /dev/null
+++ b/src/ui/flutter_app/lib/services/enviornment_config.dart
@@ -0,0 +1,34 @@
+/*
+ This file is part of Sanmill.
+ Copyright (C) 2019-2021 The Sanmill developers (see AUTHORS file)
+
+ Sanmill is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Sanmill is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+/// Enviornment configutation
+///
+/// Enables devs to start the app with compile time options
+class EnvironmentConfig {
+ const EnvironmentConfig._();
+
+ /// gets weather we build for a monkey test
+ static const monkeyTest = bool.fromEnvironment('monkey_test');
+
+ /// gets weather we build for devMode
+ static const devMode = bool.fromEnvironment('dev_mode');
+
+ /// gets weather we want catcher to be enabled
+ /// defaults to true
+ static const catcher = bool.fromEnvironment('catcher', defaultValue: true);
+}
diff --git a/src/ui/flutter_app/lib/services/init_system_ui.dart b/src/ui/flutter_app/lib/services/init_system_ui.dart
new file mode 100644
index 00000000..6b7e52ad
--- /dev/null
+++ b/src/ui/flutter_app/lib/services/init_system_ui.dart
@@ -0,0 +1,43 @@
+/*
+ This file is part of Sanmill.
+ Copyright (C) 2019-2021 The Sanmill developers (see AUTHORS file)
+
+ Sanmill is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Sanmill is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+part of 'package:sanmill/main.dart';
+
+/// initializes the given [SystemChrome] ui
+void _initUI() {
+ debugPrint(window.physicalSize.toString());
+ debugPrint(Constants.windowAspectRatio.toString());
+
+ SystemChrome.setPreferredOrientations(
+ [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown],
+ );
+
+ if (Platform.isAndroid && isLargeScreen) {
+ SystemChrome.setSystemUIOverlayStyle(
+ const SystemUiOverlayStyle(
+ statusBarColor: Colors.transparent,
+ statusBarBrightness: Brightness.light,
+ statusBarIconBrightness: Brightness.dark,
+ systemNavigationBarColor: Colors.black,
+ systemNavigationBarIconBrightness: Brightness.dark,
+ ),
+ );
+ } else if (isSmallScreen) {
+ SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
+ }
+}