Commit e53ceeae by Administrator

Merge branch 'develop251027' into develop

内容合并
2 parents ba18c03b efd1f3ba
Showing 86 changed files with 2338 additions and 806 deletions
......@@ -43,3 +43,5 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
assets/static
pubspec.lock
......@@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.
version:
revision: "05db9689081f091050f01aed79f04dce0c750154"
revision: "fcf2c11572af6f390246c056bc905eca609533a0"
channel: "stable"
project_type: app
......@@ -13,14 +13,26 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
create_revision: fcf2c11572af6f390246c056bc905eca609533a0
base_revision: fcf2c11572af6f390246c056bc905eca609533a0
- platform: android
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
create_revision: fcf2c11572af6f390246c056bc905eca609533a0
base_revision: fcf2c11572af6f390246c056bc905eca609533a0
- platform: ios
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
create_revision: fcf2c11572af6f390246c056bc905eca609533a0
base_revision: fcf2c11572af6f390246c056bc905eca609533a0
- platform: linux
create_revision: fcf2c11572af6f390246c056bc905eca609533a0
base_revision: fcf2c11572af6f390246c056bc905eca609533a0
- platform: macos
create_revision: fcf2c11572af6f390246c056bc905eca609533a0
base_revision: fcf2c11572af6f390246c056bc905eca609533a0
- platform: web
create_revision: fcf2c11572af6f390246c056bc905eca609533a0
base_revision: fcf2c11572af6f390246c056bc905eca609533a0
- platform: windows
create_revision: fcf2c11572af6f390246c056bc905eca609533a0
base_revision: fcf2c11572af6f390246c056bc905eca609533a0
# User provided section
......
✅ 执行安装:
cd macos
pod install --repo-update
✅ 返回项目根目录,重新运行 Flutter:
flutter clean
flutter pub get
flutter run -d macos
flutter run -d 00008030-001C75810E42402E --release
......@@ -72,6 +72,11 @@ android {
release {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}
......
# 微信SDK混淆规则
-keep class com.tencent.mm.opensdk.** {
*;
}
-keep class com.tencent.wxop.** {
*;
}
-keep class com.tencent.mm.sdk.** {
*;
}
# ffmpegkit
-keep class com.antonkarpenko.**{
*;
}
# 可选:如果遇到兼容性问题,可以忽略警告
-dontwarn com.tencent.mm.**
\ No newline at end of file
No preview for this file type
# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'
#platform :ios, '12.0'
#source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
#platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
......@@ -25,11 +26,14 @@ end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
pod 'SDWebImage', :git => 'https://gitee.com/mirrors/SDWebImage.git', :branch => '5.21.3'
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
# pod 'SDWebImage', :modular_headers => true
# pod 'SDWebImageWebPCoder', :modular_headers => true
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
......
PODS:
- device_info_plus (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.9):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
- DKImagePickerController/ImageDataManager (4.3.9)
- DKImagePickerController/PhotoGallery (4.3.9):
- DKImagePickerController/Core
- DKPhotoGallery
- DKImagePickerController/Resource (4.3.9)
- DKPhotoGallery (0.0.19):
- DKPhotoGallery/Core (= 0.0.19)
- DKPhotoGallery/Model (= 0.0.19)
- DKPhotoGallery/Preview (= 0.0.19)
- DKPhotoGallery/Resource (= 0.0.19)
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Core (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Preview
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Model (0.0.19):
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Preview (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Resource
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Resource (0.0.19):
- SDWebImage
- SwiftyGif
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Flutter (1.0.0)
- flutter_image_compress_common (1.0.0):
- Flutter
- Mantle
- SDWebImage
- SDWebImageWebPCoder
- flutter_sound (9.28.0):
- Flutter
- flutter_sound_core (= 9.28.0)
- flutter_sound_core (9.28.0)
- fluwx (0.0.1):
- Flutter
- fluwx/pay (= 0.0.1)
- fluwx/pay (0.0.1):
- Flutter
- WechatOpenSDK-XCFramework (~> 2.0.5)
- gallery_saver_plus (0.0.1):
- Flutter
- image_picker_ios (0.0.1):
- Flutter
- libwebp (1.5.0):
- libwebp/demux (= 1.5.0)
- libwebp/mux (= 1.5.0)
- libwebp/sharpyuv (= 1.5.0)
- libwebp/webp (= 1.5.0)
- libwebp/demux (1.5.0):
- libwebp/webp
- libwebp/mux (1.5.0):
- libwebp/demux
- libwebp/sharpyuv (1.5.0)
- libwebp/webp (1.5.0):
- libwebp/sharpyuv
- Mantle (2.2.0):
- Mantle/extobjc (= 2.2.0)
- Mantle/extobjc (2.2.0)
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.3.0):
- Flutter
- SDWebImage (5.21.3):
- SDWebImage/Core (= 5.21.3)
- SDWebImage/Core (5.21.3)
- SDWebImageWebPCoder (0.14.6):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.17)
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SwiftyGif (5.4.5)
- video_thumbnail (0.0.1):
- Flutter
- libwebp
- webview_flutter_wkwebview (0.0.1):
- Flutter
- FlutterMacOS
- WechatOpenSDK-XCFramework (2.0.5)
DEPENDENCIES:
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- Flutter (from `Flutter`)
- flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`)
- flutter_sound (from `.symlinks/plugins/flutter_sound/ios`)
- fluwx (from `.symlinks/plugins/fluwx/ios`)
- gallery_saver_plus (from `.symlinks/plugins/gallery_saver_plus/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- SDWebImage (from `https://gitee.com/mirrors/SDWebImage.git`, branch `5.21.3`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- video_thumbnail (from `.symlinks/plugins/video_thumbnail/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
SPEC REPOS:
trunk:
- DKImagePickerController
- DKPhotoGallery
- flutter_sound_core
- libwebp
- Mantle
- SDWebImageWebPCoder
- SwiftyGif
- WechatOpenSDK-XCFramework
EXTERNAL SOURCES:
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
Flutter:
:path: Flutter
flutter_image_compress_common:
:path: ".symlinks/plugins/flutter_image_compress_common/ios"
flutter_sound:
:path: ".symlinks/plugins/flutter_sound/ios"
fluwx:
:path: ".symlinks/plugins/fluwx/ios"
gallery_saver_plus:
:path: ".symlinks/plugins/gallery_saver_plus/ios"
image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
SDWebImage:
:branch: 5.21.3
:git: https://gitee.com/mirrors/SDWebImage.git
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
video_thumbnail:
:path: ".symlinks/plugins/video_thumbnail/ios"
webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
CHECKOUT OPTIONS:
SDWebImage:
:commit: 7312c9ce5e1987cb6cbf11213b5fc1fc03abe3a8
:git: https://gitee.com/mirrors/SDWebImage.git
SPEC CHECKSUMS:
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1
flutter_sound: b9236a5875299aaa4cef1690afd2f01d52a3f890
flutter_sound_core: 427465f72d07ab8c3edbe8ffdde709ddacd3763c
fluwx: 620a35d7ba14842304dc2b19fed6b4e279da9d0f
gallery_saver_plus: 61c8a831d5975e2bf57f87bcd64379dcc7d29ff2
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
SDWebImage: 22f3e17ef402a1cabed97a37a36397ec1f36e435
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
video_thumbnail: b637e0ad5f588ca9945f6e2c927f73a69a661140
webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2
WechatOpenSDK-XCFramework: ff342ae616bb86df3d236aca38059dfd4bc4a949
PODFILE CHECKSUM: 796b297eb3180da7b164556770b43e60cda83073
COCOAPODS: 1.16.2
......@@ -10,10 +10,12 @@
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 */; };
6195576B9D418343AB34E015 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED57D221E8D3BC8E83480055 /* Pods_RunnerTests.framework */; };
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 */; };
9D502E39210F4B2991CE880A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9242BFBDC74ED293FFF97CFF /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -40,14 +42,20 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1205687D9E053B2F6A9E6441 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
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 = "<group>"; };
58F47B35F2929DEC901A4F5E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
72B093583222E5CFD5B22D88 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7A979E981C1A2F29ECB7C40B /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
916E9168046628C285790488 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
9242BFBDC74ED293FFF97CFF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
......@@ -55,13 +63,25 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9D3F96B8EE7557F98EE703F9 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
D900F592122DCCA6D37CEE01 /* Runner.entitlements */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
ED57D221E8D3BC8E83480055 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
12C8B2DF0818C1515D0F7BB6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6195576B9D418343AB34E015 /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9D502E39210F4B2991CE880A /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -76,6 +96,15 @@
path = RunnerTests;
sourceTree = "<group>";
};
6CCCFE30A41FF3C468D704CD /* Frameworks */ = {
isa = PBXGroup;
children = (
9242BFBDC74ED293FFF97CFF /* Pods_Runner.framework */,
ED57D221E8D3BC8E83480055 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
......@@ -94,6 +123,8 @@
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
F4367DCDE78D6820D90794C8 /* Pods */,
6CCCFE30A41FF3C468D704CD /* Frameworks */,
);
sourceTree = "<group>";
};
......@@ -117,10 +148,24 @@
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
D900F592122DCCA6D37CEE01 /* Runner.entitlements */,
);
path = Runner;
sourceTree = "<group>";
};
F4367DCDE78D6820D90794C8 /* Pods */ = {
isa = PBXGroup;
children = (
58F47B35F2929DEC901A4F5E /* Pods-Runner.debug.xcconfig */,
72B093583222E5CFD5B22D88 /* Pods-Runner.release.xcconfig */,
916E9168046628C285790488 /* Pods-Runner.profile.xcconfig */,
9D3F96B8EE7557F98EE703F9 /* Pods-RunnerTests.debug.xcconfig */,
1205687D9E053B2F6A9E6441 /* Pods-RunnerTests.release.xcconfig */,
7A979E981C1A2F29ECB7C40B /* Pods-RunnerTests.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
......@@ -128,8 +173,10 @@
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
8BB0CD16D8D912D6FA006A19 /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
12C8B2DF0818C1515D0F7BB6 /* Frameworks */,
);
buildRules = (
);
......@@ -145,12 +192,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
6004AF99D521941E4EA2BC9A /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
8C7A12FE9D383AD28E41B4E3 /* [CP] Embed Pods Frameworks */,
46CAE28B97BBB37B25040A8D /* [CP] Copy Pods Resources */,
);
buildRules = (
);
......@@ -238,6 +288,84 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
46CAE28B97BBB37B25040A8D /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
6004AF99D521941E4EA2BC9A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
8BB0CD16D8D912D6FA006A19 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
8C7A12FE9D383AD28E41B4E3 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
......@@ -327,6 +455,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
......@@ -338,6 +467,7 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
FLUTTER_BUILD_MODE = release;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
......@@ -361,7 +491,9 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 42794B2KBU;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
......@@ -378,6 +510,7 @@
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9D3F96B8EE7557F98EE703F9 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
......@@ -395,6 +528,7 @@
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 1205687D9E053B2F6A9E6441 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
......@@ -410,6 +544,7 @@
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7A979E981C1A2F29ECB7C40B /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
......@@ -447,6 +582,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
......@@ -458,6 +594,7 @@
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
FLUTTER_BUILD_MODE = release;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
......@@ -504,6 +641,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
......@@ -515,6 +653,7 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
FLUTTER_BUILD_MODE = release;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
......@@ -524,7 +663,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_ENABLE_DEBUG_INFO = YES;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
......@@ -540,7 +679,9 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 42794B2KBU;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
......@@ -562,7 +703,9 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 42794B2KBU;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
......
......@@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
......@@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
......@@ -20,10 +22,54 @@
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>weixin</string>
<key>CFBundleURLSchemes</key>
<array>
<string>wx8c32ea248f0c7765</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
<string>weixinULAPI</string>
<string>weixinURLParamsAPI</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>dev.banxiaoer.net</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
<key>NSCameraUsageDescription</key>
<string>需要访问相机</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要麦克风权限用于录音</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册选择图片或视频</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
......@@ -41,9 +87,7 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<key>io.flutter.embedded_views_preview</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:dev.banxiaoer.net</string>
</array>
</dict>
</plist>
......@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:appframe/l10n/gen/app_localizations.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; // 添加这行
import 'config/routes.dart';
......@@ -15,6 +16,16 @@ class App extends StatelessWidget {
routerConfig: router,
title: '班小二',
theme: const CupertinoThemeData(primaryColor: CupertinoColors.systemBlue),
// === 为 iOS 添加本地化配置 ===
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate, // 为Material组件提供本地化
GlobalCupertinoLocalizations.delegate, // 为Cupertino组件提供本地化
GlobalWidgetsLocalizations.delegate, // 定义文本方向等
],
supportedLocales: const [
Locale('zh', 'CN'), // 中文(中国)
Locale('en', 'US'), // 英语(美国)
],
)
: MaterialApp.router(
localizationsDelegates: AppLocalizations.localizationsDelegates,
......@@ -22,5 +33,15 @@ class App extends StatelessWidget {
routerConfig: router,
title: '班小二',
theme: ThemeData(primarySwatch: Colors.blue),
// // === 为 iOS 添加本地化配置 ===
// localizationsDelegates: const [
// GlobalMaterialLocalizations.delegate, // 为Material组件提供本地化
// GlobalCupertinoLocalizations.delegate, // 为Cupertino组件提供本地化
// GlobalWidgetsLocalizations.delegate, // 定义文本方向等
// ],
// supportedLocales: const [
// Locale('zh', 'CN'), // 中文(中国)
// Locale('en', 'US'), // 英语(美国)
// ],
);
}
import 'dart:async';
import 'package:appframe/config/routes.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class AdvState extends Equatable {
final int countdown;
const AdvState({this.countdown = 5});
AdvState copyWith({
int? countdown,
}) {
return AdvState(
countdown: countdown ?? this.countdown,
);
}
@override
List<Object?> get props => [countdown];
}
class AdvCubit extends Cubit<AdvState> {
Timer? _timer;
AdvCubit() : super(AdvState()) {
_startCountdown();
}
void _startCountdown() {
var count = state.countdown;
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
count--;
if (count <= 0) {
_timer?.cancel();
router.go('/web');
} else {
emit(state.copyWith(countdown: count));
}
});
}
@override
Future<void> close() {
try {
_timer?.cancel();
} catch (e) {
print(e);
}
return super.close();
}
}
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/routes.dart';
import 'package:appframe/data/repositories/wechat_auth_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluwx/fluwx.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../config/locator.dart';
class LoginMainState extends Equatable {
final bool agreed;
final bool showAgreed;
const LoginMainState({this.agreed = false, this.showAgreed = false});
@override
List<Object?> get props => [agreed, showAgreed];
LoginMainState copyWith({
bool? agreed,
bool? showAgreed,
}) {
return LoginMainState(
agreed: agreed ?? this.agreed,
showAgreed: showAgreed ?? this.showAgreed,
);
}
}
class LoginMainCubit extends Cubit<LoginMainState> {
late final Fluwx _fluwx;
late final WechatAuthRepository _wechatAuthRepository;
LoginMainCubit(super.initialState) {
_fluwx = getIt.get<Fluwx>();
_fluwx.addSubscriber(_responseListener);
_wechatAuthRepository = getIt<WechatAuthRepository>();
}
void toggleAgreed(bool value) {
emit(state.copyWith(agreed: value));
}
void confirmAgreed() {
emit(state.copyWith(agreed: true, showAgreed: false));
wechatAuth();
}
void cancelAgreed() {
emit(state.copyWith(showAgreed: false));
}
void wechatAuth() async {
if (!state.agreed) {
emit(state.copyWith(showAgreed: true));
return;
}
var result = await _fluwx.authBy(
which: NormalAuth(scope: 'snsapi_userinfo', state: 'wechat_sdk_test'),
);
if (!result) {
throw Exception('微信授权处理失败');
}
}
void goLoginPhone() {
router.go('/loginPhone');
}
void _responseListener(WeChatResponse response) async {
if (response is WeChatAuthResponse) {
if (response.code == null || response.code == '') {
return;
}
dynamic resultData = await _wechatAuthRepository.codeToSk(response.code!);
var data = resultData['data'];
var role = data['roles'][0];
final sessionCode = data['sessionCode'];
final userCode = data['userCode'];
final classCode = role['classCode'];
final userType = role['userType'];
final stuId = role['stuId'];
var sharedPreferences = getIt.get<SharedPreferences>();
sharedPreferences.setString('auth_sessionCode', sessionCode);
sharedPreferences.setString('auth_userCode', userCode);
sharedPreferences.setString('auth_classCode', classCode);
sharedPreferences.setInt('auth_userType', userType);
sharedPreferences.setString('auth_stuId', stuId ?? '');
sharedPreferences.setString('auth_ip', Constant.h5Server);
router.go(
'/web',
extra: {
'ip': Constant.h5Server,
'sessionCode': sessionCode,
'userCode': userCode,
'classCode': classCode,
'userType': userType,
'stuId': stuId,
},
);
}
}
}
import 'dart:async';
import 'package:appframe/config/routes.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class LoginPhoneState extends Equatable {
final bool agreed;
final bool showAgreed;
final String phone;
final String password;
final bool allowSend;
final int seconds;
const LoginPhoneState(
{this.agreed = false,
this.showAgreed = false,
this.phone = '',
this.password = '',
this.allowSend = true,
this.seconds = 0});
LoginPhoneState copyWith({
bool? agreed,
bool? showAgreed,
String? phone,
String? password,
bool? allowSend,
int? seconds,
}) {
return LoginPhoneState(
agreed: agreed ?? this.agreed,
showAgreed: showAgreed ?? this.showAgreed,
phone: phone ?? this.phone,
password: password ?? this.password,
allowSend: allowSend ?? this.allowSend,
seconds: seconds ?? this.seconds,
);
}
@override
List<Object?> get props => [phone, password, agreed, showAgreed, allowSend, seconds];
}
class LoginPhoneCubit extends Cubit<LoginPhoneState> {
late TextEditingController _phoneController;
late TextEditingController _codeController;
Timer? _timer;
int countdown = 60; // 倒计时秒数
TextEditingController get phoneController => _phoneController;
TextEditingController get codeController => _codeController;
LoginPhoneCubit(super.initialState) {
_phoneController = TextEditingController();
_codeController = TextEditingController();
_phoneController.text = state.phone;
_codeController.text = state.password;
}
/// 开始倒计时
void startCountdown() {
countdown = 60;
emit(state.copyWith(allowSend: false, seconds: countdown));
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
countdown--;
if (countdown <= 0) {
_timer?.cancel();
emit(state.copyWith(allowSend: true, seconds: 60));
} else {
emit(state.copyWith(seconds: countdown));
}
});
}
/// 发送验证码
void sendVerificationCode() {
if (state.allowSend) {
// 实际发送验证码的逻辑
startCountdown(); // 开始倒计时
}
}
void toggleAgreed(bool value) {
emit(state.copyWith(agreed: value));
}
void goLoginMain() {
router.go('/loginMain');
}
@override
Future<void> close() async {
try {
_phoneController.dispose();
} catch (e) {
print(e);
}
try {
_codeController.dispose();
} catch (e) {
print(e);
}
await super.close();
}
}
import 'package:appframe/config/db.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart';
import 'package:appframe/services/mqtt_service.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mqtt_client/mqtt_client.dart';
class MqttState extends Equatable {
final List<String> messages;
const MqttState({this.messages = const []});
MqttState copyWith({List<String>? messages}) {
return MqttState(
messages: messages ?? this.messages,
);
}
@override
List<Object?> get props => [messages];
}
class MqttCubit extends Cubit<MqttState> with WidgetsBindingObserver {
late MqttService _mqttService;
MqttCubit() : super(MqttState()) {
_mqttService = getIt.get<MqttService>();
_mqttService.listen(_onMessageReceived);
WidgetsBinding.instance.addObserver(this);
}
void goWeb() {
router.go('/web');
}
@override
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
// print('----------------------didChangeAppLifecycleState------------------------------');
if (state == AppLifecycleState.resumed) {
// print('----------------------resumed------------------------------');
if (!_mqttService.isConnected()) {
// print('----------------------reconnected------------------------------');
await _mqttService.initConn();
_mqttService.listen(_onMessageReceived);
}
}
}
Future<void> _onMessageReceived(List<MqttReceivedMessage<MqttMessage?>>? c) async {
final recMess = c![0].payload as MqttPublishMessage;
final pt = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
print('-------------------------> $pt');
// Map<String, dynamic> data = {"id": 1, "content": pt};
// bxeDb.insert('msg', data);
//
// var msgList = await bxeDb.query('msg');
// for (var msg in msgList) {
// print('-------------------------> $msg');
// }
// 处理接收到的消息
emit(state.copyWith(messages: [...state.messages, pt]));
}
@override
Future<void> close() {
// 关闭时移除观察者
WidgetsBinding.instance.removeObserver(this);
return super.close();
}
}
......@@ -197,17 +197,21 @@ class WebCubit extends Cubit<WebState> {
// closeLocalPlayer();
},
onPageFinished: (String url) async {
_controller.runJavaScript(
'document.querySelector("meta[name=viewport]").setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no")',
);
finishLoading();
print('onPageFinished--------------------------------->');
print(url);
if (url == '${Constant.localServerTestFileUrl}/login.html') {
return;
}
// 页面加载完成时,清空录音和音频(如果有打开过)
await clearRecording();
await clearAudio();
print('onPageFinished--------------------------------->');
print(url);
_controller.runJavaScript(
'document.querySelector("meta[name=viewport]").setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no")',
);
finishLoading();
},
),
)
......@@ -225,11 +229,14 @@ class WebCubit extends Cubit<WebState> {
final String serverUrl;
if (state.sessionCode == null || state.sessionCode == '') {
serverUrl = '${Constant.localServerTestFileUrl}/login.html';
serverUrl = '${Constant.localServerUrl}/index.html';
// serverUrl = '${Constant.localServerTestFileUrl}/login.html';
// serverUrl = '${Constant.localServerTestFileUrl}/test2.html';
} else {
// serverUrl =
// 'http://${state.ip}:${_server.port}/index.html#/h5/login/pages/applogin?sessionCode=${state.sessionCode}&userCode=${state.userCode}&classCode=${state.classCode}&userType=${state.userType}&stuId=${state.stuId}';
serverUrl =
'http://${state.ip}:${_server.port}/index.html#/h5/login/pages/applogin?sessionCode=${state.sessionCode}&userCode=${state.userCode}&classCode=${state.classCode}&userType=${state.userType}&stuId=${state.stuId}';
'${Constant.localServerUrl}/index.html#/h5/login/pages/applogin?sessionCode=${state.sessionCode}&userCode=${state.userCode}&classCode=${state.classCode}&userType=${state.userType}&stuId=${state.stuId}';
}
_controller.loadRequest(Uri.parse(serverUrl));
......@@ -267,6 +274,14 @@ class WebCubit extends Cubit<WebState> {
router.go('/wechatAuth');
}
void goLogin() {
router.go('/loginMain');
}
void goMqtt(){
router.go('/mqtt');
}
//测试
void goAuth() {
// String serverUrl = 'http://${state.ip}:${_server.port}/index.html';
......@@ -741,7 +756,6 @@ class WebCubit extends Cubit<WebState> {
try {
await _recorder?.closeRecorder();
} catch (e) {
// ignore: empty_catches
print(e);
}
emit(state.copyWith(recorderIsInit: false, recordState: 0, recordPath: ''));
......@@ -843,7 +857,6 @@ class WebCubit extends Cubit<WebState> {
try {
await _player?.closePlayer();
} catch (e) {
// ignore: empty_catches
print(e);
}
emit(state.copyWith(playerIsInit: false, playState: 0, playId: ''));
......@@ -860,14 +873,12 @@ class WebCubit extends Cubit<WebState> {
try {
await _recorder?.closeRecorder();
} catch (e) {
// ignore: empty_catches
print(e);
}
try {
await _player?.closePlayer();
} catch (e) {
// ignore: empty_catches
print(e);
}
......
......@@ -12,7 +12,7 @@ class Constant {
static const int obsUploadChunkSize = 1024 * 1024 * 5;
/// 测试阶段使用的 h5 服务地址
static const String h5Server = 'appdev-xj.banxiaoer.net';
// static const String h5Server = 'appdev-th.banxiaoer.net';
// static const String h5Server = 'appdev-xj.banxiaoer.net';
static const String h5Server = 'appdev-th.banxiaoer.net';
// static const String h5Server = '192.168.1.136';
}
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
late final Database bxeDb;
Future<void> initDatabase() async {
// 获取数据库存储的默认路径
String databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'bxe_database.db');
// 打开数据库,如果不存在则创建
Database database = await openDatabase(
path,
version: 1, // 数据库版本
onCreate: (Database db, int version) async {
// 创建表
await db.execute(
// 'CREATE TABLE msg(id INTEGER PRIMARY KEY, content TEXT)',
'CREATE TABLE msg(id INTEGER, content TEXT)',
);
},
);
bxeDb = database;
}
import 'dart:io';
import 'package:archive/archive.dart';
import 'package:flutter/services.dart';
late HttpServer localServer;
Future<void> startLocalServer() async {
HttpServer localServer = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
// print('本地服务器启动在端口: ${localServer.port}');
localServer.listen((HttpRequest request) async {
final String requestPath = request.uri.path == '/' ? '/index.html' : request.uri.path;
try {
if (requestPath.startsWith('/temp/')) {
// 临时目录文件的请求
await _serveTempFile(request, requestPath);
} else if (requestPath.startsWith('/test/')) {
// assets文件服务逻辑
await _serveAssetFile(request, requestPath);
} else {
// asset/dist.zip 文件服务逻辑
await _serveZipFileContent(request, requestPath);
}
} catch (e) {
print('处理请求时出错: $e');
request.response
..statusCode = HttpStatus.internalServerError
..write('Internal server error')
..close();
}
});
}
// 临时目录的文件
Future<void> _serveTempFile(HttpRequest request, String requestPath) async {
try {
// 临时文件已经设备路径
// 构建文件路径(移除 /temp 前缀)
final String filePath = requestPath.substring('/temp/'.length);
// 检查文件是否存在
final File file = File(filePath);
if (await file.exists()) {
// 读取文件内容
final List<int> bytes = await file.readAsBytes();
request.response
..headers.contentType = ContentType.parse(_getContentType(filePath))
..add(bytes)
..close();
} else {
request.response
..statusCode = HttpStatus.notFound
..write('File not found: $filePath')
..close();
}
} catch (e) {
print('读取临时文件时出错: $e');
request.response
..statusCode = HttpStatus.notFound
..write('File not found')
..close();
}
}
Future<void> _serveZipFileContent(HttpRequest request, String requestPath) async {
String zipAssetPath = 'assets/dist.zip';
try {
// 使用 rootBundle.load 加载资源文件
final ByteData data = await rootBundle.load(zipAssetPath);
final List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
// 读取并解压zip文件内容
final Archive archive = ZipDecoder().decodeBytes(bytes);
// 查找请求的内部文件
ArchiveFile? targetFile;
for (final file in archive) {
// 标准化路径分隔符(统一使用 '/')
String zipFileName = file.name.replaceAll('\\', '/');
// 移除开头的 '/'(如果存在)
if (requestPath.startsWith('/')) {
requestPath = requestPath.substring(1);
}
if (zipFileName == requestPath) {
targetFile = file;
break;
}
}
if (targetFile == null) {
request.response
..statusCode = HttpStatus.notFound
..write('File not found in zip: $requestPath')
..close();
return;
}
// 返回文件内容
request.response
..headers.contentType = ContentType.parse(_getContentType(requestPath))
..add(targetFile.content as List<int>)
..close();
} catch (e) {
print('读取zip文件时出错: $e');
request.response
..statusCode = HttpStatus.internalServerError
..write('Error reading zip file')
..close();
}
}
// 访问assets目录下的文件
Future<void> _serveAssetFile(HttpRequest request, String requestPath) async {
// 构建文件路径(移除 /test 前缀)
final String path = requestPath.substring('/test'.length);
final String filePath = 'assets$path';
try {
final ByteData data = await rootBundle.load(filePath);
final List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
request.response
..headers.contentType = ContentType.parse(_getContentType(filePath))
..add(bytes)
..close();
} catch (e) {
request.response
..statusCode = HttpStatus.notFound
..write('File not found: $filePath')
..close();
}
}
String _getContentType(String filePath) {
if (filePath.endsWith('.html')) return 'text/html';
if (filePath.endsWith('.js')) return 'application/javascript';
if (filePath.endsWith('.css')) return 'text/css';
if (filePath.endsWith('.png')) return 'image/png';
if (filePath.endsWith('.jpg') || filePath.endsWith('.jpeg')) return 'image/jpeg';
return 'application/octet-stream';
}
......@@ -33,6 +33,7 @@ import 'package:appframe/services/dispatcher.dart';
import 'package:fluwx/fluwx.dart';
import 'package:get_it/get_it.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:io' show Platform;
final getIt = GetIt.instance;
......@@ -41,7 +42,9 @@ Future<void> setupLocator() async {
getIt.registerSingleton<Fluwx>(
await (() async {
Fluwx fluwx = Fluwx();
await fluwx.registerApi(appId: "wx8c32ea248f0c7765", universalLink: "https://univerallink.banxe.cn/link/");
if (Platform.isAndroid || Platform.isIOS) {
await fluwx.registerApi(appId: "wx8c32ea248f0c7765", universalLink: "https://dev.banxiaoer.net/path/to/wechat/");
}
return fluwx;
})(),
);
......@@ -169,6 +172,7 @@ Future<void> setupLocator() async {
/// service
getIt.registerLazySingleton<ApiService>(() => ApiService(baseUrl: 'https://dev.banxiaoer.net'));
/// repository
getIt.registerLazySingleton<WechatAuthRepository>(() => WechatAuthRepository());
}
import 'package:appframe/config/locator.dart';
import 'package:appframe/services/mqtt_service.dart';
/// 此处暂时测试
/// 正常需要在登录状态下,查询host和jwt
Future<void> registerMqtt() async {
String mqttHost = '58.87.99.45';
int mqttPort = 1883;
String mqttClientId = 'asdfasdf';
int keepAlive = 60;
String mqttUsername = 'user';
String mqttPassword =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjIzOTY5MDQsInJzIjoib2sifQ.tsouW-uHTe6ndiEqSE4wcR_oSScuoS0qVvqWtNSaXgWkX2yEja9ImnMYr6jNKxJY8_qox9UdXRuCept5cTM4-8ZaA0BBlYXwr3LbC3yPmniFhs-tAMFbZqG2-3r0sc5NMbE3M1fXMi3dmvQc2AlyazheL98EmRNILFsz6pZ-x5rR1gFulZ53PXa7fX60XRlXg8jc3-89gdUJcS0MOMU7yyU0Sv3QBBplLr3CmWCoYX99a_3QHvq3o7aUTJ_Ed5Ms9_3k4QHgawsfdTWjZkyBouAvLMgVkt4D0PJbhgsjzAaA01Q7jEJ_SokNojOFfQYuHNScczmlOLXocJCCD4189A';
/// 初始化MQTT客户端
var mqttService = MqttService(mqttHost, mqttPort, mqttClientId, keepAlive, mqttUsername, mqttPassword);
await mqttService.initConn();
/// 设置到getIt,用于获取使用
getIt.registerSingleton(mqttService);
}
import 'package:appframe/ui/pages/adv_page.dart';
import 'package:appframe/ui/pages/link_page.dart';
import 'package:appframe/ui/pages/login_main_page.dart';
import 'package:appframe/ui/pages/login_phone_page.dart';
import 'package:appframe/ui/pages/mqtt_page.dart';
import 'package:appframe/ui/pages/scan_code_page.dart';
import 'package:appframe/ui/pages/web_page.dart';
import 'package:appframe/ui/pages/wechat_auth_page.dart';
......@@ -6,7 +10,7 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
final GoRouter router = GoRouter(
initialLocation: '/web',
initialLocation: '/adv',
routes: <RouteBase>[
GoRoute(
path: '/web',
......@@ -32,5 +36,29 @@ final GoRouter router = GoRouter(
return const LinkPage();
},
),
GoRoute(
path: '/loginMain',
builder: (BuildContext context, GoRouterState state) {
return const LoginMainPage();
},
),
GoRoute(
path: '/loginPhone',
builder: (BuildContext context, GoRouterState state) {
return const LoginPhonePage();
},
),
GoRoute(
path: '/adv',
builder: (BuildContext context, GoRouterState state) {
return const AdvPage();
},
),
GoRoute(
path: '/mqtt',
builder: (BuildContext context, GoRouterState state) {
return const MqttPage();
},
),
],
);
import 'package:fluwx/fluwx.dart';
final Fluwx fluwx = Fluwx();
Future<void> registerWechatApi() async {
await fluwx.registerApi(appId: "wx8c32ea248f0c7765", universalLink: "https://dev.banxiaoer.net/path/to/wechat/");
}
......@@ -15,6 +15,7 @@ class AudioPlayHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(dynamic params) async {
try {
if (params is! Map<String, dynamic>) {
throw Exception('参数错误');
}
......@@ -23,6 +24,9 @@ class AudioPlayHandler extends MessageHandler {
bool result = await _webCubit!.playAudio(url);
return result;
} finally {
_unfollowCubit();
}
}
}
......
......@@ -15,8 +15,12 @@ class AudioRecorderStartHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(dynamic params) async {
try {
bool result = await _webCubit!.startRecording();
return result;
} finally {
_unfollowCubit();
}
}
}
......@@ -34,8 +38,12 @@ class AudioRecorderPauseHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(dynamic params) async {
try {
bool result = await _webCubit!.pauseRecording();
return result;
} finally {
_unfollowCubit();
}
}
}
......@@ -53,8 +61,12 @@ class AudioRecorderResumeHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(dynamic params) async {
try {
bool result = await _webCubit!.resumeRecording();
return result;
} finally {
_unfollowCubit();
}
}
}
......@@ -72,7 +84,11 @@ class AudioRecorderStopHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(dynamic params) async {
try {
return await _webCubit!.stopRecording();
} finally {
_unfollowCubit();
}
}
}
......@@ -90,6 +106,10 @@ class AudioRecorderClearHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(dynamic params) async {
try {
return await _webCubit!.clearRecording();
} finally {
_unfollowCubit();
}
}
}
......@@ -21,6 +21,7 @@ class ChooseImageHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(params) async {
try {
if (params is! Map<String, dynamic>) {
throw Exception('参数错误');
}
......@@ -46,5 +47,8 @@ class ChooseImageHandler extends MessageHandler {
}
_webCubit!.setChooseImageCmdFlag(true, _message!);
} finally {
_unfollowCubit();
}
}
}
......@@ -21,6 +21,7 @@ class ChooseVideoHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(params) async {
try {
if (params is! Map<String, dynamic>) {
throw Exception('参数错误');
}
......@@ -46,134 +47,8 @@ class ChooseVideoHandler extends MessageHandler {
}
_webCubit!.setChooseVideoCmdFlag(true, _message!);
} finally {
_unfollowCubit();
}
}
}
// class ChooseVideoHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(params) async {
// if (params is! Map<String, dynamic>) {
// throw Exception('参数错误');
// }
// var sourceType = params['sourceType'] as String;
// if (sourceType != 'album' && sourceType != 'camera') {
// throw Exception('参数错误');
// }
// // 暂时忽略对此参数的处理
// List<dynamic>? sizeType;
// if (params.containsKey('sizeType')) {
// sizeType = params['sizeType'] as List<dynamic>;
// if (sizeType.isEmpty || sizeType.length > 2) {
// throw Exception('参数错误');
// }
// }
//
// int count = 1;
// if (params.containsKey('count')) {
// count = params['count'] as int;
// if (count < 1 || count > 9) {
// throw Exception('参数错误');
// }
// }
//
// int number = 60;
// if (params.containsKey('number')) {
// number = params['number'] as int;
// if (number < 1 || number > 60) {
// throw Exception('参数错误');
// }
// }
//
// // 从相册选择
// if (sourceType == 'album') {
// if (count == 1) {
// return await _selectSingleVideo();
// } else {
// return await _selectMultiVideo(count);
// }
// }
// // 拍摄
// else {
// return await _cameraSingle();
// }
// }
//
// Future<List<dynamic>> _selectSingleVideo() async {
// final ImagePicker picker = ImagePicker();
// final XFile? pickedVideo = await picker.pickVideo(source: ImageSource.gallery);
//
// // 用户取消选择,返回空数组
// if (pickedVideo == null) {
// return [];
// }
//
// // 获取临时目录
// final Directory tempDir = await getTemporaryDirectory();
//
// return [await _handleOne(pickedVideo, tempDir)];
// }
//
// Future<List<dynamic>> _selectMultiVideo(int limit) async {
// final ImagePicker picker = ImagePicker();
// final List<XFile> pickedVideoList = await picker.pickMultiVideo(limit: limit);
//
// // 用户取消选择,返回空数组
// if (pickedVideoList.isEmpty) {
// return [];
// }
//
// // 限制最多limit张
// if (pickedVideoList.length > limit) {
// pickedVideoList.removeRange(limit, pickedVideoList.length);
// }
//
// // 获取临时目录
// final Directory tempDir = await getTemporaryDirectory();
//
// final List<Map<String, dynamic>> result = [];
// for (final XFile? file in pickedVideoList) {
// if (file != null) {
// result.add(await _handleOne(file, tempDir));
// }
// }
// return result;
// }
//
// ///
// /// 拍照
// ///
// Future<List<Map<String, dynamic>>?> _cameraSingle() async {
// final ImagePicker picker = ImagePicker();
//
// final XFile? pickedFile = await picker.pickVideo(source: ImageSource.camera);
//
// // 用户取消选择,返回空数组
// if (pickedFile == null) {
// return [];
// }
//
// // 获取临时目录
// final Directory tempDir = await getTemporaryDirectory();
//
// return [await _handleOne(pickedFile, tempDir)];
// }
//
// Future<Map<String, dynamic>> _handleOne(XFile pickedFile, Directory tempDir) async {
// var sourceFile = File(pickedFile.path);
//
// final thumbnailPath = await ThumbnailUtil.genVideoThumbnail(pickedFile.path, tempDir);
// // 暂时这样进行接口测试
// // 根据视频预览图,获取视频的宽度和高度
// final sizeResult = ImageSizeGetter.getSizeResult(FileInput(File(thumbnailPath!)));
//
// // 返回一个元素的数组
// return {
// "tempFilePath": "/temp${sourceFile.path}",
// "size": sourceFile.lengthSync(),
// "width": sizeResult.size.width,
// "height": sizeResult.size.height,
// "thumbTempFilePath": '/temp$thumbnailPath',
// "fileType": sourceFile.path.split('/').last.split('.').last,
// };
// }
// }
......@@ -15,7 +15,11 @@ class GoLoginHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(params) async {
_webCubit!.goWechatAuth();
try {
_webCubit!.goLogin();
return;
} finally {
_unfollowCubit();
}
}
}
......@@ -21,6 +21,10 @@ class OrientationHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(params) async {
try {
_webCubit!.setOrientationCmdFlag(true, _message!);
} finally {
_unfollowCubit();
}
}
}
import 'dart:ffi';
import 'package:appframe/services/dispatcher.dart';
import 'package:flutter_sound/flutter_sound.dart';
FlutterSoundPlayer? localPlayer;
bool isLocalPlaying = false;
bool isLocalPausePlaying = false;
String? localPlayedFilePath;
Future<bool> initLocalPlayer() async {
localPlayer = FlutterSoundPlayer();
try {
await localPlayer!.openPlayer();
} catch (e) {
print(e);
await _resetPlayerStatus();
throw Exception('打开播放器失败!');
}
return true;
}
Future<bool> startLocalPlayer(String url) async {
if (localPlayer == null) {
await initLocalPlayer();
}
try {
localPlayedFilePath = url;
localPlayer!.startPlayer(fromURI: url);
return true;
} catch (e) {
print(e);
await _resetPlayerStatus();
return false;
}
}
Future<bool> pauseLocalPlayer() async {
if(!(isLocalPlaying==true && isLocalPausePlaying==false)) {
return false;
}
try {
await localPlayer!.pausePlayer();
return true;
} catch (e) {
print(e);
await _resetPlayerStatus();
return false;
}
}
Future<bool> resumeLocalPlayer() async {
if(!(isLocalPlaying==true && isLocalPausePlaying==true)) {
return false;
}
try {
await localPlayer!.resumePlayer();
return true;
} catch (e) {
print(e);
await _resetPlayerStatus();
return false;
}
}
Future<bool> stopLocalPlayer() async {
try {
localPlayer!.stopPlayer();
return true;
} catch (e) {
print(e);
return false;
} finally {
await _resetPlayerStatus();
}
}
void closeLocalPlayer() async {
await _resetPlayerStatus();
}
Future<void> _resetPlayerStatus() async {
try {
await localPlayer?.closePlayer();
} catch (e) {
print(e);
}
localPlayer = null;
isLocalPlaying = false;
isLocalPausePlaying = false;
localPlayedFilePath = null;
}
// class AudioPlayHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// bool result = await startLocalPlayer(params['url']);
// return result;
// }
// }
//
// class AudioPauseHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// bool result = await pauseLocalPlayer();
// return result;
// }
// }
//
// class AudioResumeHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// bool result = await resumeLocalPlayer();
// return result;
// }
// }
//
// class AudioStopHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// bool result = await stopLocalPlayer();
// return result;
// }
// }
//
// class AudioClearHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// closeLocalPlayer();
// return true;
// }
// }
import 'package:appframe/services/dispatcher.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
/*录音相关全局参数*/
FlutterSoundRecorder? localRecorder;
bool isLocalRecording = false;
bool isLocalPauseRecording = false;
String? localRecordedFilePath;
Future<bool> initLocalRecorder() async {
// 请求麦克风权限
var status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
throw RecordingPermissionException('no auth');
}
if (!(!isLocalRecording && !isLocalPauseRecording && localRecordedFilePath == null)) {
return false;
}
// 打开录音器
FlutterSoundRecorder recorder = FlutterSoundRecorder();
try {
localRecorder = await recorder.openRecorder();
return true;
} catch (e) {
print(e);
await _resetRecorderStatus();
throw Exception('打开录音器失败!');
}
}
Future<bool> startLocalRecording() async {
if (isLocalRecording) {
return false;
}
if (!await initLocalRecorder()) {
return false;
}
try {
// 获取应用文档目录路径
final directory = await getApplicationDocumentsDirectory();
String filePath = '${directory.path}/bxe_recording.aac';
await localRecorder!.startRecorder(toFile: filePath, codec: Codec.aacMP4);
isLocalRecording = true;
isLocalPauseRecording = false;
localRecordedFilePath = filePath;
return true;
} catch (e) {
print(e);
await _resetRecorderStatus();
return false;
}
}
Future<bool> pauseLocalRecording() async {
if (!(isLocalRecording && !isLocalPauseRecording)) {
return false;
}
try {
await localRecorder!.pauseRecorder();
isLocalPauseRecording = true;
return true;
} catch (e) {
print(e);
await _resetRecorderStatus();
return false;
}
}
Future<bool> resumeLocalRecording() async {
if (!(isLocalRecording && isLocalPauseRecording)) {
return false;
}
try {
await localRecorder!.resumeRecorder();
isLocalPauseRecording = false;
return true;
} catch (e) {
print(e);
await _resetRecorderStatus();
return false;
}
}
Future<String?> stopLocalRecording() async {
if (!(localRecorder != null && isLocalRecording)) {
throw Exception("录音器未初始化");
}
try {
String? url = await localRecorder!.stopRecorder();
isLocalRecording = false;
isLocalPauseRecording = false;
if (url == null || url == "") {
throw Exception("录音失败");
}
await _resetRecorderStatus();
return url;
} catch (e) {
print(e);
await _resetRecorderStatus();
throw Exception("录音失败");
}
}
/// 关闭录音器,释放资源
void closeLocalRecorder() async {
await _resetRecorderStatus();
}
Future<void> _resetRecorderStatus() async {
try {
await localRecorder?.closeRecorder();
} catch (e) {
print(e);
}
localRecorder == null;
isLocalRecording = false;
isLocalPauseRecording = false;
localRecordedFilePath = null;
}
// class AudioRecorderStartHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// bool result = await startLocalRecording();
// return result;
// }
// }
//
// class AudioRecorderPauseHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// bool result = await pauseLocalRecording();
// return result;
// }
// }
//
// class AudioRecorderResumeHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// bool result = await resumeLocalRecording();
// return result;
// }
// }
//
// class AudioRecorderStopHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// return await stopLocalRecording();
// }
// }
//
// class AudioRecorderClearHandler extends MessageHandler {
// @override
// Future<dynamic> handleMessage(dynamic params) async {
// closeLocalRecorder();
// return true;
// }
// }
import 'dart:async';
import 'package:appframe/services/dispatcher.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:flutter/material.dart';
import 'package:appframe/bloc/web_cubit.dart';
import 'package:appframe/services/dispatcher.dart';
class ScanCodeHandler extends MessageHandler {
late WebCubit? _webCubit;
......
......@@ -15,6 +15,7 @@ class SetTitleHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(params) async {
try {
if (params is! Map<String, dynamic>) {
throw Exception('参数错误');
}
......@@ -23,5 +24,8 @@ class SetTitleHandler extends MessageHandler {
final bool showBack = params['showBack'] as bool;
return _webCubit!.setTitle(title, showBack);
} finally {
_unfollowCubit();
}
}
}
......@@ -16,7 +16,14 @@ class UpgradeHandler extends MessageHandler {
final version = params['version'] as String;
// 1 下载
var direct = await getExternalStorageDirectory();
Directory? direct;
if (Platform.isAndroid) {
direct = await getExternalStorageDirectory();
} else if (Platform.isIOS || Platform.isMacOS) {
direct = await getApplicationDocumentsDirectory();
} else {
throw Exception('未知平台');
}
var saveFilePath = '${direct?.path}/dist_$version.zip';
var dio = Dio();
......
......@@ -21,6 +21,10 @@ class WindowInfoHandler extends MessageHandler {
@override
Future<dynamic> handleMessage(dynamic params) async {
try {
_webCubit!.setWindowInfoCmdFlag(true, _message!);
} finally {
_unfollowCubit();
}
}
}
import 'package:appframe/config/db.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/config/wechat.dart';
import 'package:appframe/config/mqtt.dart';
import 'package:flutter/material.dart';
import 'app.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await registerWechatApi();
await setupLocator();
await registerMqtt();
await initDatabase();
runApp(const App());
}
......@@ -144,10 +144,13 @@ class LocalServerService {
}
Future<void> _initHttpDirectory() async {
if (Platform.isAndroid) {
var direct = await getExternalStorageDirectory();
_httpDirectory = '${direct?.path}/http_dist_assets';
// var direct = await getApplicationSupportDirectory();
// _httpDirectory = '${direct.path}/http_dist_assets';
} else if (Platform.isIOS || Platform.isMacOS) {
var direct = await getApplicationSupportDirectory();
_httpDirectory = '${direct.path}/http_dist_assets';
}
}
Future<void> _extractDist() async {
......@@ -190,8 +193,7 @@ class LocalServerService {
var distUrl = "https://github.com/xinxin-wu/flutter_web_dist/releases/download/v1.0.0/dist.zip";
// Dio进行下载
var dio = Dio();
dio
.download(
dio.download(
distUrl,
'$httpDirectory/dist.zip',
onReceiveProgress: (received, total) {
......@@ -199,8 +201,7 @@ class LocalServerService {
print((received / total * 100).toStringAsFixed(0) + "%");
}
},
)
.then((_) {
).then((_) {
_extractDist();
});
dio.close();
......
import 'dart:async';
import 'dart:io';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
class MqttService {
/// MQTT服务器信息
final String _host;
final int _port;
final String _clientId;
final int _keepAlive;
final String _username;
/// 重连的时候要重新获取一下 token
final String _password;
/// MQTT客户端
late MqttServerClient _client;
StreamSubscription? _subscription;
/// MQTT重连相关变量
int _reconnectAttempts = 0;
final int _maxReconnectAttempts = 5;
Timer? _reconnectTimer;
MqttService(this._host, this._port, this._clientId, this._keepAlive, this._username, this._password);
Future<void> initConn() async {
_client = MqttServerClient(_host, _clientId);
_client.logging(on: false);
_client.port = _port;
_client.keepAlivePeriod = _keepAlive;
_client.onDisconnected = onDisconnected;
_client.onConnected = onConnected;
_client.onSubscribed = onSubscribed;
_client.pongCallback = pong;
final connMess = MqttConnectMessage()
.withWillTopic('willtopic')
.withWillMessage('My Will message')
.startClean()
.withWillQos(MqttQos.atLeastOnce);
_client.connectionMessage = connMess;
try {
print('MQTT 开始连接......');
await _client.connect(_username, _password);
} on NoConnectionException catch (e) {
print('MQTT客户端连接失败: $e');
_client.disconnect();
} on SocketException catch (e) {
print('MQTT客户端连接失败: $e');
_client.disconnect();
}
// 订阅主题
subscribe("\$q/bxe/abc");
// 监听消息
listen(onMessageReceived);
}
void onConnected() {
print('MQTT客户端连接成功');
_reconnectAttempts = 0;
_reconnectTimer?.cancel();
}
void onDisconnected() {
print('MQTT客户端断开连接');
// if (_reconnectAttempts < _maxReconnectAttempts) {
// handleReconnect(_host, _port, _clientId, '');
// }
}
void onSubscribed(String topic) {
print('MQTT客户端订阅主题: $topic');
}
void onMessageReceived(List<MqttReceivedMessage<MqttMessage?>>? c) {
final recMess = c![0].payload as MqttPublishMessage;
final pt = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
print('MQTT消息接收: topic is ${c[0].topic}, payload is $pt');
// 处理接收到的消息
}
void subscribe(String topic) {
_client.subscribe(topic, MqttQos.atLeastOnce);
}
void listen(Function(List<MqttReceivedMessage<MqttMessage?>>? c) onMessageReceivedCallback) {
_subscription?.cancel();
_subscription = _client.updates?.listen(onMessageReceivedCallback);
}
void disconnect() {
_client.disconnect();
}
bool isConnected() {
return _client.connectionStatus?.state == MqttConnectionState.connected;
}
void pong() {
print('Ping response client callback invoked');
}
void onMqttMessageReceived(List<MqttReceivedMessage<MqttMessage?>>? c) {
final recMess = c![0].payload as MqttPublishMessage;
final pt = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
print('MQTT消息接收: topic is ${c[0].topic}, payload is $pt');
// 处理接收到的消息
}
void handleReconnect(String host, int port, String username, String password) {
if (_reconnectAttempts >= _maxReconnectAttempts) {
print('已达到最大重连次数,停止重连');
return;
}
_reconnectAttempts++;
print('第 $_reconnectAttempts 次重连尝试,${_maxReconnectAttempts - _reconnectAttempts} 次机会剩余');
// 取消之前的重连定时器(如果有)
_reconnectTimer?.cancel();
// 设置延迟重连,每次重连间隔递增
final delay = Duration(seconds: _reconnectAttempts * 5);
_reconnectTimer = Timer(delay, () async {
print('正在尝试重新连接...');
await initConn();
if (!isConnected()) {
disconnect();
}
});
}
}
import 'package:appframe/bloc/adv_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class AdvPage extends StatelessWidget {
const AdvPage({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => AdvCubit(),
child: BlocConsumer<AdvCubit, AdvState>(
builder: (context, state) {
return Scaffold(
appBar: AppBar(
title: Text(''),
),
// body: Center(
// child: Text(
// '${state.countdown}',
// style: TextStyle(fontSize: 50),
// ),
// ),
body: Stack(children: [
Center(
child: GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('点击了开屏广告')));
},
child: Text(
'开屏广告',
style: TextStyle(fontSize: 50),
)),
),
Positioned(
bottom: 30,
right: 30,
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xFF7691FA),
),
child: Center(
child: Text(
'${state.countdown}',
style: TextStyle(fontSize: 20, color: Colors.white),
),
),
),
),
]),
);
},
listener: (context, state) {}),
);
}
}
import 'package:appframe/bloc/login_main_cubit.dart';
import 'package:appframe/ui/widgets/login/login_page_agreed_widget.dart';
import 'package:appframe/ui/widgets/login/login_page_header_widget.dart';
import 'package:appframe/ui/widgets/login/login_page_image_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class LoginMainPage extends StatelessWidget {
const LoginMainPage({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => LoginMainCubit(LoginMainState()),
child: BlocConsumer<LoginMainCubit, LoginMainState>(builder: (context, state) {
var loginMainCubit = context.read<LoginMainCubit>();
return Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Colors.white,
body: SafeArea(
top: false,
child: SingleChildScrollView(
child: Column(
children: [
LoginPageImageWidget(),
Transform.translate(
offset: Offset(0, -40), // 向上移动40像素
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
color: Colors.white, // 设置背景色
),
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 30),
// _buildHeader(),
LoginPageHeaderWidget(),
SizedBox(height: 25),
_buildLoginButtons(context, loginMainCubit, state.agreed),
SizedBox(height: 20),
_buildAgreement(context, loginMainCubit, state.agreed),
],
),
),
),
],
)),
),
);
}, listener: (context, state) {
if (state.showAgreed) {
_showAgreementDialog(context, context.read<LoginMainCubit>());
}
}),
);
}
Widget _buildHeader() {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'欢迎登录',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
SizedBox(height: 6),
Text(
'班小二,班级群必备效率工具',
style: TextStyle(
fontSize: 14,
color: Colors.black87,
),
),
],
);
}
Widget _buildLoginButtons(BuildContext context, LoginMainCubit loginMainCubit, bool agreed) {
return Column(
children: [
SizedBox(
width: double.infinity,
height: 47,
child: ElevatedButton(
onPressed: () {
loginMainCubit.wechatAuth();
},
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF00CB60),
foregroundColor: Colors.white,
textStyle: TextStyle(fontSize: 19),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(23.5),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/login/wechat_white_icon.png'),
SizedBox(width: 6),
Text('微信登录'),
],
),
),
),
SizedBox(height: 15),
SizedBox(
width: double.infinity,
height: 47,
child: ElevatedButton(
onPressed: () {
loginMainCubit.goLoginPhone();
},
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF7691FA),
foregroundColor: Colors.white,
textStyle: TextStyle(fontSize: 19),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(23.5),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/login/phone_white_icon.png'),
// SizedBox(width: 8),
Text('手机号登录'),
],
),
),
),
],
);
}
Widget _buildAgreement(BuildContext context, LoginMainCubit loginMainCubit, bool agreed) {
return Padding(
padding: const EdgeInsets.only(bottom: 32.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Theme(
data: Theme.of(context).copyWith(
checkboxTheme: CheckboxThemeData(
shape: CircleBorder(
side: BorderSide(width: 0.5, color: Color(0xFF999999)),
),
fillColor: WidgetStateProperty.resolveWith<Color>(
(Set<WidgetState> states) {
if (states.contains(WidgetState.selected)) {
return Color(0xFF7691FA); // 选中时的颜色
}
return Colors.white; // 未选中时的颜色
},
),
checkColor: WidgetStateProperty.all<Color>(Colors.white),
side: BorderSide(width: 0.5, color: Color(0xFF999999)),
),
cardColor: Colors.white,
unselectedWidgetColor: Color(0xFF999999),
),
child: Checkbox(
value: agreed,
onChanged: (bool? value) {
loginMainCubit.toggleAgreed(value!);
},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, // 缩小点击区域,减小间隔
),
),
LoginPageAgreedWidget(),
],
),
);
}
Future<void> _showAgreementDialog(BuildContext context, LoginMainCubit loginMainCubit) async {
final result = await showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
title: Text(
'个人信息保护指引',
style: TextStyle(
fontSize: 17,
color: Color(0xFF000000),
// fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
content: Text.rich(
TextSpan(
children: [
TextSpan(
text: '感谢使用班小二APP,为保护您的个人权益,请仔细阅读并充分理解',
style: TextStyle(color: Color(0xFF666666), fontSize: 14),
),
TextSpan(
text: '《班小二数据据安全和隐私政策》',
style: TextStyle(color: Color(0xFF7691FA), fontSize: 14),
),
TextSpan(
text: '与',
style: TextStyle(color: Color(0xFF666666), fontSize: 14),
),
TextSpan(
text: '《用户协议》',
style: TextStyle(color: Color(0xFF7691FA), fontSize: 14),
),
TextSpan(
text: '。如您同意上述文件的全部内容,请点击“同意”以继续。',
style: TextStyle(color: Color(0xFF666666), fontSize: 14),
),
],
),
),
actions: [
Table(
children: [
TableRow(
children: [
TableCell(
child: TextButton(
onPressed: () {
Navigator.of(context).pop();
},
style: TextButton.styleFrom(
foregroundColor: Color(0xFF666666),
textStyle: TextStyle(fontSize: 17),
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.zero,
),
),
child: Text('放弃登录'),
),
),
TableCell(
child: TextButton(
onPressed: () {
Navigator.of(context).pop('OK');
},
style: TextButton.styleFrom(
foregroundColor: Color(0xFF7691FA),
textStyle: TextStyle(fontSize: 17),
minimumSize: Size.fromHeight(40),
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.zero,
),
),
child: Text('同意'),
),
),
],
),
],
),
],
);
},
);
if (result != null) {
loginMainCubit.confirmAgreed();
} else {
loginMainCubit.cancelAgreed();
}
}
}
import 'package:appframe/bloc/login_phone_cubit.dart';
import 'package:appframe/ui/widgets/login/login_page_agreed_widget.dart';
import 'package:appframe/ui/widgets/login/login_page_header_widget.dart';
import 'package:appframe/ui/widgets/login/login_page_image_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class LoginPhonePage extends StatelessWidget {
const LoginPhonePage({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => LoginPhoneCubit(LoginPhoneState()),
child: BlocConsumer<LoginPhoneCubit, LoginPhoneState>(
builder: (context, state) {
var loginPhoneCubit = context.read<LoginPhoneCubit>();
return Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Colors.white,
body: SafeArea(
top: false,
child: SingleChildScrollView(
child: Column(children: [
LoginPageImageWidget(),
Transform.translate(
offset: Offset(0, -40), // 向上移动40像素
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
color: Colors.white, // 设置背景色
),
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 30),
LoginPageHeaderWidget(),
SizedBox(height: 25),
_buildInputFields(loginPhoneCubit, state),
SizedBox(height: 20),
_buildLoginButton(),
SizedBox(height: 30),
_buildWechatLogin(loginPhoneCubit),
SizedBox(height: 24.5),
_buildAgreement(context, loginPhoneCubit, state.agreed),
],
),
),
),
])),
),
);
},
listener: (context, state) {}),
);
}
Widget _buildInputFields(LoginPhoneCubit loginPhoneCubit, LoginPhoneState state) {
return Column(
children: [
// 手机号输入框
Container(
height: 60.5,
decoration: BoxDecoration(
color: Color(0xFFF7F9FF),
borderRadius: BorderRadius.vertical(top: Radius.circular(15)),
),
child: TextField(
controller: loginPhoneCubit.phoneController,
keyboardType: TextInputType.phone,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(11), // 使用这个来限制长度
FilteringTextInputFormatter.allow(RegExp(r'^1[0-9]{0,10}$')),
],
decoration: InputDecoration(
hintText: '请输入手机号',
hintStyle: TextStyle(
fontSize: 18,
color: Color(0xFFCCCCCC),
),
border: InputBorder.none,
contentPadding: EdgeInsets.fromLTRB(0, 26.5, 0, 15),
// 左右内边距,垂直居中
prefixIcon: Container(
width: 25.5,
height: 25.5,
margin: EdgeInsets.only(left: 15), // 控制左边距
child: Image.asset(
'assets/images/login/phone_blue_icon.png',
fit: BoxFit.contain,
),
),
),
style: TextStyle(
fontSize: 18,
color: Color(0xFF000000),
),
),
),
// 增加一条线段
Padding(
padding: EdgeInsets.symmetric(horizontal: 15),
child: Divider(
color: Color(0xFFE1E7FF),
height: 0.5,
thickness: 0.5,
),
),
// 验证码输入框和发送按钮
Row(
children: [
Expanded(
child: Container(
height: 60.5,
decoration: BoxDecoration(
color: Color(0xFFF7F9FF),
borderRadius: BorderRadius.vertical(bottom: Radius.circular(15)),
),
child: Stack(
children: [
TextField(
controller: loginPhoneCubit.codeController,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(6), // 使用这个来限制长度
],
decoration: InputDecoration(
hintText: '请输入验证码',
hintStyle: TextStyle(
fontSize: 18,
color: Color(0xFFCCCCCC),
),
border: InputBorder.none,
contentPadding: EdgeInsets.fromLTRB(0, 26.5, 0, 15),
// 左右内边距,垂直居中
prefixIcon: Container(
width: 25.5,
height: 25.5,
margin: EdgeInsets.only(left: 15), // 控制左边距
child: Image.asset(
'assets/images/login/security_blue_icon.png',
fit: BoxFit.contain,
),
),
),
style: TextStyle(
fontSize: 18,
color: Color(0xFF000000),
),
),
Positioned(
right: 0,
top: 0,
bottom: 0,
child: Container(
width: 100,
decoration: BoxDecoration(
color: Colors.transparent,
),
child: TextButton(
onPressed: () {
if (state.allowSend) {
loginPhoneCubit.sendVerificationCode();
}
},
style: TextButton.styleFrom(
backgroundColor: Colors.transparent,
// foregroundColor: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.zero,
),
child: Text(
state.allowSend ? '发送验证码' : '${state.seconds}s后可重发',
style: TextStyle(
fontSize: 16,
color: Color(0xFF7691FA),
fontWeight: FontWeight.normal,
),
),
),
),
),
],
),
),
),
],
),
],
);
}
Widget _buildLoginButton() {
return SizedBox(
width: double.infinity,
height: 47,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF7691FA),
foregroundColor: Colors.white,
textStyle: TextStyle(fontSize: 19),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(23.5),
),
),
child: Text('手机号登录'),
),
);
}
Widget _buildWechatLogin(LoginPhoneCubit loginPhoneCubit) {
return SizedBox(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
loginPhoneCubit.goLoginMain();
},
child: Column(
children: [
Image.asset('assets/images/login/wechat.png'),
SizedBox(height: 4),
Text(
'微信登录',
style: TextStyle(
fontSize: 14,
color: Color(0xFF000000),
),
),
],
),
),
],
),
);
}
Widget _buildAgreement(BuildContext context, LoginPhoneCubit loginPhoneCubit, bool agreed) {
return Padding(
padding: const EdgeInsets.only(bottom: 32.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Theme(
data: Theme.of(context).copyWith(
checkboxTheme: CheckboxThemeData(
shape: CircleBorder(
side: BorderSide(width: 0.5, color: Color(0xFF999999)),
),
fillColor: WidgetStateProperty.resolveWith<Color>(
(Set<WidgetState> states) {
if (states.contains(WidgetState.selected)) {
return Color(0xFF7691FA); // 选中时的颜色
}
return Colors.white; // 未选中时的颜色
},
),
checkColor: WidgetStateProperty.all<Color>(Colors.white),
side: BorderSide(width: 0.5, color: Color(0xFF999999)),
),
cardColor: Colors.white,
unselectedWidgetColor: Color(0xFF999999),
),
child: Checkbox(
value: agreed,
onChanged: (bool? value) {
loginPhoneCubit.toggleAgreed(value!);
},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, // 缩小点击区域,减小间隔
),
),
LoginPageAgreedWidget(),
],
),
);
}
}
import 'package:appframe/bloc/mqtt_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class MqttPage extends StatelessWidget {
const MqttPage({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => MqttCubit(),
child: BlocConsumer<MqttCubit, MqttState>(
builder: (context, state) {
return Scaffold(
appBar: AppBar(
title: Text('推送测试'),
centerTitle: true,
automaticallyImplyLeading: false,
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
context.read<MqttCubit>().goWeb();
},
),
),
body: ListView(
children: state.messages
.map((message) => ListTile(
title: Text(message),
))
.toList(),
));
},
listener: (context, state) {},
));
}
}
......@@ -62,24 +62,112 @@ class WebPage extends StatelessWidget {
},
)
: null,
actions: [
Builder(
builder: (BuildContext context) {
return IconButton(
icon: const Icon(Icons.more_vert),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return SizedBox(
height: 300,
child: Column(
children: [
// actions: [
// Builder(
// builder: (BuildContext context) {
// return IconButton(
// icon: const Icon(Icons.more_vert),
// onPressed: () {
// showModalBottomSheet(
// context: context,
// builder: (BuildContext context) {
// return SizedBox(
// height: 300,
// child: Column(
// children: [
// ListTile(
// leading: const Icon(Icons.chat_outlined),
// title: const Text('微信授权'),
// onTap: () {
// Navigator.pop(context);
// ctx.read<WebCubit>().goWechatAuth();
// },
// ),
// ListTile(
// leading: const Icon(Icons.accessibility_new),
// title: const Text('身份认证'),
// onTap: () {
// Navigator.pop(context);
// ctx.read<WebCubit>().goAuth();
// },
// ),
// ListTile(
// leading: const Icon(Icons.app_blocking_sharp),
// title: const Text('打开小程序'),
// onTap: () {
// Navigator.pop(context);
// ctx.read<WebCubit>().goMiniProgram();
// },
// ),
// ListTile(
// leading: const Icon(Icons.refresh),
// title: const Text('刷新'),
// onTap: () {
// Navigator.pop(context);
// ctx.read<WebCubit>().refresh();
// },
// ),
// ListTile(
// leading: const Icon(Icons.cleaning_services),
// title: const Text('清理缓存'),
// onTap: () {
// Navigator.pop(context);
// ctx.read<WebCubit>().clearStorage();
// },
// ),
// ],
// ),
// );
// },
// );
// },
// );
// },
// ),
// ],
),
endDrawer: Drawer(
width: MediaQuery.of(ctx).size.width * 0.8,
child: ListView(padding: EdgeInsets.zero, children: [
// DrawerHeader(
// decoration: BoxDecoration(
// color: Theme.of(ctx).colorScheme.primary,
// ),
// child: Text('设置',
// style: TextStyle(
// color: Theme.of(ctx).colorScheme.onPrimary,
// fontSize: 24,
// ))),
ListTile(
tileColor: Color(0xFF7691FA),
title: Text('设置',
style: TextStyle(
color: Theme.of(ctx).colorScheme.onPrimary,
fontSize: 24,
)
),
),
ListTile(
leading: const Icon(Icons.chat_bubble_outline),
title: const Text('推送测试'),
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goMqtt();
},
),
ListTile(
leading: const Icon(Icons.login),
title: const Text('登录界面'),
onTap: () {
Navigator.pop(ctx);
ctx.read<WebCubit>().goLogin();
},
),
ListTile(
leading: const Icon(Icons.chat_outlined),
title: const Text('微信授权'),
onTap: () {
Navigator.pop(context);
Navigator.pop(ctx);
ctx.read<WebCubit>().goWechatAuth();
},
),
......@@ -87,7 +175,7 @@ class WebPage extends StatelessWidget {
leading: const Icon(Icons.accessibility_new),
title: const Text('身份认证'),
onTap: () {
Navigator.pop(context);
Navigator.pop(ctx);
ctx.read<WebCubit>().goAuth();
},
),
......@@ -95,7 +183,7 @@ class WebPage extends StatelessWidget {
leading: const Icon(Icons.app_blocking_sharp),
title: const Text('打开小程序'),
onTap: () {
Navigator.pop(context);
Navigator.pop(ctx);
ctx.read<WebCubit>().goMiniProgram();
},
),
......@@ -103,7 +191,7 @@ class WebPage extends StatelessWidget {
leading: const Icon(Icons.refresh),
title: const Text('刷新'),
onTap: () {
Navigator.pop(context);
Navigator.pop(ctx);
ctx.read<WebCubit>().refresh();
},
),
......@@ -111,21 +199,11 @@ class WebPage extends StatelessWidget {
leading: const Icon(Icons.cleaning_services),
title: const Text('清理缓存'),
onTap: () {
Navigator.pop(context);
Navigator.pop(ctx);
ctx.read<WebCubit>().clearStorage();
},
),
],
),
);
},
);
},
);
},
),
],
),
])),
body: state.loaded
? SizedBox(
height: MediaQuery.of(ctx).size.height - 120, // 减去100像素留空
......@@ -150,3 +228,19 @@ class WebPage extends StatelessWidget {
);
}
}
class LoginMainState {
final bool loaded;
final bool orientationCmdFlag;
final bool windowInfoCmdFlag;
final bool chooseImageCmdFlag;
final bool chooseVideoCmdFlag;
LoginMainState({
required this.loaded,
required this.orientationCmdFlag,
required this.windowInfoCmdFlag,
required this.chooseImageCmdFlag,
required this.chooseVideoCmdFlag,
});
}
import 'package:flutter/material.dart';
class LoginPageAgreedWidget extends StatelessWidget {
const LoginPageAgreedWidget({super.key});
@override
Widget build(BuildContext context) {
return Text.rich(
TextSpan(
children: [
TextSpan(
text: '同意',
style: TextStyle(color: Color(0xFF999999), fontSize: 14),
),
TextSpan(
text: '《隐私保障》',
style: TextStyle(color: Color(0xFF7691FA), fontSize: 14),
),
TextSpan(
text: '和',
style: TextStyle(color: Color(0xFF999999), fontSize: 14),
),
TextSpan(
text: '《用户协议》',
style: TextStyle(color: Color(0xFF7691FA), fontSize: 14),
),
],
),
);
}
}
import 'package:flutter/material.dart';
class LoginPageHeaderWidget extends StatelessWidget {
const LoginPageHeaderWidget({super.key});
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'欢迎登录',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Color(0xFF000000),
),
),
SizedBox(height: 6),
Text(
'班小二,班级群必备效率工具',
style: TextStyle(
fontSize: 14,
color: Color(0xFF000000),
),
),
],
);
}
}
import 'package:flutter/material.dart';
class LoginPageImageWidget extends StatelessWidget {
const LoginPageImageWidget({super.key});
@override
Widget build(BuildContext context) {
return Image.asset(
'assets/images/login/login_bg.png',
width: double.infinity,
fit: BoxFit.cover,
);
}
}
......@@ -6,10 +6,18 @@
#include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h>
#include <flutter_localization/flutter_localization_plugin.h>
#include <open_file_linux/open_file_linux_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
g_autoptr(FlPluginRegistrar) flutter_localization_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterLocalizationPlugin");
flutter_localization_plugin_register_with_registrar(flutter_localization_registrar);
g_autoptr(FlPluginRegistrar) open_file_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "OpenFileLinuxPlugin");
open_file_linux_plugin_register_with_registrar(open_file_linux_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
}
......@@ -3,7 +3,9 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
flutter_localization
open_file_linux
url_launcher_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
......
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
MACOSX_DEPLOYMENT_TARGET = 10.15
\ No newline at end of file
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
MACOSX_DEPLOYMENT_TARGET = 10.15
\ No newline at end of file
......@@ -7,30 +7,42 @@ import Foundation
import connectivity_plus
import device_info_plus
import ffmpeg_kit_flutter_new_audio
import file_picker
import file_selector_macos
import flutter_image_compress_macos
import flutter_localization
import geolocator_apple
import mobile_scanner
import network_info_plus
import open_file_mac
import package_info_plus
import path_provider_foundation
import photo_manager
import shared_preferences_foundation
import sqflite_darwin
import url_launcher_macos
import video_compress
import video_player_avfoundation
import webview_flutter_wkwebview
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FFmpegKitFlutterPlugin.register(with: registry.registrar(forPlugin: "FFmpegKitFlutterPlugin"))
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FlutterImageCompressMacosPlugin.register(with: registry.registrar(forPlugin: "FlutterImageCompressMacosPlugin"))
FlutterLocalizationPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalizationPlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
NetworkInfoPlusPlugin.register(with: registry.registrar(forPlugin: "NetworkInfoPlusPlugin"))
OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
PhotoManagerPlugin.register(with: registry.registrar(forPlugin: "PhotoManagerPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
VideoCompressPlugin.register(with: registry.registrar(forPlugin: "VideoCompressPlugin"))
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin"))
}
platform :osx, '10.14'
platform :osx, '10.15'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
......
PODS:
- connectivity_plus (0.0.1):
- FlutterMacOS
- device_info_plus (0.0.1):
- FlutterMacOS
- file_selector_macos (0.0.1):
- ffmpeg_kit_flutter_new_audio (7.1.1):
- ffmpeg_kit_flutter_new_audio/audio (= 7.1.1)
- FlutterMacOS
- ffmpeg_kit_flutter_new_audio/audio (7.1.1):
- FlutterMacOS
- file_picker (0.0.1):
- FlutterMacOS
- flutter_image_compress_macos (1.0.0):
- FlutterMacOS
- flutter_localization (0.0.1):
- FlutterMacOS
- FlutterMacOS (1.0.0)
- geolocator_apple (1.2.0):
- Flutter
- FlutterMacOS
- mobile_scanner (7.0.0):
- Flutter
- FlutterMacOS
- network_info_plus (0.0.1):
- FlutterMacOS
- open_file_mac (0.0.1):
- FlutterMacOS
- package_info_plus (0.0.1):
- FlutterMacOS
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- photo_manager (3.7.1):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
- url_launcher_macos (0.0.1):
- FlutterMacOS
- video_compress (0.3.0):
- FlutterMacOS
- video_player_avfoundation (0.0.1):
- Flutter
- FlutterMacOS
- webview_flutter_wkwebview (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`)
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
- file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`)
- ffmpeg_kit_flutter_new_audio (from `Flutter/ephemeral/.symlinks/plugins/ffmpeg_kit_flutter_new_audio/macos`)
- file_picker (from `Flutter/ephemeral/.symlinks/plugins/file_picker/macos`)
- flutter_image_compress_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_image_compress_macos/macos`)
- flutter_localization (from `Flutter/ephemeral/.symlinks/plugins/flutter_localization/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- geolocator_apple (from `Flutter/ephemeral/.symlinks/plugins/geolocator_apple/darwin`)
- mobile_scanner (from `Flutter/ephemeral/.symlinks/plugins/mobile_scanner/darwin`)
- network_info_plus (from `Flutter/ephemeral/.symlinks/plugins/network_info_plus/macos`)
- open_file_mac (from `Flutter/ephemeral/.symlinks/plugins/open_file_mac/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- photo_manager (from `Flutter/ephemeral/.symlinks/plugins/photo_manager/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- video_compress (from `Flutter/ephemeral/.symlinks/plugins/video_compress/macos`)
- video_player_avfoundation (from `Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin`)
- webview_flutter_wkwebview (from `Flutter/ephemeral/.symlinks/plugins/webview_flutter_wkwebview/darwin`)
EXTERNAL SOURCES:
connectivity_plus:
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos
device_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
file_selector_macos:
:path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos
ffmpeg_kit_flutter_new_audio:
:path: Flutter/ephemeral/.symlinks/plugins/ffmpeg_kit_flutter_new_audio/macos
file_picker:
:path: Flutter/ephemeral/.symlinks/plugins/file_picker/macos
flutter_image_compress_macos:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_image_compress_macos/macos
flutter_localization:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_localization/macos
FlutterMacOS:
:path: Flutter/ephemeral
geolocator_apple:
:path: Flutter/ephemeral/.symlinks/plugins/geolocator_apple/darwin
mobile_scanner:
:path: Flutter/ephemeral/.symlinks/plugins/mobile_scanner/darwin
network_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/network_info_plus/macos
open_file_mac:
:path: Flutter/ephemeral/.symlinks/plugins/open_file_mac/macos
package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
photo_manager:
:path: Flutter/ephemeral/.symlinks/plugins/photo_manager/macos
shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sqflite_darwin:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin
url_launcher_macos:
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
video_compress:
:path: Flutter/ephemeral/.symlinks/plugins/video_compress/macos
video_player_avfoundation:
:path: Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin
webview_flutter_wkwebview:
:path: Flutter/ephemeral/.symlinks/plugins/webview_flutter_wkwebview/darwin
SPEC CHECKSUMS:
connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31
ffmpeg_kit_flutter_new_audio: d3c98512bcf22c530b56262ac7969a62f3dd60b6
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
flutter_image_compress_macos: e68daf54bb4bf2144c580fd4d151c949cbf492f0
flutter_localization: 3cda759884c7dab4466fe963d97fba723a492666
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93
network_info_plus: 21d1cd6a015ccb2fdff06a1fbfa88d54b4e92f61
open_file_mac: 01874b6d6a2c1485ac9b126d7105b99102dea2cf
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
photo_manager: 1d80ae07a89a67dfbcae95953a1e5a24af7c3e62
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673
video_compress: 752b161da855df2492dd1a8fa899743cc8fe9534
video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2
PODFILE CHECKSUM: 7eb978b976557c8c1cd717d8185ec483fd090a82
PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009
COCOAPODS: 1.16.2
......@@ -27,8 +27,8 @@
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
6997563B52F46519AEAB5CFA /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3BFD66D2EAD5FCD6A87DCDA /* Pods_Runner.framework */; };
AD771D69EBB54A2CBA8ABB2B /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A0226ECE76A80D281E3F385F /* Pods_RunnerTests.framework */; };
796AC6673A2E942C22E85D19 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDAA0EEF811E5E44053F7102 /* Pods_RunnerTests.framework */; };
AC5AE5D074CB873F577D77AD /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 80252AF49583AA2C7B2F703F /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -62,7 +62,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
172BA3B285E2E3FD2494EB61 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
153A322A5B6C64403603B765 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
203DDC70A14256E6734420EB /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
......@@ -80,14 +81,13 @@
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
80DE52E985F33B7E3563A1A4 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
86C1021CFD1F3D1A7EF4DACE /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
80252AF49583AA2C7B2F703F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
A0226ECE76A80D281E3F385F /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
AC4A242C41A3CDF14FFA10D8 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
B3BFD66D2EAD5FCD6A87DCDA /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DA4B5B74F631DF144A91E046 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
E1E0E426A68DE64F35D3EE26 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
A1DC5417A59135215F442691 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
BFAD86B9A0E42D9908409BC4 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
CE0096A29AE96A8F790D7F91 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
FBBF47F7C5A2721EE1D0B029 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
FDAA0EEF811E5E44053F7102 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -95,7 +95,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
AD771D69EBB54A2CBA8ABB2B /* Pods_RunnerTests.framework in Frameworks */,
796AC6673A2E942C22E85D19 /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -103,13 +103,22 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6997563B52F46519AEAB5CFA /* Pods_Runner.framework in Frameworks */,
AC5AE5D074CB873F577D77AD /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1012743B96799D7D711936E1 /* Frameworks */ = {
isa = PBXGroup;
children = (
80252AF49583AA2C7B2F703F /* Pods_Runner.framework */,
FDAA0EEF811E5E44053F7102 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
331C80D6294CF71000263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
......@@ -136,8 +145,8 @@
33CEB47122A05771004F2AC0 /* Flutter */,
331C80D6294CF71000263BE5 /* RunnerTests */,
33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */,
C3BB809B72512AFD98B2DC8A /* Pods */,
67C9ADAA11563A5F98163F75 /* Pods */,
1012743B96799D7D711936E1 /* Frameworks */,
);
sourceTree = "<group>";
};
......@@ -185,27 +194,17 @@
path = Runner;
sourceTree = "<group>";
};
C3BB809B72512AFD98B2DC8A /* Pods */ = {
67C9ADAA11563A5F98163F75 /* Pods */ = {
isa = PBXGroup;
children = (
E1E0E426A68DE64F35D3EE26 /* Pods-Runner.debug.xcconfig */,
86C1021CFD1F3D1A7EF4DACE /* Pods-Runner.release.xcconfig */,
80DE52E985F33B7E3563A1A4 /* Pods-Runner.profile.xcconfig */,
DA4B5B74F631DF144A91E046 /* Pods-RunnerTests.debug.xcconfig */,
172BA3B285E2E3FD2494EB61 /* Pods-RunnerTests.release.xcconfig */,
AC4A242C41A3CDF14FFA10D8 /* Pods-RunnerTests.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
isa = PBXGroup;
children = (
B3BFD66D2EAD5FCD6A87DCDA /* Pods_Runner.framework */,
A0226ECE76A80D281E3F385F /* Pods_RunnerTests.framework */,
203DDC70A14256E6734420EB /* Pods-Runner.debug.xcconfig */,
FBBF47F7C5A2721EE1D0B029 /* Pods-Runner.release.xcconfig */,
153A322A5B6C64403603B765 /* Pods-Runner.profile.xcconfig */,
BFAD86B9A0E42D9908409BC4 /* Pods-RunnerTests.debug.xcconfig */,
CE0096A29AE96A8F790D7F91 /* Pods-RunnerTests.release.xcconfig */,
A1DC5417A59135215F442691 /* Pods-RunnerTests.profile.xcconfig */,
);
name = Frameworks;
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
......@@ -215,7 +214,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
E97F030859904F4BD40B2F65 /* [CP] Check Pods Manifest.lock */,
06DD16C3491F404579011AFE /* [CP] Check Pods Manifest.lock */,
331C80D1294CF70F00263BE5 /* Sources */,
331C80D2294CF70F00263BE5 /* Frameworks */,
331C80D3294CF70F00263BE5 /* Resources */,
......@@ -234,13 +233,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
00D96A2625AF897C8D9E8E15 /* [CP] Check Pods Manifest.lock */,
A5106AB8ABF9ABA03E9DE684 /* [CP] Check Pods Manifest.lock */,
33CC10E92044A3C60003C045 /* Sources */,
33CC10EA2044A3C60003C045 /* Frameworks */,
33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
0B09314984AD1F7E65F8CC32 /* [CP] Embed Pods Frameworks */,
6F8312B3959709DCE5C4E576 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
......@@ -323,7 +322,7 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
00D96A2625AF897C8D9E8E15 /* [CP] Check Pods Manifest.lock */ = {
06DD16C3491F404579011AFE /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
......@@ -338,30 +337,13 @@
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
0B09314984AD1F7E65F8CC32 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
......@@ -400,7 +382,24 @@
shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
};
E97F030859904F4BD40B2F65 /* [CP] Check Pods Manifest.lock */ = {
6F8312B3959709DCE5C4E576 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
A5106AB8ABF9ABA03E9DE684 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
......@@ -415,7 +414,7 @@
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
......@@ -473,11 +472,12 @@
/* Begin XCBuildConfiguration section */
331C80DB294CF71000263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = DA4B5B74F631DF144A91E046 /* Pods-RunnerTests.debug.xcconfig */;
baseConfigurationReference = BFAD86B9A0E42D9908409BC4 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = cn.banxe.appframe.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
......@@ -488,11 +488,12 @@
};
331C80DC294CF71000263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 172BA3B285E2E3FD2494EB61 /* Pods-RunnerTests.release.xcconfig */;
baseConfigurationReference = CE0096A29AE96A8F790D7F91 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = cn.banxe.appframe.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
......@@ -503,11 +504,12 @@
};
331C80DD294CF71000263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AC4A242C41A3CDF14FFA10D8 /* Pods-RunnerTests.profile.xcconfig */;
baseConfigurationReference = A1DC5417A59135215F442691 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = cn.banxe.appframe.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
......@@ -579,6 +581,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.5;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
......@@ -711,6 +714,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.5;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
......@@ -731,6 +735,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.5;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
......
{"guid":"dc4b70c03e8043e50e38f2068887b1d4","name":"Pods","path":"/Users/ethanlam/works/gitlab/flutter_pros/appframe.git/ios/Pods/Pods.xcodeproj/project.xcworkspace","projects":["PROJECT@v11_mod=4d9e48e39f50d70bfc7a740417998f87_hash=bfdfe7dc352907fc980b868725387e98plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1"]}
\ No newline at end of file
......@@ -45,10 +45,10 @@ packages:
dependency: transitive
description:
name: bloc
sha256: "52c10575f4445c61dd9e0cafcc6356fdd827c4c64dd7945ef3c4105f6b6ac189"
sha256: a2cebb899f91d36eeeaa55c7b20b5915db5a9df1b8fd4a3c9c825e22e474537d
url: "https://pub.flutter-io.cn"
source: hosted
version: "9.0.0"
version: "9.1.0"
boolean_selector:
dependency: transitive
description:
......@@ -61,10 +61,10 @@ packages:
dependency: transitive
description:
name: build
sha256: "5b887c55a0f734b433b3b2d89f9cd1f99eb636b17e268a5b4259258bc916504b"
sha256: dfb67ccc9a78c642193e0c2d94cb9e48c2c818b3178a86097d644acdcde6a8d9
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.0"
version: "4.0.2"
build_config:
dependency: transitive
description:
......@@ -85,10 +85,10 @@ packages:
dependency: "direct dev"
description:
name: build_runner
sha256: "804c47c936df75e1911c19a4fb8c46fa8ff2b3099b9f2b2aa4726af3774f734b"
sha256: "4e54dbeefdc70691ba80b3bce3976af63b5425c8c07dface348dfee664a0edc1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.8.0"
version: "2.9.0"
built_collection:
dependency: transitive
description:
......@@ -117,18 +117,18 @@ packages:
dependency: transitive
description:
name: camera_android
sha256: "6402a654ab42104c49bd40c1feb9e6d7be8b19d18affb7b8c2e843b10040de05"
sha256: "4db8a27da163130d913ab4360297549ead1c7f9a6a88e71c44e5f4d10081a3d4"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.10.10+9"
version: "0.10.10+6"
camera_avfoundation:
dependency: transitive
description:
name: camera_avfoundation
sha256: "397f44f8a63c8c0a474668d500f9739d4f2bc45ac2b21801194b7d29260f03ee"
sha256: "951ef122d01ebba68b7a54bfe294e8b25585635a90465c311b2f875ae72c412f"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.9.22+1"
version: "0.9.21+2"
camera_platform_interface:
dependency: transitive
description:
......@@ -173,10 +173,10 @@ packages:
dependency: transitive
description:
name: code_builder
sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243"
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.10.1"
version: "4.11.0"
collection:
dependency: transitive
description:
......@@ -297,6 +297,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.7"
event_bus:
dependency: transitive
description:
name: event_bus
sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.1"
exif:
dependency: "direct main"
description:
......@@ -442,10 +450,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.0.0"
version: "6.0.0"
flutter_localization:
dependency: "direct main"
description:
......@@ -455,7 +463,7 @@ packages:
source: hosted
version: "0.3.3"
flutter_localizations:
dependency: transitive
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
......@@ -463,10 +471,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31
sha256: c2fe1001710127dfa7da89977a08d591398370d099aacdaa6d44da7eb14b8476
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.30"
version: "2.0.31"
flutter_sound:
dependency: "direct main"
description:
......@@ -509,14 +517,6 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.7.2"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.0"
gallery_saver_plus:
dependency: "direct main"
description:
......@@ -609,10 +609,10 @@ packages:
dependency: "direct main"
description:
name: go_router
sha256: eb059dfe59f08546e9787f895bd01652076f996bcbf485a8609ef990419ad227
sha256: e1d7ffb0db475e6e845eb58b44768f50b830e23960e3df6908924acd8f7f70ea
url: "https://pub.flutter-io.cn"
source: hosted
version: "16.2.1"
version: "16.2.5"
graphs:
dependency: transitive
description:
......@@ -737,42 +737,42 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
url: "https://pub.flutter-io.cn"
source: hosted
version: "11.0.1"
version: "10.0.9"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.10"
version: "3.0.9"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.2"
version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.1.1"
version: "6.0.0"
logger:
dependency: transitive
description:
name: logger
sha256: "55d6c23a6c15db14920e037fe7e0dc32e7cdaf3b64b4b25df2d541b5b6b81c0c"
sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.6.1"
version: "2.6.2"
logging:
dependency: transitive
description:
......@@ -817,10 +817,18 @@ packages:
dependency: "direct main"
description:
name: mobile_scanner
sha256: "54005bdea7052d792d35b4fef0f84ec5ddc3a844b250ecd48dc192fb9b4ebc95"
sha256: "5e7e09d904dc01de071b79b3f3789b302b0ed3c9c963109cd3f83ad90de62ecf"
url: "https://pub.flutter-io.cn"
source: hosted
version: "7.0.1"
version: "7.1.2"
mqtt_client:
dependency: "direct main"
description:
name: mqtt_client
sha256: "3b3f406bf804df7de909f2c5098fba1a7d87fc4d86f01b6a12dc8d1b24be221f"
url: "https://pub.flutter-io.cn"
source: hosted
version: "10.11.1"
nested:
dependency: transitive
description:
......@@ -961,10 +969,10 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
sha256: "3b4c1fc3aa55ddc9cd4aa6759984330d5c8e66aa7702a6223c61540dc6380c37"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.18"
version: "2.2.19"
path_provider_foundation:
dependency: transitive
description:
......@@ -1089,10 +1097,10 @@ packages:
dependency: transitive
description:
name: pool
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.5.1"
version: "1.5.2"
posix:
dependency: transitive
description:
......@@ -1153,10 +1161,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_android
sha256: a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74
sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.12"
version: "2.4.13"
shared_preferences_foundation:
dependency: transitive
description:
......@@ -1222,10 +1230,10 @@ packages:
dependency: transitive
description:
name: source_gen
sha256: ccf30b0c9fbcd79d8b6f5bfac23199fb354938436f62475e14aea0f29ee0f800
sha256: "9098ab86015c4f1d8af6486b547b11100e73b193e1899015033cb3e14ad20243"
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.1"
version: "4.0.2"
source_helper:
dependency: transitive
description:
......@@ -1250,6 +1258,46 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "7.0.0"
sqflite:
dependency: "direct main"
description:
name: sqflite
sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.2"
sqflite_android:
dependency: transitive
description:
name: sqflite_android
sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.1"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.5.6"
sqflite_darwin:
dependency: transitive
description:
name: sqflite_darwin
sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.2"
sqflite_platform_interface:
dependency: transitive
description:
name: sqflite_platform_interface
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.0"
stack_trace:
dependency: transitive
description:
......@@ -1302,10 +1350,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.7.6"
version: "0.7.4"
typed_data:
dependency: transitive
description:
......@@ -1334,10 +1382,10 @@ packages:
dependency: transitive
description:
name: url_launcher_android
sha256: "5c8b6c2d89a78f5a1cca70a73d9d5f86c701b36b42f9c9dac7bad592113c28e9"
sha256: "81777b08c498a292d93ff2feead633174c386291e35612f8da438d6e92c4447e"
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.3.24"
version: "6.3.20"
url_launcher_ios:
dependency: transitive
description:
......@@ -1398,10 +1446,10 @@ packages:
dependency: transitive
description:
name: vector_math
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.0"
version: "2.1.4"
vibration:
dependency: "direct main"
description:
......@@ -1478,18 +1526,18 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
url: "https://pub.flutter-io.cn"
source: hosted
version: "15.0.2"
version: "15.0.0"
watcher:
dependency: transitive
description:
name: watcher
sha256: "5bf046f41320ac97a469d506261797f35254fa61c641741ef32dacda98b7d39c"
sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.3"
version: "1.1.4"
web:
dependency: transitive
description:
......@@ -1574,10 +1622,10 @@ packages:
dependency: transitive
description:
name: win32
sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03"
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.14.0"
version: "5.15.0"
win32_registry:
dependency: transitive
description:
......@@ -1611,5 +1659,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.9.0 <4.0.0"
flutter: ">=3.35.0"
dart: ">=3.8.0 <4.0.0"
flutter: ">=3.29.0"
......@@ -19,7 +19,14 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ^3.9.0
sdk: ">=3.5.0 <4.0.0"
fluwx:
app_id: wx8c32ea248f0c7765
debug_logging: true # Logging in debug mode.
ios:
universal_link: https://dev.banxiaoer.net/path/to/wechat/
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
......@@ -30,6 +37,8 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_localizations: # 确保存在这一行
sdk: flutter
archive: ^4.0.7
connectivity_plus: ^7.0.0
device_info_plus: ^11.5.0
......@@ -53,12 +62,15 @@ dependencies:
json_annotation: ^4.9.0
mime: ^2.0.0
mobile_scanner: ^7.0.1
mqtt_client: ^10.11.1
network_info_plus: ^7.0.0
open_file: ^3.5.10
path: ^1.9.1
path_provider: ^2.1.5
permission_handler: ^12.0.1
shared_preferences: ^2.5.3
sqflite: ^2.4.2
# video_thumbnail: ^0.5.6
url_launcher: ^6.3.2
uuid: ^4.5.1
vibration: ^3.1.3
......@@ -83,7 +95,7 @@ dev_dependencies:
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^5.0.0
flutter_lints: ^6.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
......@@ -103,6 +115,7 @@ flutter:
assets:
- assets/
- assets/dist.zip
- assets/images/login/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/to/resolution-aware-images
......
cd /Users/ethanlam/works/gitlab/flutter_pros/xehybrid/dist
zip -r dist.zip ./* -x ".*" -x "*/.*"
cp -f /Users/ethanlam/works/gitlab/flutter_pros/xehybrid/dist/dist.zip /Users/ethanlam/works/gitlab/flutter_pros/appframe.git/assets
......@@ -7,17 +7,20 @@
#include "generated_plugin_registrant.h"
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
#include <file_selector_windows/file_selector_windows.h>
#include <flutter_localization/flutter_localization_plugin_c_api.h>
#include <geolocator_windows/geolocator_windows.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
FlutterLocalizationPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterLocalizationPluginCApi"));
GeolocatorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("GeolocatorWindows"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}
......@@ -4,9 +4,10 @@
list(APPEND FLUTTER_PLUGIN_LIST
connectivity_plus
file_selector_windows
flutter_localization
geolocator_windows
permission_handler_windows
url_launcher_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!