From 13877f0a7622fbcdedbb465cdae632b0447d3ade Mon Sep 17 00:00:00 2001 From: Ferry-200 Date: Sun, 1 Sep 2024 22:34:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=8A=E9=A1=B9=E7=9B=AE=E7=A7=BB=E8=87=B3?= =?UTF-8?q?=20Flutter=20=E7=9B=AE=E5=BD=95=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- summer-ospp/2024/Flutter/changelog.md | 179 +++++ .../2024/Flutter/maxkey_flutter/.metadata | 36 + .../maxkey_flutter/.vscode/settings.json | 3 + .../2024/Flutter/maxkey_flutter/README.md | 46 ++ .../maxkey_flutter/analysis_options.yaml | 4 + .../maxkey_flutter/android/app/build.gradle | 58 ++ .../android/app/src/debug/AndroidManifest.xml | 8 + .../android/app/src/main/AndroidManifest.xml | 47 ++ .../maxkey/maxkey_flutter/MainActivity.kt | 5 + .../res/drawable-v21/launch_background.xml | 12 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2783 bytes .../src/main/res/mipmap-ldpi/ic_launcher.png | Bin 0 -> 1596 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2163 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 3813 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6116 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 8429 bytes .../app/src/main/res/playstore-icon.png | Bin 0 -> 27372 bytes .../app/src/main/res/values-night/styles.xml | 18 + .../app/src/main/res/values/styles.xml | 18 + .../app/src/profile/AndroidManifest.xml | 7 + .../maxkey_flutter/android/build.gradle | 18 + .../maxkey_flutter/android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 5 + .../maxkey_flutter/android/settings.gradle | 25 + .../Flutter/maxkey_flutter/assets/logo.jpg | Bin 0 -> 48435 bytes .../maxkey_flutter/assets/logo_maxkey.png | Bin 0 -> 144941 bytes .../ios/Flutter/AppFrameworkInfo.plist | 26 + .../maxkey_flutter/ios/Flutter/Debug.xcconfig | 1 + .../ios/Flutter/Release.xcconfig | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 616 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 98 +++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../ios/Runner/AppDelegate.swift | 13 + .../AppIcon.appiconset/Contents.json | 120 ++++ .../AppIcon.appiconset/icon-1024.png | Bin 0 -> 78138 bytes .../AppIcon.appiconset/icon-20@2x.png | Bin 0 -> 1564 bytes .../AppIcon.appiconset/icon-20@3x.png | Bin 0 -> 2567 bytes .../AppIcon.appiconset/icon-29@2x.png | Bin 0 -> 2500 bytes .../AppIcon.appiconset/icon-29@3x.png | Bin 0 -> 3819 bytes .../AppIcon.appiconset/icon-38@2x.png | Bin 0 -> 3243 bytes .../AppIcon.appiconset/icon-38@3x.png | Bin 0 -> 5047 bytes .../AppIcon.appiconset/icon-40@2x.png | Bin 0 -> 3406 bytes .../AppIcon.appiconset/icon-40@3x.png | Bin 0 -> 5453 bytes .../AppIcon.appiconset/icon-60@2x.png | Bin 0 -> 5453 bytes .../AppIcon.appiconset/icon-60@3x.png | Bin 0 -> 8479 bytes .../AppIcon.appiconset/icon-64@2x.png | Bin 0 -> 5760 bytes .../AppIcon.appiconset/icon-64@3x.png | Bin 0 -> 9197 bytes .../AppIcon.appiconset/icon-68@2x.png | Bin 0 -> 6209 bytes .../AppIcon.appiconset/icon-76@2x.png | Bin 0 -> 6922 bytes .../AppIcon.appiconset/icon-83.5@2x.png | Bin 0 -> 7787 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + .../Runner/Base.lproj/LaunchScreen.storyboard | 37 ++ .../ios/Runner/Base.lproj/Main.storyboard | 26 + .../maxkey_flutter/ios/Runner/Info.plist | 49 ++ .../ios/Runner/Runner-Bridging-Header.h | 1 + .../ios/RunnerTests/RunnerTests.swift | 12 + .../2024/Flutter/maxkey_flutter/l10n.yaml | 3 + .../maxkey_flutter/lib/app_color_scheme.dart | 105 +++ .../maxkey_flutter/lib/l10n/app_en.arb | 66 ++ .../maxkey_flutter/lib/l10n/app_zh.arb | 66 ++ .../2024/Flutter/maxkey_flutter/lib/main.dart | 97 +++ .../maxkey_flutter/lib/maxkey/maxkey.dart | 90 +++ .../lib/maxkey/services/authn.service.dart | 161 +++++ .../services/image_captcha.service.dart | 27 + .../maxkey/services/time_based.service.dart | 29 + .../lib/maxkey/services/users.service.dart | 245 +++++++ .../home_page/components/new_totp_btn.dart | 58 ++ .../home_page/components/totp_list_view.dart | 250 +++++++ .../pages/home_page/components/user_card.dart | 206 ++++++ .../lib/pages/home_page/page.dart | 74 +++ .../login_page/components/captcha_view.dart | 49 ++ .../login_page/components/login_view.dart | 95 +++ .../lib/pages/login_page/page.dart | 82 +++ .../maxkey_flutter/lib/pages/scan_page.dart | 145 +++++ .../components/host_setting.dart | 98 +++ .../components/show_log_btn.dart | 56 ++ .../components/theme_mode_setting.dart | 38 ++ .../lib/pages/settings_page/page.dart | 66 ++ .../user_page/full_user_info_dialog.dart | 51 ++ .../lib/pages/user_page/page.dart | 136 ++++ .../maxkey_flutter/lib/persistent.dart | 87 +++ .../lib/repeat_tween_animation_builder.dart | 55 ++ .../2024/Flutter/maxkey_flutter/lib/totp.dart | 55 ++ .../Flutter/maxkey_flutter/lib/utils.dart | 34 + .../2024/Flutter/maxkey_flutter/pubspec.lock | 431 ++++++++++++ .../2024/Flutter/maxkey_flutter/pubspec.yaml | 33 + .../maxkey_flutter/windows/CMakeLists.txt | 108 +++ .../windows/flutter/CMakeLists.txt | 109 ++++ .../flutter/generated_plugin_registrant.cc | 11 + .../flutter/generated_plugin_registrant.h | 15 + .../windows/flutter/generated_plugins.cmake | 23 + .../windows/runner/CMakeLists.txt | 40 ++ .../maxkey_flutter/windows/runner/Runner.rc | 121 ++++ .../windows/runner/flutter_window.cpp | 71 ++ .../windows/runner/flutter_window.h | 33 + .../maxkey_flutter/windows/runner/main.cpp | 43 ++ .../maxkey_flutter/windows/runner/resource.h | 16 + .../windows/runner/resources/app_icon.ico | Bin 0 -> 33772 bytes .../windows/runner/runner.exe.manifest | 20 + .../maxkey_flutter/windows/runner/utils.cpp | 65 ++ .../maxkey_flutter/windows/runner/utils.h | 19 + .../windows/runner/win32_window.cpp | 288 ++++++++ .../windows/runner/win32_window.h | 102 +++ 113 files changed, 5650 insertions(+) create mode 100644 summer-ospp/2024/Flutter/changelog.md create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/.metadata create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/.vscode/settings.json create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/README.md create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/analysis_options.yaml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/build.gradle create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/debug/AndroidManifest.xml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/AndroidManifest.xml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/kotlin/org/dromara/maxkey/maxkey_flutter/MainActivity.kt create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/drawable/launch_background.xml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-ldpi/ic_launcher.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/playstore-icon.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/values-night/styles.xml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/values/styles.xml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/profile/AndroidManifest.xml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/build.gradle create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/gradle.properties create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/android/settings.gradle create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/assets/logo.jpg create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/assets/logo_maxkey.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/AppFrameworkInfo.plist create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/Debug.xcconfig create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/Release.xcconfig create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.pbxproj create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/AppDelegate.swift create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-38@3x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-64@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-64@3x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-68@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Base.lproj/Main.storyboard create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Info.plist create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Runner-Bridging-Header.h create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/ios/RunnerTests/RunnerTests.swift create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/l10n.yaml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/app_color_scheme.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/l10n/app_en.arb create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/l10n/app_zh.arb create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/main.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/maxkey.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/authn.service.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/image_captcha.service.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/time_based.service.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/users.service.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/new_totp_btn.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/totp_list_view.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/user_card.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/page.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/components/captcha_view.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/components/login_view.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/page.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/scan_page.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/host_setting.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/show_log_btn.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/theme_mode_setting.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/page.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/user_page/full_user_info_dialog.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/user_page/page.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/persistent.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/repeat_tween_animation_builder.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/totp.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/lib/utils.dart create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/pubspec.lock create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/pubspec.yaml create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/CMakeLists.txt create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/CMakeLists.txt create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugin_registrant.cc create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugin_registrant.h create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugins.cmake create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/CMakeLists.txt create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/Runner.rc create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/flutter_window.cpp create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/flutter_window.h create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/main.cpp create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/resource.h create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/resources/app_icon.ico create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/runner.exe.manifest create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/utils.cpp create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/utils.h create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/win32_window.cpp create mode 100644 summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/win32_window.h diff --git a/summer-ospp/2024/Flutter/changelog.md b/summer-ospp/2024/Flutter/changelog.md new file mode 100644 index 000000000..ba1b2f47b --- /dev/null +++ b/summer-ospp/2024/Flutter/changelog.md @@ -0,0 +1,179 @@ +2024-09-01T21:01:16+08:00 +- [Update .gitignore](https://gitee.com/biyanci/MaxKey/commit/1643f9608d61e59b0eaf6fb76b2e610b81e6b250) + +2024-09-01T20:30:30+08:00 +- [Update README.md](https://gitee.com/biyanci/MaxKey/commit/66d9fc38c901a52e76a91fb886c6e691f32dfc21) + +2024-09-01T20:29:51+08:00 +- [提供多语言支持。包括中文和英文](https://gitee.com/biyanci/MaxKey/commit/ab8517bf723062d1428476adeade4a1a9bb2833a) + +2024-09-01T17:31:21+08:00 +- [在切换账户时读取 totp](https://gitee.com/biyanci/MaxKey/commit/4b96be9e28d945bff6454b607c6479fc8de14763) +- [v1.0.0](https://gitee.com/biyanci/MaxKey/commit/41d2e10bf3771960e427a401bc27eb2bd25aa737) + +2024-09-01T17:23:14+08:00 +- [在 user card 加载时也显示箭头图标](https://gitee.com/biyanci/MaxKey/commit/302fcedcf99067cbf23cb7c3eaf95a545465f7b9) + +2024-09-01T17:21:05+08:00 +- [不再把 MaxKey 的 totp 特别对待](https://gitee.com/biyanci/MaxKey/commit/93f7e71f17844253dc6e4e0bded70a469e467b37) + +2024-09-01T16:41:46+08:00 +- [use auth_totp instead of totp.](https://gitee.com/biyanci/MaxKey/commit/a8854c12ad9b097fdf96a144dd9d51ade1b9f037) + +2024-09-01T16:07:47+08:00 +- [避免重复构造 totp](https://gitee.com/biyanci/MaxKey/commit/d4fa845c19ccb034c158c6ca519e5e7a2170b4b2) +- [upgrade flutter sdk to 3.24](https://gitee.com/biyanci/MaxKey/commit/014a3b8e0dbdb522826c5e3206cfeac23c7067c2) + +2024-08-29T22:07:18+08:00 +- [保证 normalTotps 的返回值不为空](https://gitee.com/biyanci/MaxKey/commit/5048e521160fe01213ab5afa56699b9d0e9ec312) + +2024-08-29T21:51:51+08:00 +- [更新 Readme](https://gitee.com/biyanci/MaxKey/commit/be96e50066b8faf9c769ba844d4243ff073f9fa7) + +2024-08-29T21:51:19+08:00 +- [添加查看 Log 页面](https://gitee.com/biyanci/MaxKey/commit/f846e8806ab20e03f1a360d56f74c800f612b35e) + +2024-08-29T21:35:15+08:00 +- [提取函数](https://gitee.com/biyanci/MaxKey/commit/f782adead1ec04e91f4d8ee705d9d7cb8a946b32) +- [在登陆状态过期时提示重新登陆](https://gitee.com/biyanci/MaxKey/commit/29b907b14c74a8c06059fab873311d2d4111dabc) + +2024-08-29T21:04:35+08:00 +- [dart format](https://gitee.com/biyanci/MaxKey/commit/0d62f3fc612c8880c911714917cacce33614d7c3) + +2024-08-29T20:54:34+08:00 +- [支持第三方时间令牌](https://gitee.com/biyanci/MaxKey/commit/356251c0b424af39318c8ddb6f5fc6accadf9cb6) +- [优化时间令牌标签内容;修复一些兼容性问题](https://gitee.com/biyanci/MaxKey/commit/edcee1ef5f122dffb4e7e4eb35a8dbf63c61edd1) + +2024-08-29T15:41:23+08:00 +- [优化设置页代码目录结构](https://gitee.com/biyanci/MaxKey/commit/7c1880434df5c45893d61ce41626bbb2a2a3befb) +- [优化登录页代码目录结构;删除无用的 otp_count_down_view](https://gitee.com/biyanci/MaxKey/commit/dd740fe4221c5a3066ccd3ad80023cbf318f3ad6) + +2024-08-29T15:21:06+08:00 +- [去除 log 浮窗](https://gitee.com/biyanci/MaxKey/commit/b22214982d5356738048e49943ebb55412ebd2ad) + +2024-08-29T14:41:07+08:00 +- [把 MaxKey 改造成单例;提供更新 baseurl 的方法;更新 baseurl 后通知组件刷新](https://gitee.com/biyanci/MaxKey/commit/69a3ce9144a1d8eec9beb6f04224582b311152d3) +- [新增设置页;把修改主机功能移至设置](https://gitee.com/biyanci/MaxKey/commit/684ac1cd00f946d701c1775d2b1c0c53bf8172bf) + +2024-08-29T00:32:22+08:00 +- [允许修改主题模式;修复一些热重载时的奇怪问题](https://gitee.com/biyanci/MaxKey/commit/91e5121cf1f6f8ea40dc67b2728739b43a6cac73) + +2024-08-28T20:16:39+08:00 +- [新增用户页;提供查看用户详细信息的功能;把退出账号移至用户页](https://gitee.com/biyanci/MaxKey/commit/e1c023caaf08404a0b3fdfd9be61a1ff49028963) + +2024-08-27T21:14:04+08:00 +- [修复热重载时可能出现的异常情况](https://gitee.com/biyanci/MaxKey/commit/843e9c5c95f0ee3f1760a42675c3181dd0f2a5c8) + +2024-08-27T21:00:54+08:00 +- [Delete app_list.service.dart](https://gitee.com/biyanci/MaxKey/commit/b0951d69995b45928fadcdd0b73e21c8b3aa3585) +- [优化应用数据持久化逻辑](https://gitee.com/biyanci/MaxKey/commit/92b42e78a7314155dd442214f0f269b036f16b50) + +2024-08-26T23:33:04+08:00 +- [更新 ReadMe](https://gitee.com/biyanci/MaxKey/commit/7df25ba58033018d71dc12b85e90725d7b6c982a) + +2024-08-26T22:39:12+08:00 +- [让主题跟随系统日夜间模式](https://gitee.com/biyanci/MaxKey/commit/7c2c59eab0c7151652a6369d82977dea352d152e) + +2024-08-26T22:31:37+08:00 +- [去除手机验证码登陆功能](https://gitee.com/biyanci/MaxKey/commit/ea9b6410ee649deb8732321671545aba421a23c6) +- [去除访问 web app 功能](https://gitee.com/biyanci/MaxKey/commit/b963998066c42dc81cb9ba5bbd3a6d54c7357dbd) + +2024-08-26T22:09:06+08:00 +- [新增验证 MaxKey totp 的方法;在添加 MaxKey 的 totp 时自动验证正确性](https://gitee.com/biyanci/MaxKey/commit/311348f6be356426c74c066dc063d7b8cc18bb23) + +2024-08-26T20:30:29+08:00 +- [去除不需要的访问 web app 的功能](https://gitee.com/biyanci/MaxKey/commit/85933bbbb93c5386eccc5c73d5f32bf5d9a14ecc) + +2024-08-23T00:31:26+08:00 +- [提供修改主机地址的功能](https://gitee.com/biyanci/MaxKey/commit/b62f60c4e24b6128a31357fd2cbb0d6e21d19eaf) +- [完善错误处理和日志输出;跟进 MaxKey Api](https://gitee.com/biyanci/MaxKey/commit/f1625f521951c202820396514b53dc8c38a9d74e) + +2024-08-22T16:36:07+08:00 +- [使用 MaxKey LOGO 作为应用图标](https://gitee.com/biyanci/MaxKey/commit/7d8d808bbfe67b6a64750544d9bb0c6ab87d7fc1) + +2024-07-22T13:25:26+08:00 +- [去掉没用的大小限制;使用圆角矩形作为加载中的 app icon](https://gitee.com/biyanci/MaxKey/commit/63fa5708b858279dc93a77e13eea7bcd81194f50) +- [更正 添加时间令牌 按钮的圆角](https://gitee.com/biyanci/MaxKey/commit/83bf46ee2edacc4be7271afa0e705e60f1a234d1) + +2024-07-20T17:14:14+08:00 +- [Create repeat_tween_animation_builder.dart](https://gitee.com/biyanci/MaxKey/commit/f39031c3e6027ec35bd50a8c0b909ee45ba3e3ba) +- [新增 loading user card 组件,在加载时替代 user card 使用](https://gitee.com/biyanci/MaxKey/commit/03dde4c16b1c67e324b9176b9c9e6ef45976b2ff) + +2024-07-20T15:21:53+08:00 +- [减少不必要的重新请求](https://gitee.com/biyanci/MaxKey/commit/cecab3e68d2673ea9ea07f3c30c8e0e10dccf2b2) +- [保存 dio 获取到的 cookie](https://gitee.com/biyanci/MaxKey/commit/4d843a3b06ef3e94f245c75196de2886873ba78c) + +2024-07-17T17:14:22+08:00 +- [更新待做](https://gitee.com/biyanci/MaxKey/commit/8c6f3855b886a5f607c490332295471b7e2e14bd) + +2024-07-17T17:11:55+08:00 +- [等待logout结束](https://gitee.com/biyanci/MaxKey/commit/c50cd8fe12d96acc292621747d882a55e9dad2fb) + +2024-07-17T17:01:24+08:00 +- [完善没有摄像头权限时的提示](https://gitee.com/biyanci/MaxKey/commit/2dd9e98d495705f002a16792204d6a24abd6c581) +- [在重试时复用之前的 header](https://gitee.com/biyanci/MaxKey/commit/cab0b37234259b40375aa87c7ba3e66b93d19040) + +2024-07-16T23:21:00+08:00 +- [debug manifest 允许 http](https://gitee.com/biyanci/MaxKey/commit/c9dddf095630386de41d3141daea18240c84f697) +- [release manifest 应用名称、允许 http、允许联网](https://gitee.com/biyanci/MaxKey/commit/f963d77ae9ab83fb13c1fa732627c8ab9e1c4678) + +2024-07-14T15:30:29+08:00 +- [更正拼写](https://gitee.com/biyanci/MaxKey/commit/5b695c0f488f47ea0dbd3cd34616a9d4f2bd0aa7) + +2024-07-14T13:56:10+08:00 +- [删除多余的函数](https://gitee.com/biyanci/MaxKey/commit/4ac10a408b6abdd99d9b3c41be5746ae0906f1fa) +- [更正设置 header 的方法](https://gitee.com/biyanci/MaxKey/commit/24f1da2a685dd2a0fc71a9365475e17ea7552274) + +2024-07-14T13:22:32+08:00 +- [修改函数命名](https://gitee.com/biyanci/MaxKey/commit/59659a35fbb9ea736256912125957a3f0edf08fb) + +2024-07-14T13:21:35+08:00 +- [默认使用手动设置的 host ip](https://gitee.com/biyanci/MaxKey/commit/53abfe3cdcf17016908d9a6645ddbb10df49497a) + +2024-07-09T17:35:28+08:00 +- [去掉无意义的写入操作](https://gitee.com/biyanci/MaxKey/commit/c983871f26c2016901f1f9b77f3aa8bf9e4a827b) +- [更新待做](https://gitee.com/biyanci/MaxKey/commit/13042adafc2e054b97927bb63a92e5a56e183c02) + +2024-07-07T15:07:34+08:00 +- [问候](https://gitee.com/biyanci/MaxKey/commit/afc70d2209ac03e2d5b78a011ce5cedb892fe410) +- [录入时间令牌时判断是否属于当前用户](https://gitee.com/biyanci/MaxKey/commit/7c46d0b5b77037a7872ef756155d342ebbc4b51c) + +2024-07-07T14:25:20+08:00 +- [删除不必要的引用](https://gitee.com/biyanci/MaxKey/commit/c9a5cc9cf5ddc8551bbe04aa9e4b8cc3dd624e58) +- [更新待做](https://gitee.com/biyanci/MaxKey/commit/2c5dccd940bc52248cc1f5fc5728a01ddaf5e40b) + +2024-07-06T14:19:22+08:00 +- [手机号登录](https://gitee.com/biyanci/MaxKey/commit/332fda74c77f2e5958b03a765cf2b27746014a8e) + +2024-07-06T13:35:12+08:00 +- [更正拼写](https://gitee.com/biyanci/MaxKey/commit/66a942e369da9af42458e47f519bb554f8952646) + +2024-07-06T13:12:08+08:00 +- [提取 needlogin 函数](https://gitee.com/biyanci/MaxKey/commit/5cfb0830837813db9f7866c241670ad783684079) +- [优化读取偏好的方式](https://gitee.com/biyanci/MaxKey/commit/161df2830f02deacd8a4194afc5339d6ea9b7a67) + +2024-07-06T12:59:30+08:00 +- [取消设置 host 弹窗](https://gitee.com/biyanci/MaxKey/commit/79cddaf6e022082d67c46e981c02a9bfde6f161a) +- [保持登录状态](https://gitee.com/biyanci/MaxKey/commit/024daa301749a4e649696bab343fac25fd81c8c4) + +2024-07-06T12:43:46+08:00 +- [Revert "提取 setHostDialog"](https://gitee.com/biyanci/MaxKey/commit/9e2f277be61ad78cb8ec4cddbbdac665ca1129e1) + +2024-07-06T12:31:50+08:00 +- [公开 setToken 方法](https://gitee.com/biyanci/MaxKey/commit/85c9680fd7882ed54791f8008a99c8a9e34bf841) +- [提取 setHostDialog](https://gitee.com/biyanci/MaxKey/commit/b160c57c92ed451a37d4e6861056b7826b816e06) + +2024-07-05T23:27:10+08:00 +- [只重绘密码输入框](https://gitee.com/biyanci/MaxKey/commit/0202e4413f4748ad34d18a5df37e8c0175c5d236) + +2024-07-05T16:11:08+08:00 +- [scan page](https://gitee.com/biyanci/MaxKey/commit/d8384b42addfe478d65f547a785228fa28747391) +- [统一命名](https://gitee.com/biyanci/MaxKey/commit/c915df66a3577dc37066c2be73d8a01004730c57) + +2024-07-04T22:58:28+08:00 +- [整合到 utils](https://gitee.com/biyanci/MaxKey/commit/70814dccaaaf99fe272e506f6c79872e815e9879) +- [优化 appList 接口](https://gitee.com/biyanci/MaxKey/commit/6f3473e365c24011372497807ed97225ab85ca74) + +2024-07-04T18:05:19+08:00 +- [init](https://gitee.com/biyanci/MaxKey/commit/80a77f9750d255cd4a69155912e10fbd8dcd1ac2) +- [generate color scheme](https://gitee.com/biyanci/MaxKey/commit/091b44d28e3836119a568548c326369419ad96c5) \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/.metadata b/summer-ospp/2024/Flutter/maxkey_flutter/.metadata new file mode 100644 index 000000000..64d166516 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/.metadata @@ -0,0 +1,36 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "5dcb86f68f239346676ceb1ed1ea385bd215fba1" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 5dcb86f68f239346676ceb1ed1ea385bd215fba1 + base_revision: 5dcb86f68f239346676ceb1ed1ea385bd215fba1 + - platform: android + create_revision: 5dcb86f68f239346676ceb1ed1ea385bd215fba1 + base_revision: 5dcb86f68f239346676ceb1ed1ea385bd215fba1 + - platform: ios + create_revision: 5dcb86f68f239346676ceb1ed1ea385bd215fba1 + base_revision: 5dcb86f68f239346676ceb1ed1ea385bd215fba1 + - platform: windows + create_revision: 5dcb86f68f239346676ceb1ed1ea385bd215fba1 + base_revision: 5dcb86f68f239346676ceb1ed1ea385bd215fba1 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/.vscode/settings.json b/summer-ospp/2024/Flutter/maxkey_flutter/.vscode/settings.json new file mode 100644 index 000000000..8f2b7113d --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.compile.nullAnalysis.mode": "disabled" +} \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/README.md b/summer-ospp/2024/Flutter/maxkey_flutter/README.md new file mode 100644 index 000000000..7cbab5399 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/README.md @@ -0,0 +1,46 @@ +# maxkey_flutter + +MaxKey Flutter project. + +### 待做: +- [x] 账密登录 +- [x] 手机号登陆 +- [x] 保留登陆状态 +- [x] 账号信息 +- [x] 扫码登录 +- [x] 登出 +- [x] TOTP 录入 +- [x] TOTP 展示 +- [x] TOTP 与账号绑定的持久化 +- [x] 支持多个 TOTP +- [x] 检测 token 是否有效 +- [x] 完善错误处理和提示 +- [x] 优化用户界面 +- [x] 多语言 + +登陆页: +- MaxKey LOGO +- 用户名、密码、验证码 +- 登陆 +- 设置 + +主页面: +- 用户卡片(包括扫码登陆按钮) +- 添加 TOTP 按钮 +- TOTP 列表(可删除某个 TOTP) + +账号页: +- 用户卡片 +- 详细信息 +- 登出 +- 设置 + +设置页: +- 主题模式(跟随系统、日间、夜间) +- 地址、端口(提供请求 sign/get 以验证连接性的功能) +- 查看日志 + +持久化: +- token +- host ip +- user's totp list \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/analysis_options.yaml b/summer-ospp/2024/Flutter/maxkey_flutter/analysis_options.yaml new file mode 100644 index 000000000..5f2c6194a --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml +analyzer: + errors: + unused_element: ignore diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/build.gradle b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/build.gradle new file mode 100644 index 000000000..14ed26fbe --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/build.gradle @@ -0,0 +1,58 @@ +plugins { + id "com.android.application" + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" +} + +def localProperties = new Properties() +def localPropertiesFile = rootProject.file("local.properties") +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader("UTF-8") { reader -> + localProperties.load(reader) + } +} + +def flutterVersionCode = localProperties.getProperty("flutter.versionCode") +if (flutterVersionCode == null) { + flutterVersionCode = "1" +} + +def flutterVersionName = localProperties.getProperty("flutter.versionName") +if (flutterVersionName == null) { + flutterVersionName = "1.0" +} + +android { + namespace = "org.dromara.maxkey.maxkey_flutter" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "org.dromara.maxkey.maxkey_flutter" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutterVersionCode.toInteger() + versionName = flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.debug + } + } +} + +flutter { + source = "../.." +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/debug/AndroidManifest.xml b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000..2a957f6d1 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/AndroidManifest.xml b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..69a1af78f --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/kotlin/org/dromara/maxkey/maxkey_flutter/MainActivity.kt b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/kotlin/org/dromara/maxkey/maxkey_flutter/MainActivity.kt new file mode 100644 index 000000000..c9a73e65f --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/kotlin/org/dromara/maxkey/maxkey_flutter/MainActivity.kt @@ -0,0 +1,5 @@ +package org.dromara.maxkey.maxkey_flutter + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/drawable-v21/launch_background.xml b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 000000000..f74085f3f --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/drawable/launch_background.xml b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000..304732f88 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..2da26bb88cfb468ad50bec8c98495a67e680c2bf GIT binary patch literal 2783 zcmV<53Ly1~P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-ldpi/ic_launcher.png b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-ldpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..ac2f6d71ecaeb4c59ecdf0c07f14efeaf19ff50c GIT binary patch literal 1596 zcmV-C2E+M@P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x1+_^;K~z}7?U!F{99I>GzqvDa#cL5s!3Csh>fg{4Oj#Rxu_&){8Wh+u^|85sewWt%p=3l53f=Z)xzThc)XBmI0(PUgjYX~_#KB?)hr>t? z;P9+FT)K8J(|Xdj^m{JNB>rWY>9MMpUtAGTE?Y^fs5uFGC;=1A&ZX{c*NO*evJam; zioRw0ZSevbKIM*-s)L!|E+&ffBER2!-K%&ocY3>ju-cLb+_kR8jL7=uL_0Jb$X* zf3vCHzi@tSEr~>7Pe96s~x*z9G*t< z3~+{!8}a!fiY_0uciU#eS@MxexNji&P)O@4w(wAezC;S<(y`B~SA zb^=3f-}p9K1vMms4+mW@`5hawxrSa<#Xyp0cN@5k|>AoTf>!KZ&=s- zg>C6OF(3%Vf}1UUyj?5agMl>G@9}~LLNPl#m-=+OR&+3MjkQd#1R|+!5913-!*#-2t)Ys6 z!!Iw1^4Sx=mcM`RJLAd5StOq7qdVfX(l)c?Q8*LblM3qwAdT(hO# zK9F9_(@zX4Rx~6htK^O+=jum81xY{L(E}f4&d;6cepe*m}&jYmU?T)mH%#; z>0MPXAFdb(V080%No#++Gb#wh>up~?9ERpohGCwXZ;ZzmeCdI*8OPBsDWlK3PWVY% z>W(gm8PiPNH02e&ZaFUtlpC!WN;Q8#toJSx8H0FL7}CQq1L9~<$Keg2-`4#^Q8&%h zho-#Z(dBYpdFmJ~8#)Re)N%MN(AJgWmzQ|y{M2#T8LgMOY%Gdej}hy!-o{Je3qw9E zgj241g)4qOdYoJ*gpR}8iK9I_4nIh&ovtUG8S literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..5adcd0c2100581f7132d80258e1c2e00655a9458 GIT binary patch literal 2163 zcmV-(2#oiMP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x2kc2iK~!ko?U{RQTUQ;&Kj++gZO4i8PA9c#6DRJ3)W-%L zZJ{a~5=HAa)OFn^jlotXbppWvL7$4_(Ig!eeb7Z3h#|z*X_H!sZiTHt#ne(U251bn zma(l)-F8V?+c-`0aBSau&*2Y`wn=O!PErI?et%i#@jKto?{|D&7p866rtSaQ#Px6* z3bqQRogxqwfCVH$_efKvqtVv?J%CU{t5C|l8Mq7WE?3%K2x`VK{~8BjoRPwO6JZzWvO`{OTVJXbr((wK+dMd2{YXG5!R-xSV8l~-> zpz0khpRsxgo74%@NXlWFh1cz5`Gwq}8{R$&?Lyds~w z)-vsNXjPh3LB`)c(}*vuF!AXm)fFO>73s3BTAtK~M+NE{jl zk(ov(O(XC~G}iQoTyA8(F_cPe%qAXWJel_2G1L_~&sn}fKL-mE58$wv%lt`qv$(S> za@2OLuW)56lYLTpH=1V2f_&mLamXG0fa4CV8&#pfcCD}X#3L~Vc>tSs!~}N)n<{!a zq%X3>AN1|7ELAJKmPATlI2vpEa6B$@0x0d=1FCdXg^<5b+TQ)TmwLK+dK}^v`7)h> zcs}t#)3TZyw?Eo-Zu7V|G4eXr?%i3V?^sX7FNQS(Y{#Y~YhQ~$6X0ITsiqtsKGT<>Tp?1DYqW2Dn{Z-Vf{AV z9d=2vCWrWgl(NBJzpZ4}%;b}nIq)DT56F0FNpov)u(*A&bMq?FY{SPBqLi}}6`mIW z2xZNUFy8nmZ_Bgx^0LL8)5;B%{rfCat-K~ARhF6BQ&EZ*<+KA|oviS&0J1KLX`9oT zAIu$9X>pPg-YqM3Z}AKhe@zq94mZ>_zlt!jp8citMx&>;q^AO)C|hA-hyi^GL7dU6 zlR>AbM9-MP{M_r3s!=+1g4|b^7U1!z0LT>uADKOJ^eNG$LdT(MZkCniipe1YR&Ng9Wsuc9@yI{>6D12A$(Cxr=Ge&JA_VN0m<9I;>Db-=KeCyyJT(i1SBmmX7LZ;o{?ml(18j za~?onLeS4bQf$ZJ_7UxWK?NH{6{n^w0~s{qUAyg3%e052FrSac!s9v@<;*}d7Veb7IxxCM89qn<(d2EM6OjaEAbUsb;>I&4H@AmK%MZp(CK`MbL`c1J#ft1}7ZXzqYe0@>hKcL5iCZ+>KxfFo*xVN^s>>;(#cptE#$H z_&n(^Tc+Kf_1c=b6F+Affrq29rksb5alQ++e8P1T$3PY5fN*WcdSNJO?6w`_t^U5| zoC8)>x0yaqYNch`ThQuLdESMN8-{;bM=a7msSI2Lai{Ah4rI>v`Aq&p3hPyb@fKHK z<^n(++Wn-`_UA#}kh6P6{At7Rf2JcA`Cu$vg}#m6>AH!1xic{pCf_p*|Lq;I$mwyl zF2r?5Eb@wB_?Lt1U_!6?c}xSymkq=J>G6sOvRn(tuuHv1KCG@>`Ewwk(ThMA6ojn8 zh3t{i^KHZQZ|sOQCkp94$uBh9<|&m7D{bG4R%U@;Xfncu^%Qcj4>%XAf)OH&fK p07RuQJEO6QeGi+qX`8mu_HXxIFB+$*7~=o{002ovPDHLkV1k|C6;}WN literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..7c5ea122aef1a506199776d19a2107b7c4d00b01 GIT binary patch literal 3813 zcmV004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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ʝ!WcWsom@>3G}YD5tVOv`IUiB>Ud@NgP!b>%y1 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 Q{~!R2^h|Z@wVfaS5BDK-Y5)KL literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/playstore-icon.png b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/playstore-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..37fcf79b4d82bd38f0bcff49c886d0c500583782 GIT binary patch literal 27372 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 V-O7{v!4XslTPr8a#zVwQ{|E4R!+-z) literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/values-night/styles.xml b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000..06952be74 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/values/styles.xml b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..cb1ef8805 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/profile/AndroidManifest.xml b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 000000000..399f6981d --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/build.gradle b/summer-ospp/2024/Flutter/maxkey_flutter/android/build.gradle new file mode 100644 index 000000000..d2ffbffa4 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/build.gradle @@ -0,0 +1,18 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = "../build" +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/gradle.properties b/summer-ospp/2024/Flutter/maxkey_flutter/android/gradle.properties new file mode 100644 index 000000000..3b5b324f6 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/gradle/wrapper/gradle-wrapper.properties b/summer-ospp/2024/Flutter/maxkey_flutter/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..e1ca574ef --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/android/settings.gradle b/summer-ospp/2024/Flutter/maxkey_flutter/android/settings.gradle new file mode 100644 index 000000000..536165d35 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/android/settings.gradle @@ -0,0 +1,25 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.3.0" apply false + id "org.jetbrains.kotlin.android" version "1.7.10" apply false +} + +include ":app" diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/assets/logo.jpg b/summer-ospp/2024/Flutter/maxkey_flutter/assets/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b887a278329b5632ee7ab4ea08c12785cd09d4b0 GIT binary patch literal 48435 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 E055J<+W-In literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/assets/logo_maxkey.png b/summer-ospp/2024/Flutter/maxkey_flutter/assets/logo_maxkey.png new file mode 100644 index 0000000000000000000000000000000000000000..df747614cefee1e834a19ef2c6dc7e390a595f46 GIT binary patch literal 144941 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
  • UG<^bLC- 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 literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/AppFrameworkInfo.plist b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000..7c5696400 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 12.0 + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/Debug.xcconfig b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000..592ceee85 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/Release.xcconfig b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000..592ceee85 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.pbxproj b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..b1ef252a3 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,616 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.dromara.maxkey.maxkeyFlutter; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.dromara.maxkey.maxkeyFlutter.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.dromara.maxkey.maxkeyFlutter.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = org.dromara.maxkey.maxkeyFlutter.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.dromara.maxkey.maxkeyFlutter; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.dromara.maxkey.maxkeyFlutter; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000..8e3ca5dfe --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/contents.xcworkspacedata b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..1d526a16e --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/AppDelegate.swift b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/AppDelegate.swift new file mode 100644 index 000000000..9074fee92 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Flutter +import UIKit + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..8b5466c7b --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,120 @@ +{ + "images": [ + { + "size": "20x20", + "idiom": "universal", + "filename": "icon-20@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "20x20", + "idiom": "universal", + "filename": "icon-20@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "29x29", + "idiom": "universal", + "filename": "icon-29@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "29x29", + "idiom": "universal", + "filename": "icon-29@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "38x38", + "idiom": "universal", + "filename": "icon-38@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "38x38", + "idiom": "universal", + "filename": "icon-38@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "40x40", + "idiom": "universal", + "filename": "icon-40@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "40x40", + "idiom": "universal", + "filename": "icon-40@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "60x60", + "idiom": "universal", + "filename": "icon-60@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "60x60", + "idiom": "universal", + "filename": "icon-60@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "64x64", + "idiom": "universal", + "filename": "icon-64@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "64x64", + "idiom": "universal", + "filename": "icon-64@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "68x68", + "idiom": "universal", + "filename": "icon-68@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "76x76", + "idiom": "universal", + "filename": "icon-76@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "83.5x83.5", + "idiom": "universal", + "filename": "icon-83.5@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "1024x1024", + "idiom": "universal", + "filename": "icon-1024.png", + "scale": "1x", + "platform": "ios" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..07044e8b0292a54061090ab07ed8a1446628d93b GIT binary patch literal 78138 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 bYY7LsE*IO6shgISvrN_4(88cb-zD}xcE-G| literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1d20f264ba4ca8d69d18f45da234c3fb2a5711e8 GIT binary patch literal 1564 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 literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7acb473a55e70747e82ce2c3cda01ddfa77637ac GIT binary patch literal 2500 zcmV;#2|M004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 T^J>T4j1$n-Fi>xRJ&FB4#+ze( literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..dedd8ed815419c3fc26bfca8ff0f1a0518c42f72 GIT binary patch literal 5453 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 T^J>T4j1$n-Fi>xRJ&FB4#+ze( literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..74265842ad923e800edb4637c3fad4cde1ae5833 GIT binary patch literal 8479 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 Ll%*>rjRXG=zsm1H literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-68@2x.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-68@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..29f024a8d0eca2989035db1657169dccb75f23d9 GIT binary patch literal 6209 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

    g8~)Lr*l0atDjDCyxija{@60W)cd*XD9;$J zVahl~S>o*DtD*9KF)-~RnPlf&mp5)$BxtwG1jnN{(9({NHv&wL_k|zFg?i)7*%x$W zijvY&^ZIiXz6z|r@GsA=b{|e+y|DBfyXX>!LUD<;+l4&}JIDMV9>mPDcuohmk7F8M z2<=5LH#|NK_DhhEEw>uJeM_3sd?nXD7XIfss)llYxG(y#t}Y>*G=D<#n7{8iy zWoBeRiDnVs;R4)Yb;;^FL-8|~tE=wr9NDs_k&HMXJY(PMe7k-yer|TzT`Y!~BHD6h zZy`UwNj(#BM1?>Dr7vC}U5^)F`>iKW#l;)8U}Ki}a$|`CuakyrTPRjIPzJczak4V< z_HPC_DxHlD@e{Njgvh(Qaa|V>oLM!+%n{+BjV7J>i&Nxr{*9{np(posb8~^1o)PC8 zu4g)*nc~Wa%4gBj?FFv&Pon{j;f#U_pLms8VK1nE)H^TVg*RN|0X6-6N)nVC`>sC; z)}n4FF%jC^J1bO~{D{Jb=GlBRB6xq*NihNR+XLgt>%NZnqxadI%#vtmGta(WBb`!O z>KA^n22iw)&R$Y`hs4FQ)20x0T!fPHe|}pPn>z5z>n#chfIwQ^W{1n{;jy_k^cuNK zmzNj3I~w>)zY2)N0=lJwqRFFoPhc5$dp$CGcy(xWAWiT^Vt-%E!Q6JLyLxADH@~*| zdhD(9bsG1#37R+Cz&fMR+HvrA-gX7PEub(^3OF5M=DN~&bJ&O5ktLpa@*vHF^8t#T z#ov5`A}2x!fQpjc{M|L%D~rJu#)0b{&nEBY5%ndfS5R7BCf}9#RjZb|&o&!nSd79D z3VX3aE{=nxpup$b3yoxKYET0n_SEIcI^50DQ@TnJJ2ZXb&ofXbMU((7$-2sn3+yf? zBr1AxxES0WjP0V5r(Gh<^t{#$T)aRJ1h3JLQK55Er$y|oid xWFTa$>zibHR_lJ~kaj~B)=en>|1;sY5|HKKv+E1jc@(b?P?A%Zt(3M1{y&F8BJThI literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2a824c6094f9931066b1a88f28570ff86259ee52 GIT binary patch literal 6922 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 literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ebe81c9d94e09a9c7853b9d5d81901fa3eaa8bcf GIT binary patch literal 7787 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 Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000..89c2725b7 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Base.lproj/LaunchScreen.storyboard b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..f2e259c7c --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Base.lproj/Main.storyboard b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000..f3c28516f --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Info.plist b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Info.plist new file mode 100644 index 000000000..8414d0f9e --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Maxkey Flutter + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + maxkey_flutter + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Runner-Bridging-Header.h b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 000000000..308a2a560 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/ios/RunnerTests/RunnerTests.swift b/summer-ospp/2024/Flutter/maxkey_flutter/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 000000000..86a7c3b1b --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/l10n.yaml b/summer-ospp/2024/Flutter/maxkey_flutter/l10n.yaml new file mode 100644 index 000000000..4e6692e55 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/l10n.yaml @@ -0,0 +1,3 @@ +arb-dir: lib/l10n +template-arb-file: app_en.arb +output-localization-file: app_localizations.dart \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/app_color_scheme.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/app_color_scheme.dart new file mode 100644 index 000000000..e29e76809 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/app_color_scheme.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; + +class AppColorScheme { + static ColorScheme lightScheme() { + return const ColorScheme( + brightness: Brightness.light, + primary: Color(0xff585992), + surfaceTint: Color(0xff585992), + onPrimary: Color(0xffffffff), + primaryContainer: Color(0xffe1dfff), + onPrimaryContainer: Color(0xff14134a), + secondary: Color(0xff5d5c72), + onSecondary: Color(0xffffffff), + secondaryContainer: Color(0xffe2e0f9), + onSecondaryContainer: Color(0xff1a1a2c), + tertiary: Color(0xff795369), + onTertiary: Color(0xffffffff), + tertiaryContainer: Color(0xffffd8ec), + onTertiaryContainer: Color(0xff2f1124), + error: Color(0xffba1a1a), + onError: Color(0xffffffff), + errorContainer: Color(0xffffdad6), + onErrorContainer: Color(0xff410002), + surface: Color(0xfffcf8ff), + onSurface: Color(0xff1b1b21), + onSurfaceVariant: Color(0xff47464f), + outline: Color(0xff777680), + outlineVariant: Color(0xffc8c5d0), + shadow: Color(0xff000000), + scrim: Color(0xff000000), + inverseSurface: Color(0xff303036), + inversePrimary: Color(0xffc1c1ff), + primaryFixed: Color(0xffe1dfff), + onPrimaryFixed: Color(0xff14134a), + primaryFixedDim: Color(0xffc1c1ff), + onPrimaryFixedVariant: Color(0xff404178), + secondaryFixed: Color(0xffe2e0f9), + onSecondaryFixed: Color(0xff1a1a2c), + secondaryFixedDim: Color(0xffc6c4dd), + onSecondaryFixedVariant: Color(0xff454559), + tertiaryFixed: Color(0xffffd8ec), + onTertiaryFixed: Color(0xff2f1124), + tertiaryFixedDim: Color(0xffe9b9d3), + onTertiaryFixedVariant: Color(0xff5f3c51), + surfaceDim: Color(0xffdcd9e0), + surfaceBright: Color(0xfffcf8ff), + surfaceContainerLowest: Color(0xffffffff), + surfaceContainerLow: Color(0xfff6f2fa), + surfaceContainer: Color(0xfff0ecf4), + surfaceContainerHigh: Color(0xffeae7ef), + surfaceContainerHighest: Color(0xffe4e1e9), + ); + } + + static ColorScheme darkScheme() { + return const ColorScheme( + brightness: Brightness.dark, + primary: Color(0xffc1c1ff), + surfaceTint: Color(0xffc1c1ff), + onPrimary: Color(0xff2a2a60), + primaryContainer: Color(0xff404178), + onPrimaryContainer: Color(0xffe1dfff), + secondary: Color(0xffc6c4dd), + onSecondary: Color(0xff2f2f42), + secondaryContainer: Color(0xff454559), + onSecondaryContainer: Color(0xffe2e0f9), + tertiary: Color(0xffe9b9d3), + onTertiary: Color(0xff46263a), + tertiaryContainer: Color(0xff5f3c51), + onTertiaryContainer: Color(0xffffd8ec), + error: Color(0xffffb4ab), + onError: Color(0xff690005), + errorContainer: Color(0xff93000a), + onErrorContainer: Color(0xffffdad6), + surface: Color(0xff131318), + onSurface: Color(0xffe4e1e9), + onSurfaceVariant: Color(0xffc8c5d0), + outline: Color(0xff918f9a), + outlineVariant: Color(0xff47464f), + shadow: Color(0xff000000), + scrim: Color(0xff000000), + inverseSurface: Color(0xffe4e1e9), + inversePrimary: Color(0xff585992), + primaryFixed: Color(0xffe1dfff), + onPrimaryFixed: Color(0xff14134a), + primaryFixedDim: Color(0xffc1c1ff), + onPrimaryFixedVariant: Color(0xff404178), + secondaryFixed: Color(0xffe2e0f9), + onSecondaryFixed: Color(0xff1a1a2c), + secondaryFixedDim: Color(0xffc6c4dd), + onSecondaryFixedVariant: Color(0xff454559), + tertiaryFixed: Color(0xffffd8ec), + onTertiaryFixed: Color(0xff2f1124), + tertiaryFixedDim: Color(0xffe9b9d3), + onTertiaryFixedVariant: Color(0xff5f3c51), + surfaceDim: Color(0xff131318), + surfaceBright: Color(0xff39383f), + surfaceContainerLowest: Color(0xff0e0e13), + surfaceContainerLow: Color(0xff1b1b21), + surfaceContainer: Color(0xff1f1f25), + surfaceContainerHigh: Color(0xff2a292f), + surfaceContainerHighest: Color(0xff35343a), + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/l10n/app_en.arb b/summer-ospp/2024/Flutter/maxkey_flutter/lib/l10n/app_en.arb new file mode 100644 index 000000000..f8e6ebd12 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/l10n/app_en.arb @@ -0,0 +1,66 @@ +{ + "homePageNewTotpBtnScanPage": "Scan TOTP", + "homePagenewTotpBtnErr": "Unsupported QR code", + "homePagenewTotpBtn": "Scan TOTP", + + "homePageTotpListViewNoTOTP": "No TOTP", + "homePageTotpListViewConfirmDialog": "Confirm to delete", + "homePageTotpListViewConfirmDialogCancelBtn": "Cancel", + "homePageTotpListViewConfirmDialogConfirmBtn": "Confirm", + + "homePageUserCardGreetingMorning": "Morning", + "homePageUserCardGreetingNoon": "Noon", + "homePageUserCardGreetingAfternoon": "Afternoon", + "homePageUserCardGreetingEvening": "Evening", + "homePageUserCardScanPage": "Scan to login", + + "loginPageSettingBtn": "Settings", + "loginPageLoginViewUsername": "Username", + "loginPageLoginViewPassword": "Password", + "loginPageLoginViewCaptcha": "Captcha", + "loginPageLoginViewLoginBtn": "Login", + + "settingsPageTitle": "Settings", + "settingsPageHostSettingDialog": "Specify host", + "settingsPageHostSettingDialogHost": "Host", + "settingsPageHostSettingDialogTestSucceed": "Succeed", + "settingsPageHostSettingDialogTestFail": "Fail", + "settingsPageHostSettingDialogTestBtn": "Test", + "settingsPageHostSettingDialogCancleBtn": "Cancle", + "settingsPageHostSettingDialogConfirmBtn": "Confirm", + "settingsPageHostSettingTitle": "Specify host", + "settingsPageHostSettingDesc": "If MaxKey is not working properly, you may need to change this", + + "settingsPageShowLogBtnTitle": "Check log", + "settingsPageLogDisplayPageTitle": "Check log", + + "settingsPageThemeModeSwitchTitle": "Theme", + + "userPageFullUserInfoDialogTitle": "User info", + "userPageFullUserInfoDialogDisplayName": "Name", + "userPageFullUserInfoDialogUsername": "Username", + "userPageFullUserInfoDialogGender": "Gender", + "userPageFullUserInfoDialogEmployeeNumber": "Employee ID", + "userPageFullUserInfoDialogMobile": "Mobile", + "userPageFullUserInfoDialogEmail": "Email", + "userPageFullUserInfoDialogUserType": "User type", + "userPageFullUserInfoDialogUserState": "User state", + "userPageFullUserInfoDialogIdType": "ID type", + "userPageFullUserInfoDialogIdCardNo": "ID card Nunber", + "userPageFullUserInfoDialogMarried": "Married", + "userPageFullUserInfoDialogBirth": "Birth date", + "userPageFullUserInfoDialogOrganization": "Organization", + "userPageFullUserInfoDialogDivision": "Division", + "userPageFullUserInfoDialogDepartmentId": "Department ID", + "userPageFullUserInfoDialogDepartment": "Department", + "userPageFullUserInfoDialogJobTitle": "Job title", + "userPageFullUserInfoDialogJobLevel": "Job level", + "userPageFullUserInfoDialogManager": "Manager", + + "userPageTitle": "User", + "userPageUserInfoBtn": "User info", + "userPageSettingsBtn": "Settings", + "userPageLogoutBtn": "Logout", + + "scanPagePermissionDeniedMsg": "Camera permissions are not granted.MaxKey requires camera permissions to scan the QR code and obtain a TOTP." +} \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/l10n/app_zh.arb b/summer-ospp/2024/Flutter/maxkey_flutter/lib/l10n/app_zh.arb new file mode 100644 index 000000000..000bd5774 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/l10n/app_zh.arb @@ -0,0 +1,66 @@ +{ + "homePageNewTotpBtnScanPage": "录入时间令牌", + "homePagenewTotpBtnErr": "不支持的二维码", + "homePagenewTotpBtn": "录入时间令牌", + + "homePageTotpListViewNoTOTP": "没有时间令牌", + "homePageTotpListViewConfirmDialog": "删除选中的时间令牌?", + "homePageTotpListViewConfirmDialogCancelBtn": "取消", + "homePageTotpListViewConfirmDialogConfirmBtn": "确认", + + "homePageUserCardGreetingMorning": "早上好", + "homePageUserCardGreetingNoon": "中午好", + "homePageUserCardGreetingAfternoon": "下午好", + "homePageUserCardGreetingEvening": "晚上好", + "homePageUserCardScanPage": "扫码登陆", + + "loginPageSettingBtn": "设置", + "loginPageLoginViewUsername": "用户名", + "loginPageLoginViewPassword": "密码", + "loginPageLoginViewCaptcha": "验证码", + "loginPageLoginViewLoginBtn": "登录", + + "settingsPageTitle": "设置", + "settingsPageHostSettingDialog": "指定主机", + "settingsPageHostSettingDialogHost": "主机地址", + "settingsPageHostSettingDialogTestSucceed": "连接成功", + "settingsPageHostSettingDialogTestFail": "连接失败", + "settingsPageHostSettingDialogTestBtn": "验证", + "settingsPageHostSettingDialogCancleBtn": "取消", + "settingsPageHostSettingDialogConfirmBtn": "确认", + "settingsPageHostSettingTitle": "指定主机", + "settingsPageHostSettingDesc": "如果网络状态良好但 MaxKey 仍无法正常工作,可能需要修改此项设置", + + "settingsPageShowLogBtnTitle": "查看日志", + "settingsPageLogDisplayPageTitle": "查看日志", + + "settingsPageThemeModeSwitchTitle": "主题模式", + + "userPageFullUserInfoDialogTitle": "详细信息", + "userPageFullUserInfoDialogDisplayName": "姓名", + "userPageFullUserInfoDialogUsername": "登陆账号", + "userPageFullUserInfoDialogGender": "性别", + "userPageFullUserInfoDialogEmployeeNumber": "员工编号", + "userPageFullUserInfoDialogMobile": "手机号码", + "userPageFullUserInfoDialogEmail": "邮箱", + "userPageFullUserInfoDialogUserType": "用户类型", + "userPageFullUserInfoDialogUserState": "用户状态", + "userPageFullUserInfoDialogIdType": "证件类型", + "userPageFullUserInfoDialogIdCardNo": "证件号码", + "userPageFullUserInfoDialogMarried": "婚姻状态", + "userPageFullUserInfoDialogBirth": "出生日期", + "userPageFullUserInfoDialogOrganization": "所属组织", + "userPageFullUserInfoDialogDivision": "分支机构", + "userPageFullUserInfoDialogDepartmentId": "部门编号", + "userPageFullUserInfoDialogDepartment": "部门名称", + "userPageFullUserInfoDialogJobTitle": "职位", + "userPageFullUserInfoDialogJobLevel": "级别", + "userPageFullUserInfoDialogManager": "上级经理", + + "userPageTitle": "用户", + "userPageUserInfoBtn": "详细信息", + "userPageSettingsBtn": "设置", + "userPageLogoutBtn": "退出账号", + + "scanPagePermissionDeniedMsg": "未授予摄像头权限。\nMaxKey 需要摄像头权限以扫描二维码并获取时间令牌。" +} \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/main.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/main.dart new file mode 100644 index 000000000..81798aa0b --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/main.dart @@ -0,0 +1,97 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:maxkey_flutter/app_color_scheme.dart'; +import 'package:maxkey_flutter/maxkey/maxkey.dart'; +import 'package:maxkey_flutter/maxkey/services/users.service.dart'; +import 'package:maxkey_flutter/pages/home_page/page.dart'; +import 'package:maxkey_flutter/pages/login_page/page.dart'; +import 'package:maxkey_flutter/pages/scan_page.dart'; +import 'package:maxkey_flutter/pages/settings_page/page.dart'; +import 'package:maxkey_flutter/pages/user_page/page.dart'; +import 'package:maxkey_flutter/persistent.dart'; +import 'package:maxkey_flutter/utils.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MaxKeyPersistent.init(); + runApp(const AppEntry()); +} + +class AppEntry extends StatelessWidget { + const AppEntry({super.key}); + + @override + Widget build(BuildContext context) { + return ValueListenableBuilder( + valueListenable: MaxKeyPersistent.instance.themeModeListenable, + builder: (context, value, _) { + return MaterialApp.router( + scaffoldMessengerKey: SCAFFOLD_MESSENGER_KEY, + themeMode: value, + theme: ThemeData.from(colorScheme: AppColorScheme.lightScheme()), + darkTheme: ThemeData.from(colorScheme: AppColorScheme.darkScheme()), + localizationsDelegates: const >[ + AppLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + supportedLocales: AppLocalizations.supportedLocales, + routerConfig: _routerConfig, + ); + }); + } +} + +GoRouter _routerConfig = GoRouter( + navigatorKey: NAVIGATOR_KEY, + initialLocation: !MaxKey.instance.authnService.localAuth() + ? RoutePath.loginPage + : RoutePath.homePage, + routes: [ + GoRoute( + path: RoutePath.loginPage, + pageBuilder: (context, state) => const CupertinoPage(child: LoginPage()), + ), + GoRoute( + path: RoutePath.homePage, + pageBuilder: (context, state) => const CupertinoPage(child: HomePage()), + ), + GoRoute( + path: RoutePath.scanPage, + pageBuilder: (context, state) => CupertinoPage( + child: ScanPage(title: state.extra as String), + ), + ), + GoRoute( + path: RoutePath.userPage, + pageBuilder: (context, state) => CupertinoPage( + child: UserPage(user: state.extra as MaxKeyUser?), + ), + ), + GoRoute( + path: RoutePath.settingsPage, + pageBuilder: (context, state) => + const CupertinoPage(child: SettingsPage()), + ), + ], +); + +// const _supportedLocales = [ +// Locale('en', 'US'), +// // generic Chinese 'zh' +// Locale.fromSubtags(languageCode: 'zh'), +// // generic simplified Chinese 'zh_Hans' +// Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'), +// // generic traditional Chinese 'zh_Hant' +// Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'), +// // 'zh_Hans_CN' +// Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'), +// // 'zh_Hant_TW' +// Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'), +// // 'zh_Hant_HK' +// Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'HK'), +// ]; diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/maxkey.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/maxkey.dart new file mode 100644 index 000000000..3e04f4c08 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/maxkey.dart @@ -0,0 +1,90 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:maxkey_flutter/maxkey/services/authn.service.dart'; +import 'package:maxkey_flutter/maxkey/services/image_captcha.service.dart'; +import 'package:maxkey_flutter/maxkey/services/time_based.service.dart'; +import 'package:maxkey_flutter/maxkey/services/users.service.dart'; +import 'package:maxkey_flutter/persistent.dart'; +import 'package:maxkey_flutter/utils.dart'; + +/// 会在需要刷新的时候通知 +class MaxKey with ChangeNotifier { + final _dio = Dio(BaseOptions( + baseUrl: MaxKeyPersistent.instance.baseUrl, + connectTimeout: const Duration(seconds: 10), + )); + late final authnService = AuthnService(_dio); + late final imageCaptchaService = ImageCaptchaService(_dio); + late final timeBasedService = TimeBasedService(_dio); + late final usersService = UsersService(_dio); + + static MaxKey? _instance; + static MaxKey get instance { + _instance ??= MaxKey._(); + return _instance!; + } + + MaxKey._() { + _dio.interceptors.add(InterceptorsWrapper( + onResponse: (response, handler) { + final cookies = response.headers[HttpHeaders.setCookieHeader]; + if (cookies != null) { + maxKeyCookies = List.from(cookies); + } + handler.next(response); + }, + onError: (error, handler) { + LOGGER.e(error.type); + LOGGER.e(error.response); + if (error.type == DioExceptionType.badResponse) { + SCAFFOLD_MESSENGER_KEY.currentState?.showSnackBar( + SnackBar( + content: const Text("Please login again."), + action: SnackBarAction( + label: "Login", + onPressed: () async { + _dio.options.headers.remove(HttpHeaders.authorizationHeader); + await MaxKeyPersistent.instance.clearToken(); + NAVIGATOR_KEY.currentContext?.pushReplacement( + RoutePath.loginPage, + ); + }, + ), + ), + ); + } + handler.next(error); + }, + )); + } + + void updateBaseUrl() { + LOGGER.i("old baseUrl: ${_dio.options.baseUrl}"); + _dio.options.baseUrl = MaxKeyPersistent.instance.baseUrl; + LOGGER.i("new baseUrl: ${_dio.options.baseUrl}"); + notifyListeners(); + } + + List maxKeyCookies = []; + + Future maxKeyNetworkTest({String? host}) async { + try { + LOGGER.i( + "[MaxKeyNetworkTest] GET: ${host == null ? MaxKeyPersistent.instance.baseUrl : "http://$host/sign"}", + ); + + await _dio.get( + host == null ? MaxKeyPersistent.instance.baseUrl : "http://$host/sign", + ); + LOGGER.i("MaxKeyNetworkTest: true"); + return true; + } catch (err) { + LOGGER.e(err); + } + LOGGER.i("MaxKeyNetworkTest: false"); + return false; + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/authn.service.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/authn.service.dart new file mode 100644 index 000000000..4a36c6823 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/authn.service.dart @@ -0,0 +1,161 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:maxkey_flutter/persistent.dart'; +import 'package:maxkey_flutter/utils.dart'; + +typedef ExpectedErrorHandler = void Function(String msg); + +class AuthnService { + final Dio _dio; + + AuthnService(this._dio); + + /// 获取 state 类型 + Future get() async { + try { + LOGGER.i("GET: /login/get?_allow_anonymous=true"); + + final res = await _dio.get( + "/login/get?_allow_anonymous=true", + queryParameters: {"remember_me": true}, + ); + return res.data["data"]["state"]; + } catch (err) { + LOGGER.e(err); + } + return null; + } + + /// 短信验证码 + Future produceOtp({ + required ExpectedErrorHandler expectedErrorHandler, + required String mobile, + }) async { + try { + LOGGER.i("GET: /login/sendotp/$mobile?_allow_anonymous=true"); + + final res = await _dio.get( + "/login/sendotp/$mobile?_allow_anonymous=true", + queryParameters: {"mobile": mobile}, + ); + + if (res.data["code"] != 0) { + final msg = res.data["message"] ?? "验证码发送失败"; + expectedErrorHandler(msg); + LOGGER.w(msg); + return false; + } + + return true; + } catch (err) { + LOGGER.e(err); + } + return false; + } + + /// 账密登录 + Future loginNormal({ + required ExpectedErrorHandler expectedErrorHandler, + required String state, + required String username, + required String password, + required String captcha, + }) async { + try { + LOGGER.i("POST: /login/signin?_allow_anonymous=true"); + + final res = await _dio.post( + "/login/signin?_allow_anonymous=true", + data: { + "authType": "app", + "state": state, + "username": username, + "password": password, + "captcha": captcha, + "remeberMe": true, + }, + ); + + if (res.data["code"] != 0) { + final msg = res.data["message"] ?? "登陆失败"; + expectedErrorHandler(msg); + LOGGER.w(msg); + return false; + } + + await onlineAuth( + token: res.data["data"]["token"], + onlineTicket: res.data["data"]["ticket"], + username: res.data["data"]["username"], + ); + return true; + } catch (err) { + LOGGER.e(err); + } + return false; + } + + Future scanCode({ + required ExpectedErrorHandler expectedErrorHandler, + required String code, + }) async { + final token = MaxKeyPersistent.instance.token; + if (token == null) { + expectedErrorHandler("未登录"); + return false; + } + + try { + LOGGER.i("POST: /login/scanCode"); + final res = await _dio.post( + "/login/scanCode", + data: {"jwtToken": token, "code": code}, + ); + + if (res.data["code"] != 0) { + final msg = res.data["message"] ?? "扫码登陆失败"; + expectedErrorHandler(msg); + LOGGER.w(msg); + return false; + } + + return true; + } catch (err) { + LOGGER.e(err); + } + return false; + } + + Future onlineAuth({ + required String token, + required String onlineTicket, + required String username, + }) async { + await MaxKeyPersistent.instance.setUser(username); + await MaxKeyPersistent.instance.setToken(token); + _dio.options.headers[HttpHeaders.authorizationHeader] = token; + } + + bool localAuth() { + final token = MaxKeyPersistent.instance.token; + if (token == null) return false; + + _dio.options.headers[HttpHeaders.authorizationHeader] = token; + return true; + } + + /// 登出并清除本地缓存的 token + Future logout() async { + try { + LOGGER.i("GET: /logout"); + await _dio.get("/logout"); + } catch (err) { + LOGGER.e(err); + } + + _dio.options.headers.remove(HttpHeaders.authorizationHeader); + + await MaxKeyPersistent.instance.clearToken(); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/image_captcha.service.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/image_captcha.service.dart new file mode 100644 index 000000000..aab4e0ddd --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/image_captcha.service.dart @@ -0,0 +1,27 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:dio/dio.dart'; +import 'package:maxkey_flutter/utils.dart'; + +class ImageCaptchaService { + final Dio _dio; + ImageCaptchaService(this._dio); + + Future captcha({required String state}) async { + try { + LOGGER.i("GET: /captcha?_allow_anonymous=true"); + + final res = await _dio.get( + "/captcha?_allow_anonymous=true", + queryParameters: {"state": state}, + ); + + final String base64Image = res.data["data"]["image"]; + return base64.decode(base64Image.split(",")[1]); + } catch (err) { + LOGGER.e(err); + } + return null; + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/time_based.service.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/time_based.service.dart new file mode 100644 index 000000000..e3591d21a --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/time_based.service.dart @@ -0,0 +1,29 @@ +import 'package:dio/dio.dart'; +import 'package:maxkey_flutter/utils.dart'; + +class TimeBasedService { + final Dio _dio; + TimeBasedService(this._dio); + + Future verify({required String totpCode}) async { + try { + LOGGER.i("GET: /config/verify?otp=$totpCode"); + + final res = await _dio.get( + "/config/verify", + queryParameters: {"otp": totpCode}, + ); + + if (res.data["code"] != 0) { + LOGGER.w("验证失败:${res.data["message"]}"); + return false; + } + + LOGGER.i("验证成功"); + return true; + } catch (err) { + LOGGER.e(err); + } + return false; + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/users.service.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/users.service.dart new file mode 100644 index 000000000..470ef45f9 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/maxkey/services/users.service.dart @@ -0,0 +1,245 @@ +import 'dart:typed_data'; + +import 'package:dio/dio.dart'; +import 'package:maxkey_flutter/utils.dart'; + +class MaxKeyUser { + final String displayName; + final Uint8List? picture; + + MaxKeyUser(this.displayName, this.picture); + + factory MaxKeyUser.fromMap(Map map) { + final String displayName = map["data"]["displayName"]; + final String? pictureBase64 = map["data"]["pictureBase64"]; + final picture = pictureBase64?.split(",")[1].base64ToBuf(); + return MaxKeyUser(displayName, picture); + } +} + +class MaxKeyUserInfo { + MaxKeyUserInfo({ + /// 姓名 + required this.displayName, + + /// 登陆账号 + required this.username, + + /// 性别 + required this.gender, + + /// 员工编号 + required this.employeeNumber, + + /// 手机号码 + required this.mobile, + + /// 邮箱 + required this.email, + + /// 用户类型 + required this.userType, + + /// 用户状态 + required this.userState, + + /// 状态 + required this.status, + + /// 证件类型 + required this.idType, + + /// 证件号码 + required this.idCardNo, + + /// 婚姻状态 + required this.married, + + /// 出生日期 + required this.birthDate, + + /// 所属组织 + required this.organization, + + /// 分支机构 + required this.division, + + /// 部门编号 + required this.departmentId, + + /// 部门名称 + required this.department, + + /// 职位 + required this.jobTitle, + + /// 级别 + required this.jobLevel, + + /// 上级经理 + required this.manager, + }); + + static MaxKeyUserInfo? fromMap(Map map) { + return MaxKeyUserInfo( + displayName: map["displayName"].toString(), + username: map["username"].toString(), + gender: switch (map["gender"]) { 1 => "女", 2 => "男", _ => _unknwon }, + employeeNumber: map["employeeNumber"]?.toString() ?? _unknwon, + mobile: map["mobile"]?.toString() ?? _unknwon, + email: map["email"]?.toString() ?? _unknwon, + userType: switch (map["userType"]) { + "EMPLOYEE" => "内部员工", + "CONTRACTOR" => "承包商", + "CUSTOMER" => "客户", + "SUPPLIER" => "供应商", + "PARTNER" => "合作伙伴", + "EXTERNAL" => "外部用户", + "INTERN" => "实习生", + "TEMP" => "临时用户", + "DEALER" => "经销商", + _ => _unknwon, + }, + userState: switch (map["userState"]) { + "RESIDENT" => "在职", + "WITHDRAWN" => "离职", + "INACTIVE" => "停薪留职", + "RETIREE" => "退休", + _ => _unknwon, + }, + status: switch (map["status"]) { + 1 => "活动", + 2 => "不活动", + 4 => "禁用", + 5 => "锁定", + 9 => "已删除", + _ => _unknwon, + }, + idType: switch (map["idType"]) { + 0 => "未知", + 1 => "身份证", + 2 => "护照", + 3 => "学生证", + 4 => "军人证", + _ => _unknwon, + }, + idCardNo: map["idCardNo"]?.toString() ?? _unknwon, + married: switch (map["married"]) { + 0 => "未知", + 1 => "单身", + 2 => "已婚", + 3 => "离异", + 4 => "丧偶", + _ => _unknwon, + }, + birthDate: map["birthDate"]?.toString() ?? _unknwon, + organization: map["organization"]?.toString() ?? _unknwon, + division: map["division"]?.toString() ?? _unknwon, + departmentId: map["departmentId"]?.toString() ?? _unknwon, + department: map["deparment"]?.toString() ?? _unknwon, + jobTitle: map["jobTitle"]?.toString() ?? _unknwon, + jobLevel: map["jobLevel"]?.toString() ?? _unknwon, + manager: map["manager"]?.toString() ?? _unknwon, + ); + } + + /// 姓名 + final String displayName; + + /// 登陆账号 + final String username; + + /// 性别 + final String gender; + + /// 员工编号 + final String employeeNumber; + + /// 手机号码 + final String mobile; + + /// 邮箱 + final String email; + + /// 用户类型 + final String userType; + + /// 用户状态 + final String userState; + + /// 状态 + final String status; + + /// 证件类型 + final String idType; + + /// 证件号码 + final String idCardNo; + + /// 婚姻状态 + final String married; + + /// 出生日期 + final String birthDate; + + /// 所属组织 + final String organization; + + /// 分支机构 + final String division; + + /// 部门编号 + final String departmentId; + + /// 部门名称 + final String department; + + /// 职位 + final String jobTitle; + + /// 级别 + final String jobLevel; + + /// 上级经理 + final String manager; + + static const String _unknwon = "未知"; +} + +class UsersService { + final Dio _dio; + UsersService(this._dio); + + Future getBasicUserInfo() async { + try { + LOGGER.i("GET: /users/profile/get"); + + final res = await _dio.get("/users/profile/get"); + if (res.data["code"] != 0) { + LOGGER.w(res.data["message"]); + return null; + } + return MaxKeyUser.fromMap(res.data); + } catch (err) { + LOGGER.e(err); + } + return null; + } + + Future getFullUserInfo() async { + try { + LOGGER.i("GET: /users/profile/get"); + + final res = await _dio.get("/users/profile/get"); + if (res.data["code"] != 0) { + LOGGER.w(res.data["message"]); + return null; + } + + return MaxKeyUserInfo.fromMap(res.data["data"]); + } catch (err) { + LOGGER.e(err); + } + return null; + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/new_totp_btn.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/new_totp_btn.dart new file mode 100644 index 000000000..b6ca4f3fd --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/new_totp_btn.dart @@ -0,0 +1,58 @@ +part of 'package:maxkey_flutter/pages/home_page/page.dart'; + +class _NewTotpBtn extends StatelessWidget { + const _NewTotpBtn({super.key, required this.controller}); + + final _TotpListViewController controller; + + @override + Widget build(BuildContext context) { + final scheme = Theme.of(context).colorScheme; + + return Ink( + decoration: BoxDecoration( + color: scheme.surfaceContainer, + borderRadius: BorderRadius.circular(8.0), + ), + child: InkWell( + borderRadius: BorderRadius.circular(8.0), + onTap: () async { + final qrCodeValue = await context.push( + RoutePath.scanPage, + extra: AppLocalizations.of(context)!.homePageNewTotpBtnScanPage, + ); + + if (qrCodeValue == null) return; + + final newTotp = Totp.fromUri(qrCodeValue); + if (newTotp == null) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(AppLocalizations.of(context)!.homePagenewTotpBtnErr)), + ); + } + return; + } + + final totps = MaxKeyPersistent.instance.totps; + totps.add(newTotp); + await MaxKeyPersistent.instance.saveTotps(totps); + + controller.update(); + }, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Center( + child: Text( + AppLocalizations.of(context)!.homePagenewTotpBtn, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ), + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/totp_list_view.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/totp_list_view.dart new file mode 100644 index 000000000..2e2d23bc3 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/totp_list_view.dart @@ -0,0 +1,250 @@ +part of 'package:maxkey_flutter/pages/home_page/page.dart'; + +class _TotpListViewController with ChangeNotifier { + List get totps => MaxKeyPersistent.instance.totps; + + bool multiSelect = false; + final Set selected = {}; + + void setMultiSelect(bool value) { + multiSelect = value; + selected.clear(); + notifyListeners(); + } + + void _select(Totp totp) { + if (!multiSelect) return; + + selected.add(totp); + } + + void _unselect(Totp totp) { + if (!multiSelect) return; + + selected.remove(totp); + } + + void selectOrNot(Totp totp) { + if (!multiSelect) return; + + if (selected.contains(totp)) { + _unselect(totp); + } else { + _select(totp); + } + notifyListeners(); + } + + bool hasSelected(Totp totp) { + if (!multiSelect) return false; + + return selected.contains(totp); + } + + Future deleteSelected() async { + final modifiedTotps = totps; + for (var selectedItem in selected) { + modifiedTotps.remove(selectedItem); + } + await MaxKeyPersistent.instance.saveTotps(modifiedTotps); + setMultiSelect(false); + } + + void update() => notifyListeners(); +} + +class _TotpListView extends StatelessWidget { + const _TotpListView({super.key, required this.controller}); + + final _TotpListViewController controller; + + @override + Widget build(BuildContext context) { + final scheme = Theme.of(context).colorScheme; + return Expanded( + child: ClipRRect( + borderRadius: BorderRadius.circular(8.0), + child: Ink( + decoration: BoxDecoration( + color: scheme.surfaceContainer, + borderRadius: BorderRadius.circular(8.0), + ), + child: ListenableBuilder( + listenable: controller, + builder: (context, _) { + if (controller.totps.isEmpty) { + return Center(child: Text(AppLocalizations.of(context)!.homePageTotpListViewNoTOTP)); + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: ListView.builder( + itemCount: controller.totps.length, + itemBuilder: (context, i) => _TotpCodeCard( + totp: controller.totps[i], + controller: controller, + ), + ), + ), + if (controller.multiSelect) ...[ + Ink( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.0), + ), + child: InkWell( + onTap: () { + controller.setMultiSelect(false); + }, + borderRadius: BorderRadius.circular(8.0), + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Icon( + Icons.cancel_outlined, + color: scheme.onSurface, + ), + ), + ), + ), + ), + const SizedBox(height: 8.0), + Ink( + decoration: BoxDecoration( + color: scheme.errorContainer, + borderRadius: BorderRadius.circular(8.0), + ), + child: InkWell( + onTap: () async { + final confirm = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(AppLocalizations.of(context)!.homePageTotpListViewConfirmDialog), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(false); + }, + child: Text(AppLocalizations.of(context)!.homePageTotpListViewConfirmDialogCancelBtn), + ), + TextButton( + onPressed: () { + Navigator.of(context).pop(true); + }, + child: Text(AppLocalizations.of(context)!.homePageTotpListViewConfirmDialogConfirmBtn), + ), + ], + ), + ); + if (confirm == true) { + await controller.deleteSelected(); + } + }, + borderRadius: BorderRadius.circular(8.0), + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Icon(Icons.delete, color: scheme.error), + ), + ), + ), + ), + ] + ], + ); + }, + ), + ), + ), + ); + } +} + +class _TotpCodeCard extends StatefulWidget { + const _TotpCodeCard( + {super.key, required this.totp, required this.controller}); + + final Totp totp; + final _TotpListViewController controller; + + @override + State<_TotpCodeCard> createState() => _TotpCodeCardState(); +} + +class _TotpCodeCardState extends State<_TotpCodeCard> { + late String password; + late Timer updater; + int validity = 0; + + int getValidity() { + final utc = DateTime.timestamp(); + return widget.totp.interval - (utc.millisecondsSinceEpoch ~/ 1000 % 30); + } + + @override + void initState() { + super.initState(); + password = widget.totp.now; + validity = getValidity(); + + updater = Timer.periodic(const Duration(seconds: 1), (timer) { + validity = getValidity(); + + setState(() { + validity = getValidity(); + if (validity == widget.totp.interval) { + LOGGER.i(DateTime.now()); + password = widget.totp.now; + } + }); + }); + } + + @override + Widget build(BuildContext context) { + return ListTile( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + onLongPress: widget.controller.multiSelect + ? null + : () { + widget.controller.setMultiSelect(!widget.controller.multiSelect); + }, + onTap: widget.controller.multiSelect + ? () { + widget.controller.selectOrNot(widget.totp); + } + : null, + leading: widget.controller.multiSelect + ? Checkbox( + value: widget.controller.hasSelected(widget.totp), + onChanged: (_) { + widget.controller.selectOrNot(widget.totp); + }, + ) + : null, + title: Text(widget.totp.issuer), + subtitle: Text( + password, + style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + trailing: Stack( + alignment: Alignment.center, + children: [ + CircularProgressIndicator( + value: validity / widget.totp.interval, + ), + Text("$validity"), + ], + ), + ); + } + + @override + void dispose() { + super.dispose(); + updater.cancel(); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/user_card.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/user_card.dart new file mode 100644 index 000000000..1a93e0dc3 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/components/user_card.dart @@ -0,0 +1,206 @@ +part of 'package:maxkey_flutter/pages/home_page/page.dart'; + +enum _TimeOfDay { + morning, + noon, + afternoon, + evening; + + const _TimeOfDay(); + + String greeting(BuildContext context) => switch(this) { + _TimeOfDay.morning => AppLocalizations.of(context)!.homePageUserCardGreetingMorning, + _TimeOfDay.noon => AppLocalizations.of(context)!.homePageUserCardGreetingNoon, + _TimeOfDay.afternoon => AppLocalizations.of(context)!.homePageUserCardGreetingAfternoon, + _TimeOfDay.evening => AppLocalizations.of(context)!.homePageUserCardGreetingEvening, + }; + + static const _table = [ + evening, + evening, + evening, + evening, + evening, + morning, + morning, + morning, + morning, + morning, + morning, + noon, + noon, + afternoon, + afternoon, + afternoon, + afternoon, + afternoon, + afternoon, + evening, + evening, + evening, + evening, + evening, + ]; + + factory _TimeOfDay.fromDateTime(DateTime dateTime) { + return _table[dateTime.hour]; + } +} + +class _UserCard extends StatelessWidget { + const _UserCard({super.key, required this.user}); + + final MaxKeyUser user; + + @override + Widget build(BuildContext context) { + final scheme = Theme.of(context).colorScheme; + + return InkWell( + borderRadius: BorderRadius.circular(8.0), + onTap: () { + context.push(RoutePath.userPage, extra: user); + }, + child: Ink( + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 16.0), + decoration: BoxDecoration( + color: scheme.surfaceContainer, + borderRadius: BorderRadius.circular(8.0), + ), + child: Row( + children: [ + ClipOval( + child: user.picture == null + ? Image.asset( + "assets/logo.jpg", + width: 64, + height: 64, + ) + : Image.memory( + user.picture!, + width: 64, + height: 64, + ), + ), + const SizedBox(width: 8), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(_TimeOfDay.fromDateTime(DateTime.now()).greeting(context)), + Text( + user.displayName, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(width: 8), + IconButton( + icon: const Icon(Icons.qr_code_scanner), + onPressed: () async { + final qrCodeValue = await context.push( + RoutePath.scanPage, + extra: AppLocalizations.of(context)!.homePageUserCardScanPage, + ); + + if (qrCodeValue == null) return; + + await MaxKey.instance.authnService.scanCode( + expectedErrorHandler: (msg) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(msg)), + ); + }, + code: qrCodeValue, + ); + }, + ), + const SizedBox(width: 8), + const SizedBox( + height: 40, + width: 40, + child: Icon(Icons.keyboard_arrow_right), + ), + ], + ), + ), + ); + } +} + +/// 加载时 [_UserCard] 的替代组件,头像、问候语和用户名用透明度渐变的圆角矩形代替。 +class _LoadingUserCard extends StatelessWidget { + const _LoadingUserCard({super.key}); + + @override + Widget build(BuildContext context) { + final scheme = Theme.of(context).colorScheme; + + return InkWell( + borderRadius: BorderRadius.circular(8.0), + onTap: () { + context.push(RoutePath.userPage); + }, + child: Ink( + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 16.0), + decoration: BoxDecoration( + color: scheme.surfaceContainer, + borderRadius: BorderRadius.circular(8.0), + ), + child: RepeatTweenAnimationBuilder( + tween: Tween(begin: 0.3, end: 0.7), + duration: const Duration(seconds: 3), + builder: (context, value, _) => Row( + children: [ + Container( + width: 64, + height: 64, + decoration: BoxDecoration( + color: scheme.outline.withOpacity(value), + borderRadius: BorderRadius.circular(32), + ), + ), + const SizedBox(width: 8), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 14, + width: 56, + decoration: BoxDecoration( + color: scheme.outline.withOpacity(value), + borderRadius: BorderRadius.circular(4.0), + ), + ), + const SizedBox(height: 4.0), + Container( + height: 18, + width: 72, + decoration: BoxDecoration( + color: scheme.outline.withOpacity(value), + borderRadius: BorderRadius.circular(4.0), + ), + ), + ], + ), + ), + const SizedBox(width: 8), + const SizedBox( + height: 40, + width: 40, + child: Icon(Icons.keyboard_arrow_right), + ), + ], + ), + ), + ), + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/page.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/page.dart new file mode 100644 index 000000000..403cd493f --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/home_page/page.dart @@ -0,0 +1,74 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:maxkey_flutter/maxkey/maxkey.dart'; +import 'package:maxkey_flutter/maxkey/services/users.service.dart'; +import 'package:maxkey_flutter/persistent.dart'; +import 'package:maxkey_flutter/repeat_tween_animation_builder.dart'; +import 'package:maxkey_flutter/totp.dart'; +import 'package:maxkey_flutter/utils.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +part 'package:maxkey_flutter/pages/home_page/components/new_totp_btn.dart'; +part 'package:maxkey_flutter/pages/home_page/components/totp_list_view.dart'; +part 'package:maxkey_flutter/pages/home_page/components/user_card.dart'; + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + var profile = MaxKey.instance.usersService.getBasicUserInfo(); + final controller = _TotpListViewController(); + + void _update() { + setState(() { + profile = MaxKey.instance.usersService.getBasicUserInfo(); + }); + } + + @override + void initState() { + super.initState(); + MaxKey.instance.addListener(_update); + } + + @override + void dispose() { + super.dispose(); + MaxKey.instance.removeListener(_update); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + FutureBuilder( + future: profile, + builder: (context, snapshot) { + if (snapshot.data == null) { + return const _LoadingUserCard(); + } + + return _UserCard(user: snapshot.data!); + }, + ), + const SizedBox(height: 8), + _NewTotpBtn(controller: controller), + const SizedBox(height: 8), + _TotpListView(controller: controller), + ], + ), + ), + ), + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/components/captcha_view.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/components/captcha_view.dart new file mode 100644 index 000000000..7f75bc1ca --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/components/captcha_view.dart @@ -0,0 +1,49 @@ +part of 'package:maxkey_flutter/pages/login_page/page.dart'; + +class _CaptchaViewController extends ChangeNotifier { + final String loginState; + late Future captcha; + + _CaptchaViewController(this.loginState) { + captcha = MaxKey.instance.imageCaptchaService.captcha(state: loginState); + } + + void getNewCaptcha() { + captcha = MaxKey.instance.imageCaptchaService.captcha(state: loginState); + notifyListeners(); + } +} + +class _CaptchaView extends StatelessWidget { + const _CaptchaView({super.key, required this.controller}); + + final _CaptchaViewController controller; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: controller.getNewCaptcha, + child: ListenableBuilder( + listenable: controller, + builder: (context, _) { + return FutureBuilder( + future: controller.captcha, + builder: (context, snapshot) { + if (snapshot.data == null) { + return const Center( + child: SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator(), + ), + ); + } + + return Image.memory(snapshot.data!, width: 80, height: 25); + }, + ); + }, + ), + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/components/login_view.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/components/login_view.dart new file mode 100644 index 000000000..591b0689e --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/components/login_view.dart @@ -0,0 +1,95 @@ +part of 'package:maxkey_flutter/pages/login_page/page.dart'; + +/// login by username and password +class _NormalLoginView extends StatefulWidget { + const _NormalLoginView({ + super.key, + required this.loginState, + }); + + final String loginState; + + @override + State<_NormalLoginView> createState() => _NormalLoginViewState(); +} + +class _NormalLoginViewState extends State<_NormalLoginView> { + final usernameEditingController = TextEditingController(); + final passwordEditingController = TextEditingController(); + final captchaEditingController = TextEditingController(); + late final captchaViewController = _CaptchaViewController(widget.loginState); + final loginBtnController = WidgetStatesController(); + ValueNotifier obscureText = ValueNotifier(true); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TextField( + controller: usernameEditingController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context)!.loginPageLoginViewUsername, + border: const OutlineInputBorder(), + ), + ), + const SizedBox(height: 16.0), + ListenableBuilder( + listenable: obscureText, + builder: (context, _) { + return TextField( + controller: passwordEditingController, + obscureText: obscureText.value, + decoration: InputDecoration( + labelText: AppLocalizations.of(context)!.loginPageLoginViewPassword, + suffix: IconButton( + onPressed: () { + obscureText.value = !obscureText.value; + }, + icon: Icon( + obscureText.value ? Icons.visibility_off : Icons.visibility, + ), + ), + border: const OutlineInputBorder(), + ), + ); + }, + ), + const SizedBox(height: 16.0), + TextField( + controller: captchaEditingController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context)!.loginPageLoginViewCaptcha, + suffix: _CaptchaView(controller: captchaViewController), + border: const OutlineInputBorder(), + ), + ), + const SizedBox(height: 16.0), + FilledButton( + statesController: loginBtnController, + onPressed: () async { + loginBtnController.update(WidgetState.disabled, true); + final hasSucceed = await MaxKey.instance.authnService.loginNormal( + expectedErrorHandler: (msg) { + loginBtnController.update(WidgetState.disabled, false); + captchaViewController.getNewCaptcha(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(msg)), + ); + }, + state: widget.loginState, + username: usernameEditingController.text, + password: passwordEditingController.text, + captcha: captchaEditingController.text, + ); + + if (hasSucceed && context.mounted) { + context.pushReplacement(RoutePath.homePage); + } + }, + child: Text(AppLocalizations.of(context)!.loginPageLoginViewLoginBtn), + ), + ], + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/page.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/page.dart new file mode 100644 index 000000000..de6eed645 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/login_page/page.dart @@ -0,0 +1,82 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:maxkey_flutter/maxkey/maxkey.dart'; +import 'package:maxkey_flutter/utils.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +part 'package:maxkey_flutter/pages/login_page/components/captcha_view.dart'; +part 'package:maxkey_flutter/pages/login_page/components/login_view.dart'; + +class LoginPage extends StatefulWidget { + const LoginPage({super.key}); + + @override + State createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + var loginGetFuture = MaxKey.instance.authnService.get(); + + void _update() { + setState(() { + loginGetFuture = MaxKey.instance.authnService.get(); + }); + } + + @override + void initState() { + super.initState(); + MaxKey.instance.addListener(_update); + } + + @override + void dispose() { + super.dispose(); + MaxKey.instance.removeListener(_update); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset("assets/logo_maxkey.png"), + const SizedBox(height: 32.0), + FutureBuilder( + future: loginGetFuture, + builder: (context, snapshot) { + if (snapshot.data == null) { + return const SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator(), + ); + } + + return _NormalLoginView(loginState: snapshot.data!); + }, + ), + const SizedBox(height: 8.0), + TextButton( + onPressed: () { + context.push(RoutePath.settingsPage); + }, + child: Text(AppLocalizations.of(context)!.loginPageSettingBtn), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/scan_page.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/scan_page.dart new file mode 100644 index 000000000..29d17f218 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/scan_page.dart @@ -0,0 +1,145 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class ScanPage extends StatelessWidget { + const ScanPage({super.key, required this.title}); + + final String title; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text(title)), + body: ScanView( + resultHandler: (capture, resumeScanner) { + context.pop(capture.barcodes.first.rawValue); + }, + ), + ); + } +} + +typedef ScanViewResultHandler = void Function( + BarcodeCapture capture, + void Function() resumeScanner, +); + +class ScanView extends StatefulWidget { + const ScanView({super.key, required this.resultHandler}); + + /// handle the QR code result. + /// + /// The scanner will stop each time the result is complete. + /// Process the result here and then resume the scanner by calling `resumeScanner`. + final ScanViewResultHandler resultHandler; + + @override + State createState() => _ScanViewState(); +} + +class _ScanViewState extends State with WidgetsBindingObserver { + final scannerController = MobileScannerController( + formats: [BarcodeFormat.qrCode], + ); + + StreamSubscription? subscription; + + bool hasResult = false; + + void resumeScanner() { + hasResult = false; + scannerController.start(); + } + + void handleQRcode(BarcodeCapture capture) { + if (hasResult) return; + hasResult = true; + + scannerController.stop().then((_) { + widget.resultHandler(capture, resumeScanner); + }); + } + + @override + void initState() { + super.initState(); + // Start listening to lifecycle changes. + WidgetsBinding.instance.addObserver(this); + + // Start listening to the barcode events. + subscription = scannerController.barcodes.listen(handleQRcode); + + // Finally, start the scanner itself. + scannerController.start(); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + // If the controller is not ready, do not try to start or stop it. + // Permission dialogs can trigger lifecycle changes before the controller is ready. + if (!scannerController.value.isInitialized) return; + + switch (state) { + case AppLifecycleState.detached: + case AppLifecycleState.hidden: + case AppLifecycleState.paused: + return; + case AppLifecycleState.resumed: + // Restart the scanner when the app is resumed. + // Don't forget to resume listening to the barcode events. + subscription = scannerController.barcodes.listen(handleQRcode); + scannerController.start(); + break; + case AppLifecycleState.inactive: + // Stop the scanner when the app is paused. + // Also stop the barcode events subscription. + subscription?.cancel(); + subscription = null; + scannerController.stop(); + break; + } + } + + @override + Widget build(BuildContext context) { + return MobileScanner( + controller: scannerController, + errorBuilder: (context, error, _) { + final scheme = Theme.of(context).colorScheme; + return ColoredBox( + color: scheme.surface, + child: Center( + child: switch (error.errorCode) { + MobileScannerErrorCode.controllerAlreadyInitialized || + MobileScannerErrorCode.controllerDisposed || + MobileScannerErrorCode.controllerUninitialized || + MobileScannerErrorCode.genericError || + MobileScannerErrorCode.unsupported => + Icon(Icons.error, color: scheme.error), + MobileScannerErrorCode.permissionDenied => Text( + AppLocalizations.of(context)!.scanPagePermissionDeniedMsg, + textAlign: TextAlign.center, + ), + }, + ), + ); + }, + ); + } + + @override + void dispose() async { + // Stop listening to lifecycle changes. + WidgetsBinding.instance.removeObserver(this); + // Stop listening to the barcode events. + subscription?.cancel(); + subscription = null; + super.dispose(); + // Finally, dispose the controller. + scannerController.dispose(); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/host_setting.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/host_setting.dart new file mode 100644 index 000000000..ac75e2d8e --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/host_setting.dart @@ -0,0 +1,98 @@ +part of 'package:maxkey_flutter/pages/settings_page/page.dart'; + +class _SetHostDialog extends StatefulWidget { + const _SetHostDialog({super.key}); + + @override + State<_SetHostDialog> createState() => _SetHostDialogState(); +} + +class _SetHostDialogState extends State<_SetHostDialog> { + final hostEditingController = + TextEditingController(text: MaxKeyPersistent.instance.host); + + /// true: 连接成功;false:链接失败 + bool testResult = true; + String? testDesc; + + @override + Widget build(BuildContext context) { + return SimpleDialog( + title: Text(AppLocalizations.of(context)!.settingsPageHostSettingDialog), + contentPadding: const EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 16.0), + children: [ + TextField( + controller: hostEditingController, + decoration: InputDecoration( + labelText: + AppLocalizations.of(context)!.settingsPageHostSettingDialogHost, + border: const OutlineInputBorder(), + helperText: testResult ? testDesc : null, + errorText: testResult ? null : testDesc, + ), + ), + const SizedBox(height: 16.0), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextButton( + onPressed: () async { + final result = await MaxKey.instance + .maxKeyNetworkTest(host: hostEditingController.text); + setState(() { + testResult = result; + testDesc = result + ? AppLocalizations.of(context)! + .settingsPageHostSettingDialogTestSucceed + : AppLocalizations.of(context)! + .settingsPageHostSettingDialogTestFail; + }); + }, + child: Text(AppLocalizations.of(context)!.settingsPageHostSettingDialogTestBtn), + ), + Row( + children: [ + TextButton( + onPressed: Navigator.of(context).pop, + child: Text(AppLocalizations.of(context)!.settingsPageHostSettingDialogCancleBtn), + ), + const SizedBox(width: 8.0), + TextButton( + onPressed: () async { + await MaxKeyPersistent.instance + .setHost(hostEditingController.text); + MaxKey.instance.updateBaseUrl(); + if (context.mounted) { + Navigator.of(context).pop(); + } + }, + child: Text(AppLocalizations.of(context)!.settingsPageHostSettingDialogConfirmBtn), + ), + ], + ) + ], + ), + ], + ); + } +} + +class _SetHostButton extends StatelessWidget { + const _SetHostButton({super.key}); + + @override + Widget build(BuildContext context) { + return _SettingTile( + title: AppLocalizations.of(context)!.settingsPageHostSettingTitle, + desc: AppLocalizations.of(context)!.settingsPageHostSettingDesc, + action: const Icon(Icons.arrow_outward), + onTap: () { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => const _SetHostDialog(), + ); + }, + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/show_log_btn.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/show_log_btn.dart new file mode 100644 index 000000000..cf8c3b1e4 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/show_log_btn.dart @@ -0,0 +1,56 @@ +part of 'package:maxkey_flutter/pages/settings_page/page.dart'; + +class _ShowLogBtn extends StatelessWidget { + const _ShowLogBtn({super.key}); + + @override + Widget build(BuildContext context) { + return _SettingTile( + title: AppLocalizations.of(context)!.settingsPageShowLogBtnTitle, + action: const Icon(Icons.arrow_outward), + onTap: () { + Navigator.of(context).push( + CupertinoPageRoute(builder: (context) => const _LogDisplayPage()), + ); + }, + ); + } +} + +class _LogDisplayPage extends StatefulWidget { + const _LogDisplayPage({super.key}); + + @override + State<_LogDisplayPage> createState() => __LogDisplayPageState(); +} + +class __LogDisplayPageState extends State<_LogDisplayPage> { + final logEditingController = TextEditingController(); + + @override + void initState() { + super.initState(); + final strbuf = StringBuffer(); + for (var item in LOGGER_MEMORY.buffer) { + strbuf.writeAll(item.lines); + strbuf.writeln(); + } + logEditingController.text = strbuf.toString(); + strbuf.clear(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text(AppLocalizations.of(context)!.settingsPageLogDisplayPageTitle)), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: TextField( + controller: logEditingController, + maxLines: null, + decoration: const InputDecoration(border: InputBorder.none), + ), + ), + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/theme_mode_setting.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/theme_mode_setting.dart new file mode 100644 index 000000000..0130804a5 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/theme_mode_setting.dart @@ -0,0 +1,38 @@ +part of 'package:maxkey_flutter/pages/settings_page/page.dart'; + +class _ThemeModeSwitch extends StatefulWidget { + const _ThemeModeSwitch({super.key}); + + @override + State<_ThemeModeSwitch> createState() => __ThemeModeSwitchState(); +} + +class __ThemeModeSwitchState extends State<_ThemeModeSwitch> { + @override + Widget build(BuildContext context) { + return _SettingTile( + title: AppLocalizations.of(context)!.settingsPageThemeModeSwitchTitle, + action: SegmentedButton( + showSelectedIcon: false, + segments: ThemeMode.values + .map( + (item) => ButtonSegment( + value: item, + icon: switch (item) { + ThemeMode.system => const Icon(Icons.brightness_auto), + ThemeMode.light => const Icon(Icons.light_mode), + ThemeMode.dark => const Icon(Icons.dark_mode), + }, + ), + ) + .toList(), + selected: {MaxKeyPersistent.instance.themeMode}, + onSelectionChanged: (selected) { + setState(() { + MaxKeyPersistent.instance.setThemeMode(selected.first); + }); + }, + ), + ); + } +} \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/page.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/page.dart new file mode 100644 index 000000000..e8f9497fe --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/page.dart @@ -0,0 +1,66 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:maxkey_flutter/maxkey/maxkey.dart'; +import 'package:maxkey_flutter/persistent.dart'; +import 'package:maxkey_flutter/utils.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +part 'package:maxkey_flutter/pages/settings_page/components/theme_mode_setting.dart'; +part 'package:maxkey_flutter/pages/settings_page/components/host_setting.dart'; +part 'package:maxkey_flutter/pages/settings_page/components/show_log_btn.dart'; + +class SettingsPage extends StatelessWidget { + const SettingsPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text(AppLocalizations.of(context)!.settingsPageTitle)), + body: const SafeArea( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + children: [ + _ThemeModeSwitch(), + SizedBox(height: 8.0), + _SetHostButton(), + SizedBox(height: 8.0), + _ShowLogBtn(), + ], + ), + ), + ), + ); + } +} + +class _SettingTile extends StatelessWidget { + const _SettingTile({ + super.key, + required this.title, + this.desc, + required this.action, + this.onTap, + }); + + final String title; + final String? desc; + final Widget action; + final void Function()? onTap; + + @override + Widget build(BuildContext context) { + final scheme = Theme.of(context).colorScheme; + return ListTile( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + tileColor: scheme.surfaceContainer, + title: Text(title, maxLines: 1), + subtitle: desc == null ? null : Text(desc!, maxLines: 2), + isThreeLine: desc == null ? false : true, + trailing: action, + onTap: onTap, + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/user_page/full_user_info_dialog.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/user_page/full_user_info_dialog.dart new file mode 100644 index 000000000..75b49c94d --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/user_page/full_user_info_dialog.dart @@ -0,0 +1,51 @@ +part of 'package:maxkey_flutter/pages/user_page/page.dart'; + +class _FullUserInfoDialog extends StatelessWidget { + const _FullUserInfoDialog({super.key, required this.userInfo}); + + final MaxKeyUserInfo userInfo; + + @override + Widget build(BuildContext context) { + return SimpleDialog( + title: Text(AppLocalizations.of(context)!.userPageFullUserInfoDialogTitle), + children: [ + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogDisplayName, infoValue: userInfo.displayName), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogUsername, infoValue: userInfo.username), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogGender, infoValue: userInfo.gender), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogEmployeeNumber, infoValue: userInfo.employeeNumber), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogMobile, infoValue: userInfo.mobile), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogEmail, infoValue: userInfo.email), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogUserType, infoValue: userInfo.userType), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogUserState, infoValue: userInfo.userState), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogIdType, infoValue: userInfo.idType), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogIdCardNo, infoValue: userInfo.idCardNo), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogMarried, infoValue: userInfo.married), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogBirth, infoValue: userInfo.birthDate), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogOrganization, infoValue: userInfo.organization), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogDivision, infoValue: userInfo.division), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogDepartmentId, infoValue: userInfo.departmentId), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogDepartment, infoValue: userInfo.department), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogJobTitle, infoValue: userInfo.jobTitle), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogJobLevel, infoValue: userInfo.jobLevel), + _UserInfoTile(infoDes: AppLocalizations.of(context)!.userPageFullUserInfoDialogManager, infoValue: userInfo.manager), + ], + ); + } +} + +class _UserInfoTile extends StatelessWidget { + const _UserInfoTile({ + super.key, + required this.infoDes, + required this.infoValue, + }); + + final String infoDes; + final String infoValue; + + @override + Widget build(BuildContext context) { + return ListTile(title: Text(infoDes), subtitle: Text(infoValue)); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/user_page/page.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/user_page/page.dart new file mode 100644 index 000000000..93a62a71c --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/user_page/page.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:maxkey_flutter/maxkey/maxkey.dart'; +import 'package:maxkey_flutter/maxkey/services/users.service.dart'; +import 'package:maxkey_flutter/utils.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +part 'package:maxkey_flutter/pages/user_page/full_user_info_dialog.dart'; + +class UserPage extends StatelessWidget { + const UserPage({super.key, this.user}); + + final MaxKeyUser? user; + + @override + Widget build(BuildContext context) { + final scheme = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar(title: Text(AppLocalizations.of(context)!.userPageTitle)), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column(children: [ + if (user != null) + Ink( + decoration: BoxDecoration( + color: scheme.surfaceContainer, + borderRadius: BorderRadius.circular(8.0), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column(children: [ + _UserCard(user: user!), + _UserPageButtonTile( + title: AppLocalizations.of(context)!.userPageUserInfoBtn, + trailing: Icons.info, + onTap: () async { + final userInfo = await MaxKey.instance.usersService + .getFullUserInfo(); + if (userInfo == null) return; + + if (context.mounted) { + showDialog( + context: context, + builder: (context) => + _FullUserInfoDialog(userInfo: userInfo), + ); + } + }, + ), + ]), + ), + ), + const SizedBox(height: 8.0), + _UserPageButtonTile( + title: AppLocalizations.of(context)!.userPageSettingsBtn, + trailing: Icons.settings, + onTap: () { + context.push(RoutePath.settingsPage); + }, + ), + const SizedBox(height: 8.0), + _UserPageButtonTile( + title: AppLocalizations.of(context)!.userPageLogoutBtn, + trailing: Icons.logout, + onTap: () async { + await MaxKey.instance.authnService.logout(); + + if (context.mounted) { + context.pushReplacement(RoutePath.loginPage); + } + }, + ) + ]), + ), + ), + ); + } +} + +class _UserPageButtonTile extends StatelessWidget { + const _UserPageButtonTile({ + super.key, + required this.title, + required this.trailing, + required this.onTap, + }); + + final String title; + final IconData trailing; + final void Function() onTap; + + @override + Widget build(BuildContext context) { + final scheme = Theme.of(context).colorScheme; + return ListTile( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + tileColor: scheme.surfaceContainer, + title: Text(title), + trailing: Icon(trailing), + onTap: onTap, + ); + } +} + +class _UserCard extends StatelessWidget { + const _UserCard({super.key, required this.user}); + + final MaxKeyUser user; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + ClipOval( + child: user.picture == null + ? Image.asset("assets/logo.jpg", width: 64, height: 64) + : Image.memory(user.picture!, width: 64, height: 64), + ), + const SizedBox(width: 8), + Expanded( + child: Text( + user.displayName, + style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600), + ), + ), + ], + ), + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/persistent.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/persistent.dart new file mode 100644 index 000000000..09f152ca5 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/persistent.dart @@ -0,0 +1,87 @@ +// ignore_for_file: constant_identifier_names, non_constant_identifier_names + +import 'package:flutter/material.dart'; +import 'package:maxkey_flutter/totp.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class MaxKeyPersistent { + static const String _CURR_USER_KEY = "CurrUser"; + + static const String _THEME_MODE_KEY = "ThemeMode"; + + /// 和用户绑定 + String get _TOKEN_KEY => "$_currUser.Token"; + + /// 不和用户绑定 + static const String _HOST_KEY = "Host"; + static const String _DEFAULT_HOST = "192.168.1.66:9527"; + + /// 和用户绑定 + String get _TOTP_LIST_KEY => "$_currUser.TotpList"; + + /// must call [init] first + static final MaxKeyPersistent instance = MaxKeyPersistent(); + + late SharedPreferences _sp; + + static Future init() async { + instance._sp = await SharedPreferences.getInstance(); + instance._readTotps(); + } + + ThemeMode get themeMode => switch (_sp.getString(_THEME_MODE_KEY)) { + "light" => ThemeMode.light, + "dark" => ThemeMode.dark, + _ => ThemeMode.system, + }; + + late ValueNotifier themeModeListenable = ValueNotifier(themeMode); + + String? get _currUser => _sp.getString(_CURR_USER_KEY); + + String? get token => _sp.getString(_TOKEN_KEY); + + /// example: 192.168.220.26:9527 + String get host => _sp.getString(_HOST_KEY) ?? _DEFAULT_HOST; + String get baseUrl => "http://$host/sign"; + + final List _totps = []; + void _readTotps() { + final totpUris = _sp.getStringList(_TOTP_LIST_KEY); + if (totpUris == null) return; + + for (final uri in totpUris) { + final parsed = Totp.fromUri(uri); + if (parsed == null) continue; + _totps.add(parsed); + } + } + + List get totps => _totps; + + Future setThemeMode(ThemeMode themeMode) { + themeModeListenable.value = themeMode; + return _sp.setString(_THEME_MODE_KEY, themeMode.name); + } + + Future setUser(String username) async { + final result = await _sp.setString(_CURR_USER_KEY, username); + _totps.clear(); + if (result) { + instance._readTotps(); + } + return result; + } + + Future setToken(String token) => _sp.setString(_TOKEN_KEY, token); + + /// example: 192.168.220.26:9527 + Future setHost(String host) => _sp.setString(_HOST_KEY, host); + + Future saveTotps(List totps) => _sp.setStringList( + _TOTP_LIST_KEY, + List.generate(totps.length, (i) => totps[i].uri), + ); + + Future clearToken() => _sp.remove(_TOKEN_KEY); +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/repeat_tween_animation_builder.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/repeat_tween_animation_builder.dart new file mode 100644 index 000000000..097b5faec --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/repeat_tween_animation_builder.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; + +/// 由 [TweenAnimationBuilder] 改造的组件,区别在于这个会重复动画。 +class RepeatTweenAnimationBuilder extends ImplicitlyAnimatedWidget { + const RepeatTweenAnimationBuilder({ + super.key, + required this.tween, + required super.duration, + super.curve, + required this.builder, + super.onEnd, + this.child, + }); + + final Tween tween; + final ValueWidgetBuilder builder; + final Widget? child; + + @override + ImplicitlyAnimatedWidgetState createState() { + return _TweenAnimationBuilderState(); + } +} + +class _TweenAnimationBuilderState extends AnimatedWidgetBaseState> { + Tween? _currentTween; + + @override + void initState() { + _currentTween = widget.tween; + _currentTween!.begin ??= _currentTween!.end; + super.initState(); + if (_currentTween!.begin != _currentTween!.end) { + // 使用 repeat 来重复绘制动画。 + controller.repeat(reverse: true); + } + } + + @override + void forEachTween(TweenVisitor visitor) { + assert( + widget.tween.end != null, + 'Tween provided to TweenAnimationBuilder must have non-null Tween.end value.', + ); + _currentTween = visitor(_currentTween, widget.tween.end, (dynamic value) { + assert(false); + throw StateError('Constructor will never be called because null is never provided as current tween.'); + }) as Tween?; + } + + @override + Widget build(BuildContext context) { + return widget.builder(context, _currentTween!.evaluate(animation), widget.child); + } +} \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/totp.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/totp.dart new file mode 100644 index 000000000..213ecec16 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/totp.dart @@ -0,0 +1,55 @@ +import 'package:auth_totp/auth_totp.dart'; + +/// otpauth://totp/{}?secret={}&issuer={} +class Totp { + /// for persistent + final String uri; + final String issuer; + + final String secret; + final int interval; + + Totp({ + required this.uri, + required this.issuer, + required this.secret, + required this.interval, + }); + + String get now => AuthTOTP.generateTOTPCode( + secretKey: secret, + interval: interval, + ); + + static Totp? fromUri(String uri) { + final totpUri = Uri.tryParse(uri); + if (totpUri == null) return null; + + final query = totpUri.queryParameters; + final secret = query["secret"]; + if (secret == null) return null; + + // final digit = query["digits"]; + final period = query["period"]; + final issuerQuery = query["issuer"]; + + final lastPathSeg = totpUri.pathSegments.lastOrNull; + final colonPos = lastPathSeg?.indexOf(":"); + final account = colonPos == null + ? null + : colonPos == -1 + ? lastPathSeg! + : lastPathSeg!.substring(colonPos + 1); + + final issuer = issuerQuery == null + ? lastPathSeg ?? "UNKNOWN" + : "$issuerQuery${account == null ? "" : ":$account"}"; + + return Totp( + uri: uri, + issuer: issuer, + secret: secret, + interval: period == null ? 30 : int.tryParse(period) ?? 30, + ); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/lib/utils.dart b/summer-ospp/2024/Flutter/maxkey_flutter/lib/utils.dart new file mode 100644 index 000000000..d6c27e1de --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/lib/utils.dart @@ -0,0 +1,34 @@ +// ignore_for_file: constant_identifier_names, non_constant_identifier_names + +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:logger/logger.dart'; + +final LOGGER_MEMORY = MemoryOutput(); +final LOGGER = Logger( + filter: ProductionFilter(), + printer: SimplePrinter(), + output: kDebugMode + ? MultiOutput([LOGGER_MEMORY, ConsoleOutput()]) + : LOGGER_MEMORY, + level: Level.all, +); + +final SCAFFOLD_MESSENGER_KEY = GlobalKey(); +final NAVIGATOR_KEY = GlobalKey(); + +class RoutePath { + static const loginPage = "/login"; + static const homePage = "/home"; + static const scanPage = "/scan"; + static const userPage = "/user"; + static const settingsPage = "/settings"; +} + +extension Base64 on String { + Uint8List base64ToBuf() { + return base64.decode(this); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/pubspec.lock b/summer-ospp/2024/Flutter/maxkey_flutter/pubspec.lock new file mode 100644 index 000000000..a02dec258 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/pubspec.lock @@ -0,0 +1,431 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + auth_totp: + dependency: "direct main" + description: + name: auth_totp + sha256: "51bb03ed052baf09661e5c65b3ed4eaf8bcd1ed70696b96935fd560792ad9aee" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + url: "https://pub.dev" + source: hosted + version: "3.0.5" + dio: + dependency: "direct main" + description: + name: dio + sha256: "0dfb6b6a1979dac1c1245e17cef824d7b452ea29bd33d3467269f9bef3715fb0" + url: "https://pub.dev" + source: hosted + version: "5.6.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: "2ddb88e9ad56ae15ee144ed10e33886777eb5ca2509a914850a5faa7b52ff459" + url: "https://pub.dev" + source: hosted + version: "14.2.7" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + intl: + dependency: "direct main" + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + url: "https://pub.dev" + source: hosted + version: "10.0.5" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + lints: + dependency: transitive + description: + name: lints + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + url: "https://pub.dev" + source: hosted + version: "3.0.0" + logger: + dependency: "direct main" + description: + name: logger + sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.dev" + source: hosted + version: "1.15.0" + mobile_scanner: + dependency: "direct main" + description: + name: mobile_scanner + sha256: "6ac2913ad98c83f558d2c8a55bc8f511bdcf28b86639701c04b04c16da1e9ee1" + url: "https://pub.dev" + source: hosted + version: "5.2.1" + path: + dependency: transitive + description: + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + platform: + dependency: transitive + description: + name: platform + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + url: "https://pub.dev" + source: hosted + version: "3.1.5" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "480ba4345773f56acda9abf5f50bd966f581dac5d514e5fc4a18c62976bbba7e" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f + url: "https://pub.dev" + source: hosted + version: "2.5.2" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e + url: "https://pub.dev" + source: hosted + version: "2.4.2" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + url: "https://pub.dev" + source: hosted + version: "0.7.2" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + url: "https://pub.dev" + source: hosted + version: "14.2.5" + web: + dependency: transitive + description: + name: web + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 + url: "https://pub.dev" + source: hosted + version: "1.0.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + url: "https://pub.dev" + source: hosted + version: "1.0.4" +sdks: + dart: ">=3.5.1 <4.0.0" + flutter: ">=3.22.0" diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/pubspec.yaml b/summer-ospp/2024/Flutter/maxkey_flutter/pubspec.yaml new file mode 100644 index 000000000..a009504bc --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/pubspec.yaml @@ -0,0 +1,33 @@ +name: maxkey_flutter +description: "MaxKey Flutter project." +publish_to: 'none' +version: 1.0.0 + +environment: + sdk: ^3.5.1 + +dependencies: + dio: ^5.4.3+1 + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + go_router: ^14.2.0 + mobile_scanner: ^5.1.1 + # permission_handler: ^11.3.1 + shared_preferences: ^2.2.3 + auth_totp: ^1.0.1 + logger: ^2.4.0 + intl: ^0.19.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^3.0.0 + +flutter: + generate: true + uses-material-design: true + assets: + - assets/logo.jpg + - assets/logo_maxkey.png \ No newline at end of file diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/CMakeLists.txt b/summer-ospp/2024/Flutter/maxkey_flutter/windows/CMakeLists.txt new file mode 100644 index 000000000..f0f10871e --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/CMakeLists.txt @@ -0,0 +1,108 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(maxkey_flutter LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "maxkey_flutter") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(VERSION 3.14...3.25) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/CMakeLists.txt b/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/CMakeLists.txt new file mode 100644 index 000000000..903f4899d --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/CMakeLists.txt @@ -0,0 +1,109 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# Set fallback configurations for older versions of the flutter tool. +if (NOT DEFINED FLUTTER_TARGET_PLATFORM) + set(FLUTTER_TARGET_PLATFORM "windows-x64") +endif() + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + ${FLUTTER_TARGET_PLATFORM} $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugin_registrant.cc b/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 000000000..8b6d4680a --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugin_registrant.h b/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 000000000..dc139d85a --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugins.cmake b/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugins.cmake new file mode 100644 index 000000000..b93c4c30c --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/CMakeLists.txt b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/CMakeLists.txt new file mode 100644 index 000000000..394917c05 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/Runner.rc b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/Runner.rc new file mode 100644 index 000000000..39855cde0 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD +#else +#define VERSION_AS_NUMBER 1,0,0,0 +#endif + +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "org.dromara.maxkey" "\0" + VALUE "FileDescription", "maxkey_flutter" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "maxkey_flutter" "\0" + VALUE "LegalCopyright", "Copyright (C) 2024 org.dromara.maxkey. All rights reserved." "\0" + VALUE "OriginalFilename", "maxkey_flutter.exe" "\0" + VALUE "ProductName", "maxkey_flutter" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/flutter_window.cpp b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/flutter_window.cpp new file mode 100644 index 000000000..955ee3038 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/flutter_window.cpp @@ -0,0 +1,71 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + + flutter_controller_->engine()->SetNextFrameCallback([&]() { + this->Show(); + }); + + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/flutter_window.h b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/flutter_window.h new file mode 100644 index 000000000..6da0652f0 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/main.cpp b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/main.cpp new file mode 100644 index 000000000..bacba0951 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.Create(L"maxkey_flutter", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/resource.h b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/resource.h new file mode 100644 index 000000000..66a65d1e4 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/resources/app_icon.ico b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c04e20caf6370ebb9253ad831cc31de4a9c965f6 GIT binary patch literal 33772 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 literal 0 HcmV?d00001 diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/runner.exe.manifest b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/runner.exe.manifest new file mode 100644 index 000000000..a42ea7687 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/utils.cpp b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/utils.cpp new file mode 100644 index 000000000..3a0b46511 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/utils.cpp @@ -0,0 +1,65 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + unsigned int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); + std::string utf8_string; + if (target_length == 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + input_length, utf8_string.data(), target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/utils.h b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/utils.h new file mode 100644 index 000000000..3879d5475 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/win32_window.cpp b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/win32_window.cpp new file mode 100644 index 000000000..60608d0fe --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/win32_window.cpp @@ -0,0 +1,288 @@ +#include "win32_window.h" + +#include +#include + +#include "resource.h" + +namespace { + +/// Window attribute that enables dark mode window decorations. +/// +/// Redefined in case the developer's machine has a Windows SDK older than +/// version 10.0.22000.0. +/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +/// Registry key for app theme preference. +/// +/// A value of 0 indicates apps should use dark mode. A non-zero or missing +/// value indicates apps should use light mode. +constexpr const wchar_t kGetPreferredBrightnessRegKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; +constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + } + FreeLibrary(user32_module); +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registrar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::Create(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + UpdateTheme(window); + + return OnCreate(); +} + +bool Win32Window::Show() { + return ShowWindow(window_handle_, SW_SHOWNORMAL); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + UpdateTheme(hwnd); + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} + +void Win32Window::UpdateTheme(HWND const window) { + DWORD light_mode; + DWORD light_mode_size = sizeof(light_mode); + LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, + kGetPreferredBrightnessRegValue, + RRF_RT_REG_DWORD, nullptr, &light_mode, + &light_mode_size); + + if (result == ERROR_SUCCESS) { + BOOL enable_dark_mode = light_mode == 0; + DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, + &enable_dark_mode, sizeof(enable_dark_mode)); + } +} diff --git a/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/win32_window.h b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/win32_window.h new file mode 100644 index 000000000..e901dde68 --- /dev/null +++ b/summer-ospp/2024/Flutter/maxkey_flutter/windows/runner/win32_window.h @@ -0,0 +1,102 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates a win32 window with |title| that is positioned and sized using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size this function will scale the inputted width and height as + // as appropriate for the default monitor. The window is invisible until + // |Show| is called. Returns true if the window was created successfully. + bool Create(const std::wstring& title, const Point& origin, const Size& size); + + // Show the current window. Returns true if the window was successfully shown. + bool Show(); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + // Update the window frame's theme to match the system theme. + static void UpdateTheme(HWND const window); + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_