diff --git a/.gitignore b/.gitignore index d00fa56..f383006 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -# Created by https://www.toptal.com/developers/gitignore/api/flutter,visualstudiocode,windows -# Edit at https://www.toptal.com/developers/gitignore?templates=flutter,visualstudiocode,windows +# Created by https://www.toptal.com/developers/gitignore/api/flutter,linux,macos,visualstudiocode +# Edit at https://www.toptal.com/developers/gitignore?templates=flutter,linux,macos,visualstudiocode ### Flutter ### # Flutter/Dart/Pub related @@ -66,6 +66,54 @@ lib/generated_plugin_registrant.dart !**/ios/**/default.perspectivev3 !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + ### VisualStudioCode ### .vscode/* !.vscode/settings.json @@ -86,31 +134,9 @@ lib/generated_plugin_registrant.dart .ionide # Support for Project snippet scope +.vscode/*.code-snippets -### Windows ### -# Windows thumbnail cache files -Thumbs.db -Thumbs.db:encryptable -ehthumbs.db -ehthumbs_vista.db +# Ignore code-workspaces +*.code-workspace -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# End of https://www.toptal.com/developers/gitignore/api/flutter,visualstudiocode,windows +# End of https://www.toptal.com/developers/gitignore/api/flutter,linux,macos,visualstudiocode diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee..ec97fc6 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee..c4855bf 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 0000000..1e8c3c9 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000..6cb9f25 --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,53 @@ +PODS: + - connectivity_plus (0.0.1): + - Flutter + - ReachabilitySwift + - Flutter (1.0.0) + - flutter_secure_storage (3.3.1): + - Flutter + - path_provider_ios (0.0.1): + - Flutter + - ReachabilitySwift (5.0.0) + - shared_preferences_ios (0.0.1): + - Flutter + - url_launcher_ios (0.0.1): + - Flutter + +DEPENDENCIES: + - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) + - Flutter (from `Flutter`) + - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) + - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) + - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + +SPEC REPOS: + trunk: + - ReachabilitySwift + +EXTERNAL SOURCES: + connectivity_plus: + :path: ".symlinks/plugins/connectivity_plus/ios" + Flutter: + :path: Flutter + flutter_secure_storage: + :path: ".symlinks/plugins/flutter_secure_storage/ios" + path_provider_ios: + :path: ".symlinks/plugins/path_provider_ios/ios" + shared_preferences_ios: + :path: ".symlinks/plugins/shared_preferences_ios/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + +SPEC CHECKSUMS: + connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e + Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a + flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec + path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 + ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 + shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad + url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de + +PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c + +COCOAPODS: 1.11.3 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 37bc30b..dad830c 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + ECEF07EFF70219039EC91A16 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7322157B64E41A54727F1B5 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -42,6 +43,10 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B2721B88A12E59F3457F19ED /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + BC9FB05A1DCF7C7EFD0E5EBB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + DBABB66BE912BBC3B3B3D706 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + E7322157B64E41A54727F1B5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -49,12 +54,32 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + ECEF07EFF70219039EC91A16 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1CA2C3BE126DAC67B3E72712 /* Pods */ = { + isa = PBXGroup; + children = ( + B2721B88A12E59F3457F19ED /* Pods-Runner.debug.xcconfig */, + DBABB66BE912BBC3B3B3D706 /* Pods-Runner.release.xcconfig */, + BC9FB05A1DCF7C7EFD0E5EBB /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 8E9103B40D6588B574AD43FA /* Frameworks */ = { + isa = PBXGroup; + children = ( + E7322157B64E41A54727F1B5 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -72,6 +97,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, + 1CA2C3BE126DAC67B3E72712 /* Pods */, + 8E9103B40D6588B574AD43FA /* Frameworks */, ); sourceTree = ""; }; @@ -105,12 +132,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 3A5C4CD1EE7C597400A4EF9C /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + C63F8C1A7AF68913C333DE72 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -169,6 +198,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 3A5C4CD1EE7C597400A4EF9C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -197,6 +248,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + C63F8C1A7AF68913C333DE72 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -478,4 +546,4 @@ /* End XCConfigurationList section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; -} \ No newline at end of file +} diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index ff59184..e6d5fc7 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,6 +2,11 @@ + CFBundleLocalizations + + Czech + en + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -43,5 +48,7 @@ UIViewControllerBasedStatusBarAppearance + CADisableMinimumFrameDurationOnPhone + diff --git a/lib/lang/lang.dart b/lib/lang/lang.dart index ca36756..336d6c9 100644 --- a/lib/lang/lang.dart +++ b/lib/lang/lang.dart @@ -7,6 +7,8 @@ abstract class Languages { String get appName; + String get home; + // Login String get errorContacting; @@ -37,6 +39,8 @@ abstract class Languages { String get loginFailed; + String get warning; + // Jídelníček String get loading; @@ -99,6 +103,10 @@ abstract class Languages { String get order; + // About + + String get usedLibs; + // Settings String get settings; diff --git a/lib/lang/lang_cz.dart b/lib/lang/lang_cz.dart index cabf9dd..435d0cf 100644 --- a/lib/lang/lang_cz.dart +++ b/lib/lang/lang_cz.dart @@ -38,6 +38,9 @@ class LanguageCz extends Languages { @override String get friday => "Pátek"; + @override + String get home => "Domů"; + @override String get httpLogin => "Snažíte se přihlásit přes nešifrované spojení HTTP, jste si jisti, že tak chcete učinit?"; @@ -130,12 +133,18 @@ class LanguageCz extends Languages { @override String get tuesday => "Úterý"; + @override + String get usedLibs => "Použité knihovny:"; + @override String get username => "Uživatelské jméno"; @override String get verifyExchange => "Opravdu chcete vložit jídlo na burzu?"; + @override + String get warning => "Pozor!"; + @override String get wednesday => "Středa"; diff --git a/lib/lang/lang_en.dart b/lib/lang/lang_en.dart index 941f985..fc8665f 100644 --- a/lib/lang/lang_en.dart +++ b/lib/lang/lang_en.dart @@ -2,143 +2,153 @@ import 'package:opencanteen/lang/lang.dart'; class LanguageEn extends Languages { @override - String get about => "O Aplikaci"; + String get about => "About"; @override - String get agree => "Souhlasím"; + String get agree => "I agree"; @override String get appName => "OpenCanteen"; @override - String get balance => "Kredit: "; + String get balance => "Balance: "; @override - String get cannotOrder => "Nelze objednat"; + String get cannotOrder => "Cannot order"; @override - String get close => "Zavřít"; + String get close => "Close"; @override - String get disagree => "Nesouhlasím"; + String get disagree => "I disagree"; @override String get errorContacting => - "Nastala chyba při kontaktování serveru, zkontrolujte připojení"; + "Failed to contact the server, check your connection."; @override - String get errorOrdering => "Jídlo se nepodařilo objednat"; + String get errorOrdering => "Could not order food."; @override - String get exchange => "Burza"; + String get exchange => "Exchange"; @override - String get exchangeError => "Nepodařilo se vložit jídlo na burzu"; + String get exchangeError => "Could not put food on exchange."; @override - String get friday => "Pátek"; + String get friday => "Friday"; + + @override + String get home => "Home"; @override String get httpLogin => - "Snažíte se přihlásit přes nešifrované spojení HTTP, jste si jisti, že tak chcete učinit?"; + "You are trying to sign in using an insecure HTTP connection, are you sure you want to continue?"; @override String get iCanteenUrl => "iCanteen URL"; @override - String get inExchange => "V BURZE"; + String get inExchange => "ON EXCHANGE"; @override - String get loading => "Načítání..."; + String get loading => "Loading..."; @override - String get logIn => "Přihlášení"; + String get logIn => "Sign in"; @override - String get loggingIn => "Přihlašuji vás..."; + String get loggingIn => "Signing you in..."; @override - String get loginFailed => "Přihlášení se nezdařilo"; + String get loginFailed => "Sign in failed"; @override - String get menu => "Jídelníček"; + String get menu => "Food Menu"; @override - String get monday => "Pondělí"; + String get monday => "Monday"; @override - String get no => "Ne"; + String get no => "No"; @override - String get noChange => "Ne, změnit"; + String get noChange => "No, change"; @override - String get noExchange => "Žádné jídlo v burze"; + String get noExchange => "No meal in exchange"; @override - String get noFood => "Žádné jídlo pro tento den"; + String get noFood => "No meal for this day"; @override String get notOfficial => - "Toto není oficiální aplikace k ovládání iCanteen. Autor neručí za ztráty nebo nefunkčnost v souvislosti s používáním této aplikace. Tato zpráva se znovu neukáže."; + "This is not an official app for accessing iCanteen. The author is not responsible for non-functionality or losses while using this app. This message will not appear again."; @override String get ok => "OK"; @override - String get order => "Objednat"; + String get order => "Order"; @override - String get orderSuccess => "Jídlo bylo úspěšně objednáno"; + String get orderSuccess => "Meal ordered succesfully"; @override - String get ordered => "Objednáno"; + String get ordered => "Ordered"; @override - String get ordering => "Objednávám..."; + String get ordering => "Ordering..."; @override - String get password => "Heslo"; + String get password => "Password"; @override - String get pullToReload => "Potáhněte zvrchu pro načtení"; + String get pullToReload => "Pull to reload"; @override - String get rememberMe => "Zapamatovat si mě"; + String get rememberMe => "Remember me"; @override - String get reportBugs => "Nahlásit chybu"; + String get reportBugs => "Report bug"; @override - String get saturday => "Sobota"; + String get saturday => "Saturday"; @override - String get saveOffline => "Ukládat jídelníček na dnešní den offline"; + String get saveOffline => "Save today`s menu offline"; @override - String get settings => "Nastavení"; + String get settings => "Settings"; @override - String get signOut => "Odhlásit se"; + String get signOut => "Sign out"; @override - String get sunday => "Neděle"; + String get sunday => "Sunday"; @override - String get thursday => "Čtvrtek"; + String get thursday => "Thursday"; @override - String get tuesday => "Úterý"; + String get tuesday => "Tuesday"; @override - String get username => "Uživatelské jméno"; + String get usedLibs => "Used libraries:"; @override - String get verifyExchange => "Opravdu chcete vložit jídlo na burzu?"; + String get username => "Username"; @override - String get wednesday => "Středa"; + String get verifyExchange => + "Are you sure you want to put this meal on exchange?"; @override - String get yes => "Ano"; + String get warning => "Warning!"; + + @override + String get wednesday => "Wednesday"; + + @override + String get yes => "Yes"; } diff --git a/lib/main.dart b/lib/main.dart index d395983..d0a9852 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -43,8 +43,8 @@ class MyApp extends StatelessWidget { AppLocalizationsDelegate(), ...GlobalMaterialLocalizations.delegates ], - supportedLocales: const [Locale("cs"), Locale("en")], - title: 'OpenCanteen', + supportedLocales: const [Locale("cs", ""), Locale("en", "")], + title: "OpenCanteen", theme: ThemeData( primarySwatch: Colors.purple, ), @@ -78,9 +78,8 @@ class _LoginPageState extends State { if (connectivityResult == ConnectivityResult.none) { ScaffoldMessenger.of(context).hideCurrentSnackBar(); ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text( - "Nastala chyba při kontaktování serveru, zkontrolujte připojení"), + SnackBar( + content: Text(Languages.of(context)!.errorContacting), ), ); } @@ -92,12 +91,12 @@ class _LoginPageState extends State { builder: (_) => Dialog( child: SizedBox( height: 100, - child: Row(children: const [ - Padding( + child: Row(children: [ + const Padding( padding: EdgeInsets.all(10), child: CircularProgressIndicator(), ), - Text("Přihlašuji vás") + Text(Languages.of(context)!.loggingIn) ]), ), )); @@ -106,8 +105,8 @@ class _LoginPageState extends State { if (!l) { ScaffoldMessenger.of(context).hideCurrentSnackBar(); ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text("Přihlášení se nezdařilo, zkontrolujte údaje"), + SnackBar( + content: Text(Languages.of(context)!.loginFailed), ), ); return; @@ -128,7 +127,7 @@ class _LoginPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text("Přihlášení"), + title: Text(Languages.of(context)!.logIn), automaticallyImplyLeading: false, ), body: Center( @@ -138,31 +137,33 @@ class _LoginPageState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Text( - 'OpenCanteen', + Text( + Languages.of(context)!.logIn, textAlign: TextAlign.center, - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 40), + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 40), ), - const Text( - 'Přihlášení', + Text( + Languages.of(context)!.logIn, textAlign: TextAlign.center, ), TextField( controller: userControl, autofillHints: const [AutofillHints.username], - decoration: - const InputDecoration(labelText: 'Uživatelské jméno'), + decoration: InputDecoration( + labelText: Languages.of(context)!.username), ), TextField( autofillHints: const [AutofillHints.password], - decoration: const InputDecoration(labelText: 'Heslo'), + decoration: InputDecoration( + labelText: Languages.of(context)!.password), controller: passControl, obscureText: true, ), TextField( autofillHints: const [AutofillHints.url], - decoration: - const InputDecoration(labelText: 'iCanteen URL'), + decoration: InputDecoration( + labelText: Languages.of(context)!.iCanteenUrl), keyboardType: TextInputType.url, controller: canteenControl, ), @@ -174,7 +175,7 @@ class _LoginPageState extends State { rememberMe = value; }); }), - const Text("Zapamatovat si mě") + Text(Languages.of(context)!.rememberMe) ]), TextButton( onPressed: () async { @@ -183,19 +184,21 @@ class _LoginPageState extends State { var d = await showDialog( context: context, builder: (c) => AlertDialog( - title: const Text("Varování!"), - content: const SingleChildScrollView( + title: Text(Languages.of(context)!.warning), + content: SingleChildScrollView( child: Text( - "Snažíte se přihlásit přes nešifrované spojení HTTP, jste si jisti, že tak chcete učinit?")), + Languages.of(context)!.httpLogin)), actions: [ TextButton( onPressed: () => Navigator.pop(c, true), - child: const Text("Ano")), + child: + Text(Languages.of(context)!.yes)), TextButton( onPressed: () => Navigator.pop(c, false), - child: const Text("Ne, změnit")) + child: Text( + Languages.of(context)!.noChange)) ], )); if (!d!) return; @@ -208,19 +211,21 @@ class _LoginPageState extends State { var d = await showDialog( context: context, builder: (c) => AlertDialog( - title: const Text("Pozor"), - content: const SingleChildScrollView( - child: Text( - "Toto není oficiální aplikace k ovládání iCanteen. Autor neručí za ztráty nebo nefunkčnost v souvislosti s používáním této aplikace. Tato zpráva se znovu neukáže.")), + title: Text(Languages.of(context)!.warning), + content: SingleChildScrollView( + child: Text(Languages.of(context)! + .notOfficial)), actions: [ TextButton( onPressed: () => Navigator.pop(c, true), - child: const Text("Souhlasím")), + child: Text( + Languages.of(context)!.agree)), TextButton( onPressed: () => Navigator.pop(c, false), - child: const Text("Nesouhlasím")) + child: Text( + Languages.of(context)!.disagree)) ], )); if (!d!) return; @@ -237,9 +242,8 @@ class _LoginPageState extends State { if (!l) { ScaffoldMessenger.of(context).hideCurrentSnackBar(); ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text( - "Přihlášení se nezdařilo, zkontrolujte údaje"), + SnackBar( + content: Text(Languages.of(context)!.loginFailed), ), ); return; @@ -257,7 +261,7 @@ class _LoginPageState extends State { )), ); }, - child: const Text("Přihlásit se")), + child: Text(Languages.of(context)!.logIn)), ], ), ), @@ -276,6 +280,7 @@ class AppLocalizationsDelegate extends LocalizationsDelegate { Future load(Locale locale) => _load(locale); static Future _load(Locale locale) async { + debugPrint(locale.countryCode); switch (locale.languageCode) { case 'cs': return LanguageCz(); diff --git a/lib/okna/about.dart b/lib/okna/about.dart index 0903b42..607efa9 100644 --- a/lib/okna/about.dart +++ b/lib/okna/about.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; +import '../lang/lang.dart'; + class AboutPage extends StatefulWidget { const AboutPage({Key? key}) : super(key: key); @@ -13,7 +15,7 @@ class _AboutPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text("O Aplikaci"), + title: Text(Languages.of(context)!.about), ), body: SingleChildScrollView( child: SizedBox( @@ -26,7 +28,8 @@ class _AboutPageState extends State { "https://github.com/hernikplays/opencanteen/blob/main/LICENSE"), child: const Text("Vydáno pod licencí GNU GPLv3")), const SizedBox(height: 15), - const Text("Použité knihovny:", style: TextStyle(fontSize: 19)), + Text(Languages.of(context)!.usedLibs, + style: const TextStyle(fontSize: 19)), const SizedBox(height: 10), cudlik( "Flutter", diff --git a/lib/okna/burza.dart b/lib/okna/burza.dart index f5787c6..20c94a8 100644 --- a/lib/okna/burza.dart +++ b/lib/okna/burza.dart @@ -2,6 +2,7 @@ import 'package:canteenlib/canteenlib.dart'; import 'package:flutter/material.dart'; import 'package:opencanteen/util.dart'; +import '../lang/lang.dart'; import '../main.dart'; class BurzaPage extends StatefulWidget { @@ -16,7 +17,7 @@ class BurzaPage extends StatefulWidget { class _BurzaPageState extends State { List obsah = []; double kredit = 0.0; - Future nactiBurzu() async { + Future nactiBurzu(BuildContext context) async { obsah = [const CircularProgressIndicator()]; widget.canteen.ziskejUzivatele().then((kr) { kredit = kr.kredit; @@ -25,11 +26,11 @@ class _BurzaPageState extends State { obsah = []; if (burza.isEmpty) { obsah = [ - const Text( - "Žádné jídlo v burze.", - style: TextStyle(fontSize: 20), + Text( + Languages.of(context)!.noExchange, + style: const TextStyle(fontSize: 20), ), - const Text("Potáhněte zvrchu pro načtení.") + Text(Languages.of(context)!.pullToReload) ]; } else { for (var b in burza) { @@ -54,12 +55,12 @@ class _BurzaPageState extends State { showDialog( context: context, builder: (context) => AlertDialog( - title: const Text("Objednáno"), - content: const Text( - "Jídlo bylo úspěšně objednáno."), + title: Text(Languages.of(context)!.ordered), + content: Text( + Languages.of(context)!.orderSuccess), actions: [ TextButton( - child: const Text("OK"), + child: Text(Languages.of(context)!.ok), onPressed: () => Navigator.of(context).pop(), ) @@ -70,12 +71,13 @@ class _BurzaPageState extends State { showDialog( context: context, builder: (context) => AlertDialog( - title: const Text("Nelze objednat"), - content: const Text( - "Jídlo se nepodařilo objednat."), + title: Text( + Languages.of(context)!.cannotOrder), + content: Text( + Languages.of(context)!.errorOrdering), actions: [ TextButton( - child: const Text("OK"), + child: Text(Languages.of(context)!.ok), onPressed: () => Navigator.of(context).pop(), ) @@ -83,10 +85,10 @@ class _BurzaPageState extends State { ), ); } - nactiBurzu(); + nactiBurzu(context); }); }, - child: const Text("Objednat")), + child: Text(Languages.of(context)!.order)), ], ), ), @@ -106,7 +108,7 @@ class _BurzaPageState extends State { @override void initState() { super.initState(); - nactiBurzu(); + nactiBurzu(context); } @override @@ -114,14 +116,14 @@ class _BurzaPageState extends State { return Scaffold( drawer: drawerGenerator(context, widget.canteen, widget.user, 3), appBar: AppBar( - title: const Text('Burza'), + title: Text(Languages.of(context)!.exchange), ), body: RefreshIndicator( child: Center( child: Column( children: [ const SizedBox(height: 10), - Text("Kredit: $kredit Kč"), + Text("${Languages.of(context)!.balance}$kredit Kč"), const SizedBox(height: 10), SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), @@ -133,7 +135,7 @@ class _BurzaPageState extends State { ], ), ), - onRefresh: () => nactiBurzu()), + onRefresh: () => nactiBurzu(context)), ); } } diff --git a/lib/okna/jidelnicek.dart b/lib/okna/jidelnicek.dart index b843eae..9594fb9 100644 --- a/lib/okna/jidelnicek.dart +++ b/lib/okna/jidelnicek.dart @@ -9,6 +9,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:url_launcher/url_launcher.dart'; +import '../lang/lang.dart'; import '../main.dart'; import 'about.dart'; @@ -22,7 +23,7 @@ class JidelnicekPage extends StatefulWidget { } class _JidelnicekPageState extends State { - List obsah = [const Text("Načítám...")]; + List obsah = [const CircularProgressIndicator()]; DateTime den = DateTime.now(); String denTydne = ""; double kredit = 0.0; @@ -30,25 +31,25 @@ class _JidelnicekPageState extends State { obsah = [const CircularProgressIndicator()]; switch (den.weekday) { case 2: - denTydne = "Úterý"; + denTydne = Languages.of(context)!.tuesday; break; case 3: - denTydne = "Středa"; + denTydne = Languages.of(context)!.wednesday; break; case 4: - denTydne = "Čtvrtek"; + denTydne = Languages.of(context)!.thursday; break; case 5: - denTydne = "Pátek"; + denTydne = Languages.of(context)!.friday; break; case 6: - denTydne = "Sobota"; + denTydne = Languages.of(context)!.saturday; break; case 7: - denTydne = "Neděle"; + denTydne = Languages.of(context)!.sunday; break; default: - denTydne = "Pondělí"; + denTydne = Languages.of(context)!.monday; } widget.canteen.ziskejUzivatele().then((kr) { kredit = kr.kredit; @@ -56,9 +57,9 @@ class _JidelnicekPageState extends State { setState(() { obsah = []; if (jd.jidla.isEmpty) { - obsah.add(const Text( - "Žádné jídlo pro tento den", - style: TextStyle(fontSize: 15), + obsah.add(Text( + Languages.of(context)!.noFood, + style: const TextStyle(fontSize: 15), )); } else { for (var j in jd.jidla) { @@ -76,7 +77,9 @@ class _JidelnicekPageState extends State { j.nazev, ), ), - Text((j.naBurze) ? "V BURZE" : "${j.cena} Kč"), + Text((j.naBurze) + ? Languages.of(context)!.inExchange + : "${j.cena} Kč"), Checkbox( value: j.objednano, fillColor: (j.lzeObjednat) @@ -95,12 +98,12 @@ class _JidelnicekPageState extends State { builder: (_) => Dialog( child: SizedBox( height: 100, - child: Row(children: const [ - Padding( + child: Row(children: [ + const Padding( padding: EdgeInsets.all(10), child: CircularProgressIndicator(), ), - Text("Objednávám...") + Text(Languages.of(context)!.ordering) ]), ), )); @@ -112,12 +115,12 @@ class _JidelnicekPageState extends State { showDialog( context: context, builder: (bc) => AlertDialog( - title: const Text( - "Jídlo se nepodařilo objednat."), + title: Text( + Languages.of(context)!.errorOrdering), content: Text(o.toString()), actions: [ TextButton( - child: const Text("Zavřít"), + child: Text(Languages.of(context)!.close), onPressed: () { Navigator.pop(bc); }, @@ -133,20 +136,20 @@ class _JidelnicekPageState extends State { var d = await showDialog( context: context, builder: (bc) => SimpleDialog( - title: const Text( - "Opravdu chcete vložit jídlo na burzu?"), + title: Text( + Languages.of(context)!.verifyExchange), children: [ SimpleDialogOption( onPressed: () { Navigator.pop(bc, true); }, - child: const Text("Ano"), + child: Text(Languages.of(context)!.yes), ), SimpleDialogOption( onPressed: () { Navigator.pop(bc, false); }, - child: const Text("Ne"), + child: Text(Languages.of(context)!.no), ), ], )); @@ -158,12 +161,13 @@ class _JidelnicekPageState extends State { showDialog( context: context, builder: (bc) => AlertDialog( - title: const Text( - "Nepodařilo se vložit jídlo na burzu"), + title: Text( + Languages.of(context)!.exchangeError), content: Text(o.toString()), actions: [ TextButton( - child: const Text("Zavřít"), + child: Text( + Languages.of(context)!.close), onPressed: () { Navigator.pop(bc); }, @@ -192,21 +196,17 @@ class _JidelnicekPageState extends State { }); } - void kliknuti(String value) { - switch (value) { - case 'Odhlásit se': - const storage = FlutterSecureStorage(); - storage.deleteAll(); - Navigator.pushReplacement( - context, MaterialPageRoute(builder: (c) => const LoginPage())); - break; - case 'Nahlásit chybu': - launch("https://github.com/hernikplays/opencanteen/issues/new/choose"); - break; - case 'O Aplikaci': - Navigator.push( - context, MaterialPageRoute(builder: (c) => const AboutPage())); - break; + void kliknuti(String value, BuildContext context) { + if (value == Languages.of(context)!.signOut) { + const storage = FlutterSecureStorage(); + storage.deleteAll(); + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (c) => const LoginPage())); + } else if (value == Languages.of(context)!.reportBugs) { + launch("https://github.com/hernikplays/opencanteen/issues/new/choose"); + } else if (value == Languages.of(context)!.about) { + Navigator.push( + context, MaterialPageRoute(builder: (c) => const AboutPage())); } } @@ -241,8 +241,8 @@ class _JidelnicekPageState extends State { } @override - void initState() { - super.initState(); + void didChangeDependencies() { + super.didChangeDependencies(); ulozitDnesekOffline(); nactiJidlo(); } @@ -252,13 +252,16 @@ class _JidelnicekPageState extends State { return Scaffold( drawer: drawerGenerator(context, widget.canteen, widget.user, 1), appBar: AppBar( - title: const Text('Jídelníček'), + title: Text(Languages.of(context)!.menu), actions: [ PopupMenuButton( - onSelected: kliknuti, + onSelected: ((String value) => kliknuti(value, context)), itemBuilder: (BuildContext context) { - return {'Nahlásit chybu', 'O Aplikaci', 'Odhlásit se'} - .map((String choice) { + return { + Languages.of(context)!.reportBugs, + Languages.of(context)!.about, + Languages.of(context)!.signOut + }.map((String choice) { return PopupMenuItem( value: choice, child: Text(choice), @@ -274,7 +277,7 @@ class _JidelnicekPageState extends State { child: Column( children: [ const SizedBox(height: 10), - Text("Kredit: $kredit Kč"), + Text("${Languages.of(context)!.balance}$kredit Kč"), Row(mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( onPressed: () { diff --git a/lib/util.dart b/lib/util.dart index 027ca03..aa0f312 100644 --- a/lib/util.dart +++ b/lib/util.dart @@ -2,6 +2,7 @@ import 'package:canteenlib/canteenlib.dart'; import 'package:flutter/material.dart'; import 'package:opencanteen/okna/burza.dart'; +import 'lang/lang.dart'; import 'okna/jidelnicek.dart'; Drawer drawerGenerator( @@ -13,18 +14,18 @@ Drawer drawerGenerator( drawer = Drawer( child: ListView( children: [ - const DrawerHeader( - child: Text("OpenCanteen"), + DrawerHeader( + child: Text(Languages.of(context)!.appName), ), ListTile( selected: true, - title: const Text("Domů"), + title: Text(Languages.of(context)!.home), leading: const Icon(Icons.home), onTap: () => Navigator.pop(context), ), ListTile( leading: const Icon(Icons.store), - title: const Text('Burza'), + title: Text(Languages.of(context)!.exchange), onTap: () => Navigator.push( context, MaterialPageRoute( @@ -41,12 +42,12 @@ Drawer drawerGenerator( drawer = Drawer( child: ListView( children: [ - const DrawerHeader( - child: Text("OpenCanteen"), + DrawerHeader( + child: Text(Languages.of(context)!.appName), ), ListTile( leading: const Icon(Icons.home), - title: const Text("Domů"), + title: Text(Languages.of(context)!.home), onTap: () => Navigator.push( context, MaterialPageRoute( @@ -56,7 +57,7 @@ Drawer drawerGenerator( ListTile( leading: const Icon(Icons.store), selected: true, - title: const Text('Burza'), + title: Text(Languages.of(context)!.exchange), onTap: () => Navigator.pop(context), ), ], diff --git a/pubspec.lock b/pubspec.lock index c2025eb..6c2709e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -56,7 +56,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0" + version: "1.16.0" connectivity_plus: dependency: "direct main" description: @@ -232,7 +232,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3" + version: "0.6.4" lints: dependency: transitive description: @@ -246,7 +246,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "0.1.4" meta: dependency: transitive description: @@ -267,7 +267,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" path_provider: dependency: "direct main" description: @@ -496,7 +496,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.2" win32: dependency: transitive description: @@ -526,5 +526,5 @@ packages: source: hosted version: "3.1.0" sdks: - dart: ">=2.16.1 <3.0.0" + dart: ">=2.17.0-0 <3.0.0" flutter: ">=2.10.0"