初始化提交

This commit is contained in:
考拉
2025-09-12 20:35:12 +08:00
parent ca77daa68e
commit d657a81239
240 changed files with 19241 additions and 0 deletions

155
.gitignore vendored Normal file
View File

@@ -0,0 +1,155 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
.properties
.flutter-plugins
.flutter-plugins-dependencies
.packages
.lock
.bin
pubspec.look
local.properties
.packages
.flutter-plugins
.packages
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
build/
# pubspec.lock
# Android related
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
**/android/key.properties
*.jks
# 针对flutter当做module集成进现有项目时.android目录下的文件
**/.android/**/gradle-wrapper.jar
**/.android/.gradle
**/.android/captures/
**/.android/gradlew
**/.android/gradlew.bat
**/.android/local.properties
**/.android/**/GeneratedPluginRegistrant.java
**/.android/key.properties
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# **/ios/Podfile.lock
# 针对flutter当做module集成进现有项目时.ios目录下的文件
**/.ios/**/*.mode1v3
**/.ios/**/*.mode2v3
**/.ios/**/*.moved-aside
**/.ios/**/*.pbxuser
**/.ios/**/*.perspectivev3
**/.ios/**/*sync/
**/.ios/**/.sconsign.dblite
**/.ios/**/.tags*
**/.ios/**/.vagrant/
**/.ios/**/DerivedData/
**/.ios/**/Icon?
**/.ios/**/Pods/
**/.ios/**/.symlinks/
**/.ios/**/profile
**/.ios/**/xcuserdata
**/.ios/.generated/
**/.ios/Flutter/App.framework
**/.ios/Flutter/Flutter.framework
**/.ios/Flutter/Generated.xcconfig
**/.ios/Flutter/app.flx
**/.ios/Flutter/app.zip
**/.ios/Flutter/flutter_assets/
**/.ios/ServiceDefinitions.json
**/.ios/Runner/GeneratedPluginRegistrant.*
# macOS
**/macos/Flutter/GeneratedPluginRegistrant.swift
**/macos/Flutter/Flutter-Debug.xcconfig
**/macos/Flutter/Flutter-Release.xcconfig
**/macos/Flutter/Flutter-Profile.xcconfig
# Coverage
coverage/
# Symbols
app.*.symbols
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
!/dev/ci/**/Gemfile.lock
.packages~92442170bbeb67da2b4cc92142720c48c0d7f490

56
README.md Normal file
View File

@@ -0,0 +1,56 @@
# chat-flutter微聊
```
基于flutter的即时通讯app客户端支持iOS与Android双系统打包运行
```
## 安装部署
+ flutter版本
```
3.22.2
```
+ 拉取依赖包
```
flutter pub get
```
+ 运行项目
```
flutter run
```
+ 打包安卓
```
flutter build apk
```
+ 打包平果
```
flutter build ios
```
## 效果截图
<img src="screenshots/IMG_0070.PNG" width="200">
<img src="screenshots/IMG_0071.PNG" width="200">
<img src="screenshots/IMG_0072.PNG" width="200">
<img src="screenshots/IMG_0073.PNG" width="200">
<img src="screenshots/IMG_0076.PNG" width="200">
<img src="screenshots/IMG_0078.PNG" width="200">
<img src="screenshots/IMG_0079.PNG" width="200">
<img src="screenshots/IMG_0080.PNG" width="200">
<img src="screenshots/IMG_0081.PNG" width="200">
<img src="screenshots/IMG_0082.PNG" width="200">
<img src="screenshots/IMG_0083.PNG" width="200">
<img src="screenshots/IMG_0084.PNG" width="200">
<img src="screenshots/IMG_0085.PNG" width="200">
<img src="screenshots/IMG_0086.PNG" width="200">
<img src="screenshots/IMG_0087.PNG" width="200">
## 传送门
+ 您的支持,就是我们`【生发的动力】`,请手动点个`star`吧。
+ chat-flutter
[https://github.com/lakaola/chat-flutter](https://github.com/lakaola/chat-flutter)
[https://gitee.com/lakaola/chat-flutter](https://gitee.com/lakaola/chat-flutter)
+ chat-uniapp
[https://github.com/lakaola/chat-uniapp](https://github.com/lakaola/chat-uniapp)
[https://gitee.com/lakaola/chat-uniapp](https://gitee.com/lakaola/chat-uniapp)
+ chat-api
[https://github.com/lakaola/chat-api](https://github.com/lakaola/chat-api)
[https://gitee.com/lakaola/chat-api](https://gitee.com/lakaola/chat-api)
+ 加入QQ群[![加入QQ群](https://img.shields.io/badge/加入QQ群-535099683-blue.svg)](https://jq.qq.com/?_wv=1027&k=PQMnFugm) 详细文档进群获取535099683

28
analysis_options.yaml Normal file
View File

@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

13
android/.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks

117
android/app/build.gradle Normal file
View File

@@ -0,0 +1,117 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
android {
namespace "com.chat.demo"
buildToolsVersion = '34.0.0'
compileSdkVersion 34
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.chat.demo"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
manifestPlaceholders = [
appId: "appId"
]
multiDexEnabled true
}
signingConfigs {
release {
storeFile file('app.jks')
storePassword 'qwertyui'
keyAlias 'app'
keyPassword 'qwertyui'
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
// 混淆
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro", "proguard.cfg"
// 平台
// arm64-v8a(表示第8代64位ARM处理器)
// armeabi-v7a(表示第7代及以上32位ARM处理器)
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
debug {
manifestPlaceholders = [applicationName: "android.app.Application"]
}
build {
manifestPlaceholders = [applicationName: "android.app.Application"]
}
}
// 此处配置必须添加 否则无法正确运行
aaptOptions {
additionalParameters '--auto-add-overlay'
// noCompress 'foo', 'bar'
ignoreAssetsPattern "!.svn:!.git:.*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~"
}
}
flutter {
source '../..'
}
// 导入 arr 需要的配置
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation 'androidx.multidex:multidex:2.0.1'
// 必须添加的依赖
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.alibaba:fastjson:1.2.83'
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation 'com.facebook.fresco:animated-gif:1.13.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'androidx.webkit:webkit:1.3.0'
}

Binary file not shown.

Binary file not shown.

3
android/app/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,3 @@
-keep class androidx.lifecycle.DefaultLifecycleObserver
-keep class com.pauldemarco.flutter_blue.** { *; }
-keep class com.mr.flutter.plugin.filepicker.** { *; }

302
android/app/proguard.cfg Normal file
View File

@@ -0,0 +1,302 @@
-dontwarn
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-dontoptimize
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends io.dcloud.common.DHInterface.IPlugin
-keep public class * extends io.dcloud.common.DHInterface.IFeature
-keep public class * extends io.dcloud.common.DHInterface.IBoot
-keep public class * extends io.dcloud.common.DHInterface.IReflectAble
-keep class io.dcloud.** {*;}
-dontwarn io.dcloud.**
-keep class vi.com.gdi.** {*;}
-keep class android.support.v4.** {*;}
-keepclasseswithmembers class io.dcloud.appstream.StreamAppManager {
public protected <methods>;
}
-keep public class * extends io.dcloud.common.DHInterface.IReflectAble{
public protected <methods>;
public protected *;
}
-keep class **.R
-keep class **.R$* {
public static <fields>;
}
-keep public class * extends io.dcloud.common.DHInterface.IJsInterface{
public protected <methods>;
public protected *;
}
-keepclasseswithmembers class io.dcloud.EntryProxy {
<methods>;
}
-keep class * implements android.os.IInterface {
<methods>;
}
-keepclasseswithmembers class *{
public static java.lang.String getJsContent();
}
-keepclasseswithmembers class *{
public static io.dcloud.share.AbsWebviewClient getWebviewClient(io.dcloud.share.ShareAuthorizeView);
}
-keepattributes Exceptions,InnerClasses,Signature,Deprecated, SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keep public class * extends android.app.Application{
public static <methods>;
public *;
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
public static <methods>;
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keep class dc.** {*;}
-keep class okio.**{*;}
-keep class org.apache.** {*;}
-keep class org.json.** {*;}
-keep class net.ossrs.** {*;}
-keep class android.** {*;}
-keep class com.facebook.**{*;}
-keep class com.bumptech.glide.**{*;}
-keep class com.alibaba.fastjson.**{*;}
-keep class com.sina.**{*;}
-keep class com.weibo.ssosdk.**{*;}
-keep class com.asus.**{*;}
-keep class com.bun.**{*;}
-keep class com.heytap.**{*;}
-keep class com.huawei.**{*;}
-keep class com.netease.**{*;}
-keep class com.meizu.**{*;}
-keep class com.samsung.**{*;}
-keep class com.zui.**{*;}
-keep class com.amap.**{*;}
-keep class com.autonavi.**{*;}
-keep class pl.droidsonroids.gif.**{*;}
-keep class com.tencent.**{*;}
-keep class com.baidu.**{*;}
-keep class com.iflytek.**{*;}
-keep class com.umeng.**{*;}
-keep class tv.**{*;}
-keep class master.**{*;}
-keep class uk.co.**{*;}
-keep class com.dmcbig.**{*;}
-keep class org.mozilla.**{*;}
-keep class androidtranscoder.**{*;}
-keep class XI.**{*;}
-dontwarn android.**
-dontwarn com.tencent.**
-keep class * implements com.taobao.weex.IWXObject{*;}
-keep public class * extends com.taobao.weex.common.WXModule{*;}
-keepattributes Signature
-dontwarn org.codehaus.mojo.**
-dontwarn org.apache.commons.**
-dontwarn com.amap.**
-dontwarn com.sina.weibo.sdk.**
-dontwarn com.alipay.**
-dontwarn com.lucan.ajtools.**
-dontwarn pl.droidsonroids.gif.**
-keep class com.taobao.weex.** { *; }
-keep class com.taobao.gcanvas.**{*;}
-dontwarn com.taobao.weex.**
-dontwarn com.taobao.gcanvas.**
#个推
-dontwarn com.igexin.**
-keep class com.igexin.** { *; }
-keep class org.json.** { *; }
-dontwarn com.getui.**
-keep class com.getui.** { *; }
-keep class android.support.v4.app.NotificationCompat { *; }
-keep class android.support.v4.app.NotificationCompat$Builder { *; }
#魅族
-keep class com.meizu.** { *; }
-dontwarn com.meizu.**
#小米
-keep class com.xiaomi.** { *; }
-dontwarn com.xiaomi.push.**
-keep class org.apache.thrift.** { *; }
#华为
-dontwarn com.huawei.hms.**
-keep class com.huawei.hms.** { *; }
-keep class com.huawei.android.** { *; }
-dontwarn com.huawei.android.**
-keep class com.hianalytics.android.** { *; }
-dontwarn com.hianalytics.android.**
-keep class com.huawei.updatesdk.** { *; }
-dontwarn com.huawei.updatesdk.**
#OPPO
-keep class com.coloros.mcssdk.** { *; }
-dontwarn com.coloros.mcssdk.**
#360聚合广告核心包
-keep class com.ak.** {*;}
-dontwarn com.ak.**
-keep class android.support.v4.** {
public *;
}
#广点通SDK
-keep class com.qq.e.** {
public protected *;
}
-keep class android.support.v7.**{
public *;
}
#穿山甲SDK
-keep class com.bytedance.sdk.openadsdk.** { *; }
-dontwarn com.bytedance.sdk.openadsdk.**
-keep class com.androidquery.callback.** {*;}
-keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;}
-keep class com.ss.sys.ces.* {*;}
#快手
-keep class org.chromium.** {*;}
-keep class org.chromium.** {*;}
-keep class aegon.chrome.** {*;}
-keep class com.kwai.**{*;}
-keep class com.kwad.**{*;}
-keepclasseswithmembernames class * {
native <methods>;
}
-dontwarn com.kwai.**
-dontwarn com.kwad.**
-dontwarn com.ksad.**
-dontwarn aegon.chrome.**
#一键登录
-dontwarn com.g.gysdk.**
-keep class com.g.gysdk.**{*;}
-dontwarn com.g.elogin.**
-keep class com.g.elogin.**{*;}
-dontwarn com.cmic.sso.sdk.**
-keep class com.cmic.sso.sdk.** {*;}
-dontwarn com.geetest.onelogin.**
-keep class com.geetest.onelogin.** {*;}
-dontwarn com.geetest.onepassv2.**
-keep class com.geetest.onepassv2.** {*;}
-dontwarn com.unicom.xiaowo.login.**
-keep class com.unicom.xiaowo.login.** {*;}
-dontwarn cn.com.chinatelecom.account.api.**
-keep class cn.com.chinatelecom.account.api.** {*;}
#腾讯X5--------------start-----------------------
-dontwarn dalvik.**
-dontwarn com.tencent.smtt.**
#-overloadaggressively
# ------------------ Keep LineNumbers and properties ---------------- #
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
# --------------------------------------------------------------------------
# Addidional for x5.sdk classes for apps
-keep class com.tencent.smtt.export.external.**{*;}
-keep class com.tencent.tbs.video.interfaces.IUserStateChangedListener {*;}
-keep class com.tencent.smtt.sdk.CacheManager {public *;}
-keep class com.tencent.smtt.sdk.CookieManager {public *;}
-keep class com.tencent.smtt.sdk.WebHistoryItem {public *;}
-keep class com.tencent.smtt.sdk.WebViewDatabase {public *;}
-keep class com.tencent.smtt.sdk.WebBackForwardList {public *;}
-keep public class com.tencent.smtt.sdk.WebView {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.WebView$HitTestResult {public static final <fields>;public java.lang.String getExtra();public int getType();}
-keep public class com.tencent.smtt.sdk.WebView$WebViewTransport {public <methods>;}
-keep public class com.tencent.smtt.sdk.WebView$PictureListener {public <fields>;public <methods>;}
-keepattributes InnerClasses
-keep public enum com.tencent.smtt.sdk.WebSettings$** {*;}
-keep public enum com.tencent.smtt.sdk.QbSdk$** {*;}
-keep public class com.tencent.smtt.sdk.WebSettings {public *;}
-keepattributes Signature
-keep public class com.tencent.smtt.sdk.ValueCallback {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.WebViewClient {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.DownloadListener {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.WebChromeClient {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.WebChromeClient$FileChooserParams {public <fields>;public <methods>;}
-keep class com.tencent.smtt.sdk.SystemWebChromeClient{public *;}
# 1. extension interfaces should be apparent
-keep public class com.tencent.smtt.export.external.extension.interfaces.* {public protected *;}
# 2. interfaces should be apparent
-keep public class com.tencent.smtt.export.external.interfaces.* {public protected *;}
-keep public class com.tencent.smtt.sdk.WebViewCallbackClient {public protected *;}
-keep public class com.tencent.smtt.sdk.WebStorage$QuotaUpdater {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.WebIconDatabase {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.WebStorage {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.DownloadListener {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.QbSdk {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.QbSdk$PreInitCallback {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.CookieSyncManager {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.Tbs* {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.utils.LogFileUtils {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.utils.TbsLog {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.utils.TbsLogClient {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.CookieSyncManager {public <fields>;public <methods>;}
# Added for game demos
-keep public class com.tencent.smtt.sdk.TBSGamePlayer {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.TBSGamePlayerClient* {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.TBSGamePlayerClientExtension {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.TBSGamePlayerService* {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.utils.Apn {public <fields>;public <methods>;}
-keep class com.tencent.smtt.** {*;}
# end
-keep public class com.tencent.smtt.export.external.extension.proxy.ProxyWebViewClientExtension {public <fields>;public <methods>;}
-keep class MTT.ThirdAppInfoNew {*;}
-keep class com.tencent.mtt.MttTraceEvent {*;}
# Game related
-keep public class com.tencent.smtt.gamesdk.* {public protected *;}
-keep public class com.tencent.smtt.sdk.TBSGameBooter {public <fields>;public <methods>;}
-keep public class com.tencent.smtt.sdk.TBSGameBaseActivity {public protected *;}
-keep public class com.tencent.smtt.sdk.TBSGameBaseActivityProxy {public protected *;}
-keep public class com.tencent.smtt.gamesdk.internal.TBSGameServiceClient {public *;}
#腾讯X5--------------end-----------------------

View File

@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@@ -0,0 +1,62 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许程序访问有关GSM网络信息 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 获取使用Wi-Fi等WLAN无线网络 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 媒体图片 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<!-- 媒体视频 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- 摄像头 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 录制音频 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 读取设备硬件信息,统计数据 -->
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<!-- 网络权限,当禁用后,无法进行检索等相关业务 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- SD卡写入 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- SD卡读取 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<application
android:label="微聊"
tools:replace="android:label"
android:icon="@mipmap/ic_launcher"
android:allowNativeHeapPointerTagging="false"
android:requestLegacyExternalStorage="true"
android:networkSecurityConfig="@xml/network_config">
<activity
android:name="com.chat.demo.MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
</queries>
</manifest>

View File

@@ -0,0 +1,25 @@
// Generated file.
//
// If you wish to remove Flutter's multidex support, delete this entire file.
//
// Modifications to this file should be done in a copy under a different name
// as this file may be regenerated.
package io.flutter.app;
import android.app.Application;
import android.content.Context;
import androidx.annotation.CallSuper;
import androidx.multidex.MultiDex;
/**
* Extension of {@link android.app.Application}, adding multidex support.
*/
public class FlutterMultiDexApplication extends Application {
@Override
@CallSuper
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}

View File

@@ -0,0 +1,13 @@
package com.chat.demo
import android.app.Application
import android.content.Context
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/launcher" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@drawable/launcher" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 配置支持http请求 -->
<network-security-config>
<base-config cleartextTrafficPermitted="true"> 
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>

View File

@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

30
android/build.gradle Normal file
View File

@@ -0,0 +1,30 @@
buildscript {
ext.kotlin_version = '1.9.0'
repositories {
google()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

View File

@@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true
android.enableJetifier=true

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip

29
android/settings.gradle Normal file
View File

@@ -0,0 +1,29 @@
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
}
include ":app"

198
assets/fonts/iconfont.json Normal file
View File

@@ -0,0 +1,198 @@
{
"id": "5019632",
"name": "通讯开源版",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "8562225",
"name": "朋友圈",
"font_class": "pengyouquan",
"unicode": "e61b",
"unicode_decimal": 58907
},
{
"icon_id": "6638071",
"name": "关于我们",
"font_class": "guanyuwomen",
"unicode": "e62e",
"unicode_decimal": 58926
},
{
"icon_id": "20258097",
"name": "视频号",
"font_class": "shipinhao",
"unicode": "e64e",
"unicode_decimal": 58958
},
{
"icon_id": "33404265",
"name": "账号安全",
"font_class": "zhanghaoanquan",
"unicode": "e619",
"unicode_decimal": 58905
},
{
"icon_id": "1302827",
"name": "帮助中心",
"font_class": "bangzhuzhongxin",
"unicode": "e63f",
"unicode_decimal": 58943
},
{
"icon_id": "2593625",
"name": "创建群聊",
"font_class": "chuangjianqunliao",
"unicode": "e615",
"unicode_decimal": 58901
},
{
"icon_id": "635569",
"name": "首页-好友",
"font_class": "haoyou",
"unicode": "e622",
"unicode_decimal": 58914
},
{
"icon_id": "9305794",
"name": "首页-群聊",
"font_class": "qunliao",
"unicode": "e71e",
"unicode_decimal": 59166
},
{
"icon_id": "9626960",
"name": "首页-消息",
"font_class": "xiaoxi",
"unicode": "e884",
"unicode_decimal": 59524
},
{
"icon_id": "4069437",
"name": "首页-我的",
"font_class": "wode",
"unicode": "e70f",
"unicode_decimal": 59151
},
{
"icon_id": "30155056",
"name": "多选",
"font_class": "duoxuan",
"unicode": "e608",
"unicode_decimal": 58888
},
{
"icon_id": "10164903",
"name": "扫一扫",
"font_class": "saoyisao1",
"unicode": "e663",
"unicode_decimal": 58979
},
{
"icon_id": "5641833",
"name": "扫一扫",
"font_class": "saoyisao",
"unicode": "e60c",
"unicode_decimal": 58892
},
{
"icon_id": "38446505",
"name": "软件设置",
"font_class": "ruanjianshezhi",
"unicode": "e602",
"unicode_decimal": 58882
},
{
"icon_id": "10156388",
"name": "转发",
"font_class": "zhuanfa",
"unicode": "e655",
"unicode_decimal": 58965
},
{
"icon_id": "1305399",
"name": "保存",
"font_class": "baocun",
"unicode": "e63c",
"unicode_decimal": 58940
},
{
"icon_id": "12310751",
"name": "at",
"font_class": "at",
"unicode": "e8de",
"unicode_decimal": 59614
},
{
"icon_id": "1790025",
"name": "复制",
"font_class": "fuzhi",
"unicode": "e6dd",
"unicode_decimal": 59101
},
{
"icon_id": "5638801",
"name": "删除",
"font_class": "shanchu",
"unicode": "e617",
"unicode_decimal": 58903
},
{
"icon_id": "9495516",
"name": "名片",
"font_class": "mingpian",
"unicode": "e62c",
"unicode_decimal": 58924
},
{
"icon_id": "39019190",
"name": "缺省",
"font_class": "none",
"unicode": "e610",
"unicode_decimal": 58896
},
{
"icon_id": "39019310",
"name": "plus",
"font_class": "add",
"unicode": "e625",
"unicode_decimal": 58917
},
{
"icon_id": "5387476",
"name": "声音播放",
"font_class": "shengyin",
"unicode": "eae0",
"unicode_decimal": 60128
},
{
"icon_id": "577312",
"name": "扩展切换",
"font_class": "extra",
"unicode": "e726",
"unicode_decimal": 59174
},
{
"icon_id": "912286",
"name": "表情切换",
"font_class": "emoji",
"unicode": "e644",
"unicode_decimal": 58948
},
{
"icon_id": "913746",
"name": "语音切换",
"font_class": "voice",
"unicode": "e664",
"unicode_decimal": 58980
},
{
"icon_id": "13245396",
"name": "键盘切换",
"font_class": "keyboard",
"unicode": "e618",
"unicode_decimal": 58904
}
]
}

BIN
assets/fonts/iconfont.ttf Normal file

Binary file not shown.

BIN
assets/image/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
assets/image/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
assets/image/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
assets/image/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
assets/image/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
assets/image/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
assets/image/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
assets/image/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
assets/image/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
assets/image/9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
assets/image/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
assets/image/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
assets/image/voice.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

34
ios/.gitignore vendored Normal file
View File

@@ -0,0 +1,34 @@
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

View File

@@ -0,0 +1,26 @@
<?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>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
</dict>
</plist>

View File

@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

66
ios/Podfile Normal file
View File

@@ -0,0 +1,66 @@
# Uncomment this line to define a global platform for your project
platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
# You can remove unused permissions here
# for more information: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
# e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=1',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',
## dart: PermissionGroup.notification
'PERMISSION_NOTIFICATIONS=1',
]
end
end
end

232
ios/Podfile.lock Normal file
View File

@@ -0,0 +1,232 @@
PODS:
- audio_session (0.0.1):
- Flutter
- barcode_scan2 (0.0.1):
- Flutter
- MTBBarcodeScanner
- SwiftProtobuf
- camera_avfoundation (0.0.1):
- Flutter
- 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
- emoji_picker_flutter (0.0.1):
- Flutter
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Flutter (1.0.0)
- flutter_keyboard_visibility (0.0.1):
- Flutter
- flutter_sound_record (0.0.1):
- Flutter
- image_gallery_saver (2.0.2):
- Flutter
- image_picker_ios (0.0.1):
- Flutter
- just_audio (0.0.1):
- Flutter
- media_kit_libs_ios_video (1.0.4):
- Flutter
- media_kit_video (0.0.1):
- Flutter
- MTBBarcodeScanner (5.0.11)
- package_info_plus (0.4.5):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.3.0):
- Flutter
- photo_manager (2.0.0):
- Flutter
- FlutterMacOS
- scan (0.0.1):
- Flutter
- screen_brightness_ios (0.1.0):
- Flutter
- SDWebImage (5.21.2):
- SDWebImage/Core (= 5.21.2)
- SDWebImage/Core (5.21.2)
- sensors_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sqflite (0.0.3):
- Flutter
- FlutterMacOS
- SwiftProtobuf (1.31.0)
- SwiftyGif (5.4.5)
- video_player_avfoundation (0.0.1):
- Flutter
- FlutterMacOS
- volume_controller (0.0.1):
- Flutter
- wakelock_plus (0.0.1):
- Flutter
- webview_flutter_wkwebview (0.0.1):
- Flutter
DEPENDENCIES:
- audio_session (from `.symlinks/plugins/audio_session/ios`)
- barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- emoji_picker_flutter (from `.symlinks/plugins/emoji_picker_flutter/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- Flutter (from `Flutter`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
- flutter_sound_record (from `.symlinks/plugins/flutter_sound_record/ios`)
- image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- just_audio (from `.symlinks/plugins/just_audio/ios`)
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
- scan (from `.symlinks/plugins/scan/ios`)
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
- sensors_plus (from `.symlinks/plugins/sensors_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
SPEC REPOS:
trunk:
- DKImagePickerController
- DKPhotoGallery
- MTBBarcodeScanner
- SDWebImage
- SwiftProtobuf
- SwiftyGif
EXTERNAL SOURCES:
audio_session:
:path: ".symlinks/plugins/audio_session/ios"
barcode_scan2:
:path: ".symlinks/plugins/barcode_scan2/ios"
camera_avfoundation:
:path: ".symlinks/plugins/camera_avfoundation/ios"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
emoji_picker_flutter:
:path: ".symlinks/plugins/emoji_picker_flutter/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
Flutter:
:path: Flutter
flutter_keyboard_visibility:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
flutter_sound_record:
:path: ".symlinks/plugins/flutter_sound_record/ios"
image_gallery_saver:
:path: ".symlinks/plugins/image_gallery_saver/ios"
image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios"
just_audio:
:path: ".symlinks/plugins/just_audio/ios"
media_kit_libs_ios_video:
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
media_kit_video:
:path: ".symlinks/plugins/media_kit_video/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
photo_manager:
:path: ".symlinks/plugins/photo_manager/ios"
scan:
:path: ".symlinks/plugins/scan/ios"
screen_brightness_ios:
:path: ".symlinks/plugins/screen_brightness_ios/ios"
sensors_plus:
:path: ".symlinks/plugins/sensors_plus/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
sqflite:
:path: ".symlinks/plugins/sqflite/darwin"
video_player_avfoundation:
:path: ".symlinks/plugins/video_player_avfoundation/darwin"
volume_controller:
:path: ".symlinks/plugins/volume_controller/ios"
wakelock_plus:
:path: ".symlinks/plugins/wakelock_plus/ios"
webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
SPEC CHECKSUMS:
audio_session: 088d2483ebd1dc43f51d253d4a1c517d9a2e7207
barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
camera_avfoundation: dd002b0330f4981e1bbcb46ae9b62829237459a4
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
emoji_picker_flutter: fe2e6151c5b548e975d546e6eeb567daf0962a58
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
flutter_sound_record: fa9800029599bccfaa8be22cc372550a5fa505ac
image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
photo_manager: ff695c7a1dd5bc379974953a2b5c0a293f7c4c8a
scan: aea35bb4aa59ccc8839c576a18cd57c7d492cc86
screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625
SDWebImage: 9f177d83116802728e122410fb25ad88f5c7608a
sensors_plus: 18a9b346c43e157da17d2c8e99def703f9efb9d8
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
SwiftProtobuf: caa61117d9a5eeb60a52375f6685991a1fd4bd7b
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9
wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1
webview_flutter_wkwebview: 2a23822e9039b7b1bc52e5add778e5d89ad488d1
PODFILE CHECKSUM: d13967f32d505bfc287f89b46a244b6ec471ee5e
COCOAPODS: 1.16.2

View File

@@ -0,0 +1,757 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
CC6507E9BCD830F82DB6ADC6 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C22F9F1C44A1F893243BD002 /* Pods_Runner.framework */; };
D27770040FEFB77541F5252F /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8132DC180632E27A2829F2A /* Pods_RunnerTests.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<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>"; };
4FA6F60FFE45C1A40ED90C54 /* 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>"; };
57B27EA12A167C1E03B22EFC /* 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>"; };
6C806ADCB853A8168F211A1C /* 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>"; };
70CB9E40C8FEFD9984893862 /* 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>"; };
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>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
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; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
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>"; };
C22F9F1C44A1F893243BD002 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D8132DC180632E27A2829F2A /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E41373226637E48F3877F80D /* 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>"; };
ED125CA064D2D12574A0421A /* 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>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
78BD0F8133D207D6E5AB0E10 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D27770040FEFB77541F5252F /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CC6507E9BCD830F82DB6ADC6 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
82026B7305B1921A3491AD11 /* Frameworks */ = {
isa = PBXGroup;
children = (
C22F9F1C44A1F893243BD002 /* Pods_Runner.framework */,
D8132DC180632E27A2829F2A /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
F43C9B9482EF8D9FFBD025F0 /* Pods */,
82026B7305B1921A3491AD11 /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
F43C9B9482EF8D9FFBD025F0 /* Pods */ = {
isa = PBXGroup;
children = (
57B27EA12A167C1E03B22EFC /* Pods-Runner.debug.xcconfig */,
E41373226637E48F3877F80D /* Pods-Runner.release.xcconfig */,
6C806ADCB853A8168F211A1C /* Pods-Runner.profile.xcconfig */,
4FA6F60FFE45C1A40ED90C54 /* Pods-RunnerTests.debug.xcconfig */,
70CB9E40C8FEFD9984893862 /* Pods-RunnerTests.release.xcconfig */,
ED125CA064D2D12574A0421A /* Pods-RunnerTests.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
191032355ADD68D22B244651 /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
78BD0F8133D207D6E5AB0E10 /* Frameworks */,
);
buildRules = (
);
dependencies = (
331C8086294A63A400263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
6D829C5DD68D87D2E556ECB6 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
45B67CBD46EE843B5A56C622 /* [CP] Embed Pods Frameworks */,
F082247C9CFE253CB68065D2 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C8080294A63A400263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
331C807F294A63A400263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
191032355ADD68D22B244651 /* [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;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
45B67CBD46EE843B5A56C622 /* [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;
};
6D829C5DD68D87D2E556ECB6 /* [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;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
F082247C9CFE253CB68065D2 /* [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;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
331C807D294A63A400263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = CC224Z6VY2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.chat.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 4FA6F60FFE45C1A40ED90C54 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.demoApp.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 70CB9E40C8FEFD9984893862 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.demoApp.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = ED125CA064D2D12574A0421A /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.demoApp.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = CC224Z6VY2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.chat.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = CC224Z6VY2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.chat.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C8088294A63A400263BE5 /* Debug */,
331C8089294A63A400263BE5 /* Release */,
331C808A294A63A400263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
<?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>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
<?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>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@@ -0,0 +1,13 @@
import Flutter
import UIKit
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1 @@
{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"}]}

View File

@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "LaunchImage.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "LaunchImage@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "LaunchImage@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,5 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

100
ios/Runner/Info.plist Normal file
View File

@@ -0,0 +1,100 @@
<?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>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>微聊</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>demo</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<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>alipay</string>
<key>CFBundleURLSchemes</key>
<array>
<string>alipay123</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>FlutterDeepLinkingEnabled</key>
<true/>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tel</string>
<string>weixin</string>
<string>weixinULAPI</string>
<string>weixinURLParamsAPI</string>
<string>alipay</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<string>如果不允许,你将无法在聊天中发送你的文件,也无法完整使用与文件相关的服务。</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key>
<string>如果不允许,你将无法在聊天中发送你的图片,也无法完整使用与相机相关的服务。</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>如果不允许,你将无法在聊天中发送你的位置,也无法完整使用与位置相关的服务。</string>
<key>NSLocationUsageDescription</key>
<string>如果不允许,你将无法在聊天中发送你的位置,也无法完整使用与位置相关的服务。</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>如果不允许,你将无法在聊天中发送你的位置,也无法完整使用与位置相关的服务。</string>
<key>NSMicrophoneUsageDescription</key>
<string>如果不允许,你将无法在聊天中发送你的声音,也无法完整使用与麦克风相关的服务。</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>如果不允许,你将无法在聊天中发送你的图片,也无法完整使用与相册相关的服务。</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
</dict>
</plist>

View File

@@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View File

@@ -0,0 +1,10 @@
<?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:baidu.com</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,12 @@
import Flutter
import UIKit
import XCTest
class RunnerTests: XCTestCase {
func testExample() {
// If you add code to the Runner application, consider adding tests here.
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
}
}

View File

@@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:demo/config/app_theme.dart';
// 右边组件
class ComponentAction extends StatelessWidget {
final Icon? icon;
final bool enable;
final String label;
final VoidCallback onTap;
const ComponentAction({
this.enable = true,
super.key,
this.icon,
this.label = '完成',
required this.onTap,
});
@override
Widget build(BuildContext context) {
if (!enable) {
return Container();
}
return InkWell(
onTap: onTap,
child: Padding(
padding: const EdgeInsets.only(right: 15),
child: icon ??
Container(
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: AppTheme.color,
),
height: 30,
width: 50,
child: Text(
label,
style: const TextStyle(
color: Colors.white,
),
),
),
),
);
}
}

View File

@@ -0,0 +1,87 @@
import 'dart:async';
import 'dart:io';
import 'package:demo/config/app_config.dart';
import 'package:get/get.dart';
import 'package:demo/tools/tools_perms.dart';
import 'package:demo/component/component_bottom.dart';
import 'package:demo/component/component_common.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import 'package:wechat_camera_picker/wechat_camera_picker.dart';
// 上传组件
class ComponentAvatar {
// 拍摄/图片
static Future<void> image({
required Function(String value) onTap,
}) async {
ComponentBottom([
BottomModel(
'图片',
onTap: () async {
// 关闭
Get.back();
// 权限
bool result = await ToolsPerms.photos();
if (!result) {
return;
}
// 选取
String portrait = await _image();
// 修改
onTap.call(portrait);
},
),
BottomModel(
'拍照',
onTap: () async {
// 关闭
Get.back();
// 权限
bool result = await ToolsPerms.camera();
if (!result) {
return;
}
// 拍照
String portrait = await _image(camera: true);
// 修改
onTap.call(portrait);
},
),
]);
}
// 拍摄/图片
static Future<String> _image({
bool camera = false,
}) async {
// 对象
AssetEntity? entity;
// 拍照
if (camera) {
entity = await CameraPicker.pickFromCamera(
AppConfig.navigatorKey.currentContext!,
);
}
// 本地选取
else {
// 选取
List<AssetEntity>? dataList = await AssetPicker.pickAssets(
AppConfig.navigatorKey.currentContext!,
pickerConfig: AssetPickerConfig(
maxAssets: 1,
requestType: RequestType.image,
pathNameBuilder: (AssetPathEntity path) {
return ComponentCommon.pathName(path);
},
),
);
entity = dataList!.first;
}
// 判断
if (entity == null) {
return '';
}
File? file = await entity.file;
return file?.path ?? '';
}
}

View File

@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:demo/config/app_config.dart';
import 'package:demo/config/app_theme.dart';
import 'package:demo/component/component_common.dart';
// 底部弹出
class ComponentBottom {
ComponentBottom(List<BottomModel> dataList) {
dataList.add(
BottomModel(
'取消',
onTap: () {
Get.back();
},
),
);
int length = dataList.length;
showModalBottomSheet(
context: AppConfig.navigatorKey.currentState!.context,
builder: (builder) {
return SizedBox(
height: 60.0 * length,
child: ListView.separated(
itemCount: length,
separatorBuilder: (BuildContext context, int index) {
if (length == index + 2) {
return Container(
color: Colors.grey.shade200,
height: 12,
);
}
return ComponentCommon.divider();
},
itemBuilder: (ctx, index) {
BottomModel model = dataList[index];
return ListTile(
title: Text(
model.label,
textAlign: TextAlign.center,
style: TextStyle(
color: AppTheme.color,
fontWeight: FontWeight.w600,
),
),
onTap: model.onTap,
);
},
),
);
},
);
}
}
// 底部弹出对象
class BottomModel {
// 文本
String label;
// 点击
GestureTapCallback? onTap;
BottomModel(this.label, {this.onTap});
}

View File

@@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
import 'package:demo/config/app_theme.dart';
// 按钮组件
class ComponentButton extends StatefulWidget {
final bool search;
final String? label;
final Color? color;
final VoidCallback onTap;
const ComponentButton({
super.key,
this.label,
required this.onTap,
this.search = false,
this.color,
});
@override
createState() => _ComponentButtonState();
}
class _ComponentButtonState extends State<ComponentButton> {
@override
Widget build(BuildContext context) {
if (widget.search) {
return _buildSearch();
}
return _buildButton();
}
_buildSearch() {
String label = widget.label ?? '搜索';
return InkWell(
onTap: widget.onTap,
child: Padding(
padding: const EdgeInsets.only(right: 6),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: AppTheme.color,
),
height: 40,
width: 50,
child: Text(
label,
style: const TextStyle(color: Colors.white),
),
),
),
);
}
_buildButton() {
String label = widget.label ?? '提交';
return Container(
width: double.infinity,
height: 70,
padding: const EdgeInsets.only(top: 16),
margin: const EdgeInsets.symmetric(horizontal: 20),
child: MaterialButton(
disabledColor: Colors.grey,
onPressed: widget.onTap,
color: widget.color ?? AppTheme.color,
textColor: Colors.white,
child: Text(
label,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
),
),
),
);
}
}

View File

@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:demo/component/component_common.dart';
// 名片组件
class ComponentCard extends StatelessWidget {
final String nickname;
final String portrait;
final String userNo;
const ComponentCard({
super.key,
required this.nickname,
required this.portrait,
required this.userNo,
});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 80,
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 10),
child: ComponentCommon.showAvatar(
portrait,
size: 55,
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
nickname,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
),
const SizedBox(
height: 10,
),
Text(
'ID$userNo',
style: const TextStyle(
color: Color.fromARGB(255, 123, 122, 122),
),
),
],
),
),
],
),
);
}
}

View File

@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
// 复选框
class ComponentCheckbox extends StatefulWidget {
final bool value;
final ValueChanged<bool> onChanged;
final double size;
const ComponentCheckbox({
super.key,
required this.value,
required this.onChanged,
this.size = 26,
});
@override
createState() => _CheckboxState();
}
class _CheckboxState extends State<ComponentCheckbox> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
widget.onChanged(!widget.value);
},
child: Container(
width: widget.size,
height: widget.size,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: widget.value ? Colors.white : Colors.grey,
),
color: widget.value ? Colors.indigoAccent[400] : Colors.transparent,
),
child: Center(
child: widget.value
? Icon(
Icons.check,
color: Colors.white,
size: widget.size - 6,
)
: null,
),
),
);
}
}

View File

@@ -0,0 +1,364 @@
import 'dart:async';
import 'dart:io';
import 'dart:ui' as ui_;
import 'package:demo/config/app_resource.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_pickers/style/picker_style.dart';
import 'package:demo/config/app_fonts.dart';
import 'package:demo/tools/tools_regex.dart';
import 'package:demo/tools/tools_format.dart';
import 'package:demo/component/component_image.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pretty_qr_code/pretty_qr_code.dart';
import 'package:timeago/timeago.dart' as timeago;
import 'package:uuid/uuid.dart';
import 'package:image/image.dart' as img;
import 'package:path/path.dart' as path;
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
// 公共组件
class ComponentCommon {
// widgit转图片
static Future<Uint8List> widgetToImage(GlobalKey globalKey) async {
Completer<Uint8List> completer = Completer();
BuildContext? context = globalKey.currentContext;
RenderRepaintBoundary render =
context!.findRenderObject() as RenderRepaintBoundary;
ui_.Image image =
await render.toImage(pixelRatio: View.of(context).devicePixelRatio);
ByteData? byteData =
await image.toByteData(format: ui_.ImageByteFormat.png);
completer.complete(byteData?.buffer.asUint8List());
return completer.future;
}
// 保存文件
static Future<void> saveFile(String filePath, String suffix) async {
var appDocDir = await getTemporaryDirectory();
if (suffix.isEmpty) {
appDocDir = await getApplicationDocumentsDirectory();
}
final savePath = path.join(appDocDir.path, '${const Uuid().v8()}$suffix');
// 确保目录存在
await File(filePath).copy(savePath);
// 保存图片到本地
await ImageGallerySaver.saveFile(savePath);
// 弹框提示
EasyLoading.showToast('保存成功121');
}
// 计算大小
static Future<Map<String, dynamic>> calculateImage(String filePath) async {
final file = File(filePath);
final bytes = await file.readAsBytes();
final image = img.decodeImage(bytes);
int? height = image?.height;
int? width = image?.width;
return {'height': height ?? 200, 'width': width ?? 200};
}
// 计算大小
static Future<Map<String, dynamic>> calculateVideo(String filePath) async {
return {'height': 200, 'width': 200};
}
// 加载中
static Widget loading() {
return const Center(child: CircularProgressIndicator());
}
// 没有数据
static Widget none() {
return const Center(
child: Icon(
AppFonts.e610,
color: Colors.black26,
size: 40,
),
);
}
// 箭头
static Widget arrow() {
return const Opacity(
opacity: 0.3,
child: Icon(Icons.keyboard_arrow_right),
);
}
// 分割线
static Widget divider() {
return const Divider(
color: Color.fromARGB(255, 232, 228, 228), // 设置分割线的颜色
height: 0.5, // 设置分割线的高度为2.0像素
thickness: 0.5, // 设置分割线的粗细为1.0像素
indent: 15, // 设置分割线的缩进为16.0像素
endIndent: 15, // 设置分割线结束位置的缩进为16.0像素
);
}
// 边框
static Widget border({bool enable = true}) {
if (!enable) {
return Container();
}
return Container(
height: 10,
color: Colors.grey[100],
);
}
// 时间
static Widget timeFormat(DateTime dateTime, bool show) {
if (!show) {
return const Text(
'',
);
}
timeago.setLocaleMessages('en', ToolsFormat());
return Text(
timeago.format(dateTime),
style: const TextStyle(fontSize: 12, color: Color(0xFFa9a9a9)),
);
}
// 相册汉化
static String pathName(AssetPathEntity path) {
String label;
switch (path.name) {
case 'Screenshots':
label = '最近';
break;
case 'Recents':
case 'Recent':
label = '全部';
break;
case 'Videos':
case 'Movies':
label = '视频';
break;
case 'Camera':
label = '相机';
break;
case 'Pictures':
case 'paintpad':
label = '相册';
break;
case 'Selfies':
label = '自拍';
break;
case 'Live Photos':
label = '实况图片';
break;
case 'Animated':
label = '动图';
break;
case 'Alipay':
label = '支付宝';
break;
case 'WeiXin':
label = '微信';
break;
case 'WeixinWork':
label = '企业微信';
break;
default:
label = '其他';
break;
}
return label;
}
// 计算长度
static double textSize(String text, {double width = 20.00}) {
final TextPainter textPainter = TextPainter(
text: TextSpan(text: text),
maxLines: 1,
textDirection: TextDirection.ltr)
..layout(minWidth: 0, maxWidth: double.infinity);
return textPainter.size.width + width;
}
// 提醒文字
static Widget label(
String value, {
Alignment alignment = Alignment.centerLeft,
}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Align(
alignment: alignment,
child: Text(
value,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
);
}
// 提醒文字
static Widget tips(
String value, {
TextAlign textAlign = TextAlign.center,
}) {
if (value.isEmpty) {
return Container();
}
Alignment alignment = Alignment.center;
if (textAlign == TextAlign.left) {
alignment = Alignment.centerLeft;
} else if (textAlign == TextAlign.right) {
alignment = Alignment.centerRight;
}
return Align(
alignment: alignment,
child: Text(
value,
style: const TextStyle(
color: ui_.Color.fromARGB(255, 150, 150, 149),
),
textAlign: textAlign,
),
);
}
// 无样式
static PickerStyle pickerStyle() {
PickerStyle style = PickerStyle();
style.commitButton = Container(
alignment: Alignment.center,
padding: const EdgeInsets.only(
left: 12,
right: 22,
),
child: const Text(
'确定',
style: TextStyle(
color: Colors.black,
fontSize: 16.0,
),
),
);
style.textSize = 20.0;
return style;
}
// 显示头像
static showAvatar(String avatar, {double size = 50}) {
if (avatar.isEmpty) {
return SizedBox(
height: size + 10,
width: size + 10,
);
}
ImageType imageType = ImageType.asset;
if (!ToolsRegex.isAsset(avatar)) {
imageType = ImageType.file;
}
return ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: ComponentImage(
avatar,
imageType,
fit: BoxFit.cover,
width: size,
height: size,
),
);
}
// 显示二维码
static showQrCode({required String data, required String avatar}) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 40),
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 10),
child: PrettyQrView.data(
data: data,
errorCorrectLevel: QrErrorCorrectLevel.Q,
decoration: PrettyQrDecoration(
image: PrettyQrDecorationImage(
image: ComponentImage.provider(avatar),
padding: const EdgeInsets.all(10),
fit: BoxFit.cover,
onError: (exception, stackTrace) => Image.asset(AppImage.error),
),
),
),
);
}
// 自定义椭圆区域
static Widget customRedClipper() {
// 椭圆区域
return ClipPath(
clipper: const _CustomClipper(search: true),
child: Container(
color: Colors.red,
width: double.infinity,
height: 50,
),
);
}
// 自定义椭圆区域
static Widget customClipper() {
return ClipPath(
// 椭圆区域
clipper: const _CustomClipper(),
child: Container(
color: Colors.white,
width: double.infinity,
height: 100,
child: const Icon(
AppFonts.e664,
size: 35,
),
),
);
}
}
// 椭圆区域
class _CustomClipper extends CustomClipper<Path> {
final bool search;
const _CustomClipper({
this.search = false,
});
@override
Path getClip(Size size) {
var path = Path();
if (search) {
path.lineTo(0, size.height - 35);
path.quadraticBezierTo(
size.width / 2,
size.height,
size.width,
size.height - 35,
);
path.lineTo(size.width, 0);
} else {
path.moveTo(0, 35);
// 上面的半圆
path.quadraticBezierTo(
size.width / 2,
-35,
size.width,
35,
);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
}
path.close();
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}

View File

@@ -0,0 +1,288 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:demo/config/app_theme.dart';
import 'package:demo/component/component_common.dart';
import 'package:grouped_list/grouped_list.dart';
import 'package:lpinyin/lpinyin.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
// 通讯录组件
class ComponentContact extends StatefulWidget {
// 选中文字
final String mark;
// 数据列表
final List<ContactModel> dataList;
// 选中列表
final List<String>? selectList;
// 单击事件
final Function(ContactModel model)? onTap;
// 多选事件
final Function(List<String> selectList)? onSelect;
const ComponentContact({
super.key,
this.mark = '选中',
required this.dataList,
this.selectList,
this.onTap,
this.onSelect,
});
@override
createState() => _ComponentContactState();
}
class _ComponentContactState extends State<ComponentContact> {
List<ContactModel> displayList = [];
List<String> selectList = [];
@override
void initState() {
super.initState();
displayList = widget.dataList;
selectList = widget.selectList ?? [];
}
@override
Widget build(BuildContext context) {
// 处理参数
List<ContactModel> dataList = _handle(displayList);
return GestureDetector(
behavior: HitTestBehavior.translucent,
onPanDown: (details) {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Column(
children: [
_buildSearch(),
Expanded(
child: _buildList(dataList),
),
],
),
);
}
// 搜索框
_buildSearch() {
return TDSearchBar(
placeHolder: '请输内容',
onTextChanged: (values) {
setState(() {
// 过滤数据
displayList = widget.dataList.where((data) {
if (data.select) {
return true;
}
String nickname = data.nickname.toLowerCase();
String extend = data.extend.toLowerCase();
String value = values.toLowerCase();
return nickname.contains(value) || extend.contains(value);
}).toList();
});
},
);
}
_buildList(List<ContactModel> dataList) {
return GroupedListView(
// 数据列表
elements: dataList,
// 分组类型
groupBy: (element) {
return element.tag;
},
// 分组排序
groupComparator: (value1, value2) {
// 排序
if (value1 == "#" || value2 == "#") {
return -1;
}
// 选中
if (value1 == widget.mark || value2 == widget.mark) {
return -1;
}
return value1.compareTo(value2);
},
// 分组间隔
groupSeparatorBuilder: (value) {
return _buildTag(value);
},
// 单条排序
itemComparator: (item1, item2) {
return item1.pinyin.compareTo(item2.pinyin);
},
// 单条数据
indexedItemBuilder: (context, element, index) {
bool divider = true;
if (index + 1 < dataList.length) {
divider = dataList[index].tag == dataList[index + 1].tag;
}
return _buildItem(element, divider);
},
);
}
// 分组标签
_buildTag(String value) {
return Container(
height: 40,
width: context.width,
padding: const EdgeInsets.only(left: 16.0),
color: const Color(0xFFF3F4F5),
alignment: Alignment.centerLeft,
child: Text(
value,
softWrap: false,
style: const TextStyle(
fontSize: 14.0,
color: Color(0xFF666666),
),
),
);
}
// 处理参数
List<ContactModel> _handle(List<ContactModel> displayList) {
List<ContactModel> dataList = [];
// 处理数据
if (displayList.isNotEmpty) {
for (int i = 0, length = displayList.length; i < length; i++) {
String nickname = displayList[i].nickname;
String pinyin = PinyinHelper.getPinyinE(nickname);
String tag = pinyin.substring(0, 1).toUpperCase();
if (displayList[i].select) {
tag = widget.mark;
}
// 其他
else if (!RegExp("[A-Z]").hasMatch(tag)) {
tag = '#';
}
displayList[i].tag = tag;
displayList[i].pinyin = pinyin;
}
// A-Z sort.
sortTag(displayList);
// 放入列表
dataList.addAll(displayList);
}
setState(() {});
return dataList;
}
// 排序
void sortTag(List<ContactModel> dataList) {
if (dataList.isNotEmpty) {
dataList.sort((a, b) {
// 所有人
if (a.userId == "0") {
return -1;
}
// 选中
if (a.tag == widget.mark) {
return -1;
}
// 选中
if (b.tag == "#") {
return -1;
}
// 选中
if (a.tag == "#") {
return 1;
}
// 选中
if (b.tag == widget.mark) {
return 1;
}
int sort = a.tag.compareTo(b.tag);
if (sort == 0) {
return a.userId.compareTo(b.userId);
}
return sort;
});
}
}
// 详情
_buildItem(ContactModel model, bool divider) {
String portrait = model.portrait;
String nickname = model.nickname;
String userId = model.userId;
String extend = model.extend;
return Column(
children: [
ListTile(
leading: ComponentCommon.showAvatar(
portrait,
size: 40,
),
title: Text(nickname),
subtitle: extend.isEmpty ? null : Text(extend),
trailing: widget.onSelect != null
? Checkbox(
value: model.select,
fillColor: WidgetStateColor.resolveWith((states) {
// 开启状态
if (states.contains(WidgetState.selected)) {
// 选中
if (model.select) {
return AppTheme.color;
}
// 未选中
return Colors.grey;
}
// 关闭状态
return Colors.white;
}),
onChanged: (value) {
model.select = value!;
if (value) {
selectList.add(userId);
} else {
selectList.remove(userId);
}
setState(() {});
widget.onSelect?.call(selectList);
},
)
: null,
onTap: () {
if (widget.onTap != null) {
widget.onTap?.call(
ContactModel(
userId: userId,
nickname: nickname,
portrait: portrait,
),
);
}
},
),
if (divider) ComponentCommon.divider()
],
);
}
}
class ContactModel {
String userId;
String nickname;
String portrait;
String pinyin;
bool select;
String extend;
String tag;
ContactModel({
required this.userId,
required this.nickname,
required this.portrait,
this.select = false,
this.extend = '',
String remark = '',
this.tag = '',
this.pinyin = '',
}) {
if (remark.isNotEmpty) {
nickname = remark;
}
}
}

View File

@@ -0,0 +1,158 @@
import 'dart:io';
import 'package:demo/tools/tools_regex.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:demo/config/app_resource.dart';
import 'package:photo_view/photo_view_gallery.dart';
// 图片组件
class ComponentImage extends StatelessWidget {
final String path;
final ImageType imageType;
final double width;
final double? height;
final Color? color;
final BoxFit? fit;
final bool gallery;
const ComponentImage(
this.path,
this.imageType, {
super.key,
this.width = 100,
this.height = 100,
this.color,
this.fit,
this.gallery = false,
});
@override
Widget build(BuildContext context) {
if (gallery) {
return GestureDetector(
child: _build(),
onTap: () {
if (gallery) {
Get.to(
ShowImage(path, imageType),
transition: Transition.topLevel,
);
}
},
);
}
return _build();
}
_build() {
if (ImageType.file == imageType) {
return Image.file(
File(path),
width: width,
height: height,
color: color,
fit: fit,
errorBuilder: (context, error, stackTrace) {
return _error();
},
);
}
if (ImageType.asset == imageType) {
return Image.asset(
path,
width: width,
height: height,
color: color,
fit: fit,
errorBuilder: (context, error, stackTrace) {
return _error();
},
);
}
return Container(
width: 50,
);
}
_error() {
return Image.asset(
AppImage.error,
width: width,
height: height,
color: color,
fit: fit,
);
}
static ImageProvider provider(String path) {
if (ToolsRegex.isAsset(path)) {
return AssetImage(path);
}
Image image = Image.file(
File(path),
errorBuilder: (context, error, stackTrace) {
return Image.asset(AppImage.error);
},
);
return image.image;
}
}
// 图片类型
enum ImageType {
// 文件
file('file'),
// 资源
asset('asset'),
;
const ImageType(this.value);
final String value;
}
// 图片组件
class ShowImage extends StatelessWidget {
final String path;
final ImageType imageType;
const ShowImage(
this.path,
this.imageType, {
super.key,
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: InkWell(
onTap: () {
Get.back();
},
child: PhotoViewGallery.builder(
itemCount: 1,
builder: (context, index) {
return PhotoViewGalleryPageOptions(
imageProvider: _provider(),
errorBuilder: (context, error, stackTrace) {
return Image.asset(AppImage.error);
},
);
},
scrollPhysics: const BouncingScrollPhysics(),
backgroundDecoration: const BoxDecoration(
color: Colors.white,
),
pageController: PageController(),
),
),
);
}
ImageProvider _provider() {
switch (imageType) {
case ImageType.file:
// ??????????????
return FileImage(File(path));
case ImageType.asset:
return AssetImage(path);
}
}
}

View File

@@ -0,0 +1,271 @@
import 'package:flutter/material.dart';
import 'package:demo/component/component_common.dart';
// 表格组件
class ComponentLineTable extends StatelessWidget {
final String label;
final bool enable;
final bool divider;
final String value;
const ComponentLineTable(
this.label,
this.value, {
super.key,
this.enable = true,
this.divider = true,
});
@override
Widget build(BuildContext context) {
if (!enable) {
return Container();
}
String text = '$label :';
double width = ComponentCommon.textSize(text);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.all(14),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row(
children: [
SizedBox(
width: width,
child: Text(
text,
style: const TextStyle(
fontSize: 16,
color: Color(0xFFa9a9a9),
),
),
),
Expanded(
child: Text(
value,
style: const TextStyle(
fontSize: 14,
color: Color(0xFF353535),
),
),
),
],
),
),
// 间隔线
if (divider) ComponentCommon.divider(),
],
);
}
}
// 单行组件
class ComponentLineRow extends StatelessWidget {
final bool enable;
final bool divider;
final String title;
final String? subtitle;
final Color? color;
final double hight;
final Icon? leading;
final String value;
final Widget? widget;
final bool arrow;
final GestureTapCallback? onTap;
final GestureLongPressCallback? onLongPress;
const ComponentLineRow(
this.title, {
this.enable = true,
this.divider = true,
this.subtitle,
this.color,
this.hight = 0.0,
this.leading,
this.value = '',
this.widget,
this.arrow = true,
this.onTap,
this.onLongPress,
super.key,
});
@override
Widget build(BuildContext context) {
if (!enable) {
return Container();
}
return Column(
children: [
Stack(
alignment: Alignment.bottomLeft,
children: [
ListTile(
contentPadding: EdgeInsets.only(
top: hight,
bottom: hight,
left: 12,
right: 5,
),
leading: leading,
title: Text(
title,
style: TextStyle(
fontSize: 16,
color: color,
),
),
subtitle: subtitle != null
? Text(
subtitle!,
style: const TextStyle(
fontSize: 12,
color: Color.fromARGB(255, 149, 144, 144),
),
)
: null,
trailing: Container(
constraints: const BoxConstraints(
maxWidth: 150,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: Padding(
padding: EdgeInsets.only(right: arrow ? 0 : 10),
child: Text(
value,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 14,
),
textAlign: TextAlign.end,
),
),
),
widget ?? Container(),
arrow ? ComponentCommon.arrow() : Container(),
],
),
),
onTap: onTap,
onLongPress: onLongPress,
),
],
),
if (divider) ComponentCommon.divider(),
],
);
}
}
// 单行组件
class ComponentLineCenter extends StatelessWidget {
final String title;
final bool enable;
final bool divider;
final Color? color;
final GestureTapCallback? onTap;
const ComponentLineCenter(
this.title, {
this.enable = true,
this.divider = true,
this.color,
this.onTap,
super.key,
});
@override
Widget build(BuildContext context) {
if (!enable) {
return Container();
}
return GestureDetector(
onTap: onTap,
child: Container(
color: Colors.white,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 16, bottom: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
title,
style: TextStyle(
color: color,
fontSize: 14,
),
),
],
),
),
if (divider) ComponentCommon.divider(),
],
),
),
);
}
}
// 内容组件
class ComponentLineContent extends StatelessWidget {
final String label;
final String value;
final bool divider;
final GestureTapCallback? onTap;
const ComponentLineContent(
this.label,
this.value, {
this.divider = true,
this.onTap,
super.key,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Column(
children: [
Container(
color: Colors.white,
margin: const EdgeInsets.symmetric(vertical: 15),
padding: const EdgeInsets.only(left: 12, right: 6),
child: Row(
children: [
Text(
label,
style: const TextStyle(
fontSize: 16,
),
),
const SizedBox(
width: 25,
),
Expanded(
child: Text(
value,
maxLines: 8,
textAlign: TextAlign.right,
style: const TextStyle(
fontSize: 14,
),
),
),
onTap != null ? ComponentCommon.arrow() : Container(width: 10),
],
),
),
if (divider) ComponentCommon.divider(),
],
),
);
}
}

View File

@@ -0,0 +1,61 @@
import 'package:flutter/material.dart';
import 'package:demo/config/app_fonts.dart';
// 顶部弹出组件
class ComponentPopup extends StatelessWidget {
final List<PopupModel> dataList;
const ComponentPopup({
super.key,
required this.dataList,
});
@override
Widget build(BuildContext context) {
List<PopupMenuItem> itemList = [];
for (var data in dataList) {
itemList.add(_popupItem(data));
}
return PopupMenuButton(
color: Colors.white,
offset: const Offset(0, 50),
icon: const Icon(
AppFonts.e625,
),
itemBuilder: (BuildContext context) {
return itemList;
},
);
}
// 顶部add加号详情
_popupItem(PopupModel popupModel) {
return PopupMenuItem(
onTap: popupModel.onTap,
child: Column(
children: [
Row(
children: [
popupModel.icon,
const SizedBox(width: 10),
Text(
popupModel.label,
style: TextStyle(fontSize: 16, color: Colors.grey[800]),
),
],
),
],
),
);
}
}
class PopupModel {
String label;
Icon icon;
VoidCallback? onTap;
PopupModel(
this.label,
this.icon, {
required this.onTap,
});
}

View File

@@ -0,0 +1,112 @@
import 'package:flutter/material.dart';
import 'package:flutter_pickers/pickers.dart';
import 'package:demo/component/component_common.dart';
// 禁言组件
class ComponentSpeak extends StatefulWidget {
final String? speakType;
final Function(String value) onChange;
const ComponentSpeak({
super.key,
required this.onChange,
this.speakType,
});
@override
createState() => _ComponentSpeakState();
}
class _ComponentSpeakState extends State<ComponentSpeak> {
_SpeakType speakType = _SpeakType.one;
@override
void initState() {
if (widget.speakType != null) {
speakType = _SpeakType.init(widget.speakType!);
}
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
"禁言时间:",
style: TextStyle(
fontSize: 16,
),
),
InkWell(
onTap: () {
Pickers.showSinglePicker(
pickerStyle: ComponentCommon.pickerStyle(),
context,
data: _informTypeList(),
selectData: speakType.label,
onConfirm: (label, position) {
speakType = _SpeakType.init(label);
widget.onChange(speakType.value);
setState(() {});
},
);
},
child: _showResult(
speakType.label,
),
),
],
);
}
// 显示结果
static _showResult(String label) {
return Row(
children: [
Text(
label,
style: const TextStyle(
fontSize: 16,
),
),
const SizedBox(width: 4),
const Icon(
Icons.arrow_forward_ios,
color: Colors.black,
size: 16,
),
],
);
}
// 举报类型
static _informTypeList() {
List<_SpeakType> typeList = _SpeakType.values;
List<String> dataList = [];
for (var element in typeList) {
dataList.add(element.label);
}
return dataList;
}
}
// 举报枚举
enum _SpeakType {
one('1', '1小时'),
two('2', '1天'),
three('3', '1周'),
four('4', '1月'),
five('5', '1年'),
six('6', '永久'),
;
const _SpeakType(this.value, this.label);
final String value;
final String label;
static _SpeakType init(String label) {
return _SpeakType.values
.firstWhere((e) => e.label == label, orElse: () => _SpeakType.one);
}
}

View File

@@ -0,0 +1,93 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:demo/views/msg/msg_forward_controller.dart';
import 'package:demo/views/msg/msg_forward_view.dart';
import 'package:demo/tools/tools_enum.dart';
// 文本组件
class ComponentText extends StatelessWidget {
const ComponentText({super.key});
@override
Widget build(BuildContext context) {
String data = Get.arguments;
// 选中文本
var text = '';
return GestureDetector(
onTap: () {
// 返回
Get.back();
},
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: SelectionArea(
child: GestureDetector(
onTap: () {
// 返回
Get.back();
},
child: Text(
data,
style: const TextStyle(fontSize: 24),
),
),
onSelectionChanged: (SelectedContent? selectContent) {
text = selectContent?.plainText ?? '';
},
contextMenuBuilder: (context, selectableRegionState) {
final List<ContextMenuButtonItem> buttonItems = [
ContextMenuButtonItem(
label: '复制',
onPressed: () {
if (text.isNotEmpty) {
Clipboard.setData(ClipboardData(text: text));
EasyLoading.showToast('复制成功');
}
},
),
ContextMenuButtonItem(
label: '全选',
onPressed: () {
selectableRegionState.selectAll(
SelectionChangedCause.toolbar,
);
},
),
ContextMenuButtonItem(
label: '转发',
onPressed: () async {
if (text.isNotEmpty) {
// 转发
dynamic result = await Get.toNamed(
MsgForwardView.routeName,
arguments: [
ForwardModel(MsgType.text, {'data': text.trim()}),
],
);
if (result != null) {
Get.back();
}
}
},
),
];
return AdaptiveTextSelectionToolbar.buttonItems(
buttonItems: buttonItems,
anchors: selectableRegionState.contextMenuAnchors,
);
},
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,79 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
// 视频组件
class ComponentVideo extends StatefulWidget {
final String path;
const ComponentVideo({super.key, required this.path});
@override
createState() => _ComponentVideoState();
}
class _ComponentVideoState extends State<ComponentVideo> {
late final player = Player();
late final controller = VideoController(player);
@override
void initState() {
super.initState();
_initVideo();
}
/*
* 初始化视频
*/
_initVideo() async {
await player.open(Media(widget.path));
}
@override
void dispose() {
player.dispose();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
}
@override
Widget build(BuildContext context) {
// 视频宽高
Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
toolbarHeight: 0,
),
body: Container(
color: Colors.black,
child: Stack(
children: [
SizedBox(
width: size.width,
height: size.height,
child: Video(controller: controller),
),
Positioned(
top: 0,
left: 10,
child: IconButton(
iconSize: 28,
icon: const Icon(Icons.close),
color: Colors.white,
onPressed: () {
Get.back();
},
),
),
],
),
),
);
}
}

139
lib/config/app_config.dart Normal file
View File

@@ -0,0 +1,139 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get_storage/get_storage.dart';
import 'package:demo/config/app_theme.dart';
import 'package:media_kit/media_kit.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
// 总配置
class AppConfig {
// 以下为配置文件读取出来
static final navigatorKey = GlobalKey<NavigatorState>();
// 在线客服
static const String robotId = '10001';
// 视频大小
static const int videoSize = 100;
// 请求隐私协议
static const String privacyHost = 'https://baidu.com';
// 请求服务协议
static const String serviceHost = 'https://baidu.com';
// 数据库
static const String dbName = 'demo—im.db';
// 设备类型
static final String device = Platform.operatingSystem;
// 项目名称
static late final String appName;
// 版本号码
static late final String version;
// 是否打开
static bool open = true;
// 超时时间
static Duration timeout = const Duration(seconds: 5);
// 密码文本
static const String passText = '密码长度为6-16位可以使用字母、数字和特殊字符';
// 初始化
static init() async {
// 全局异常
await _loadException();
// 媒体库
MediaKit.ensureInitialized();
// 全局存储
await GetStorage.init();
// 禁止横屏
await _loadPortrait();
// 读取app配置
await _loadPackage();
// 生命周期
await _loadAppLifecycle();
}
// 拦截异常
static _loadException() {
FlutterError.onError = (details) {
// 错误
String error = details.exception.toString();
// 处理
error = error.replaceFirst('Exception: ', '');
if ('' == error) {
return;
}
EasyLoading.showToast(error);
};
}
// 禁止横屏
static _loadPortrait() async {
// 禁止横屏
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
}
// 读取app配置
static _loadPackage() async {
final packageInfo = await PackageInfo.fromPlatform();
appName = packageInfo.appName;
version = packageInfo.version;
}
// 生命周期
static _loadAppLifecycle() {
SystemChannels.lifecycle.setMessageHandler((handler) async {
if (AppLifecycleState.resumed.toString() == handler) {
debugPrint('打开app');
// 是否打开
AppConfig.open = true;
} else if (AppLifecycleState.paused.toString() == handler) {
debugPrint('关闭app');
// 是否打开
AppConfig.open = false;
}
return handler;
});
}
// 下拉刷新全局配置
static refreshConfig({required Widget child}) {
return RefreshConfiguration(
// 配置默认头部指示器
headerBuilder: () => const ClassicHeader(
idleText: "下拉刷新",
refreshingText: "刷新中...",
completeText: "刷新成功",
releaseText: "松开立即刷新",
failedText: '刷新失败',
),
// 配置默认底部指示器
footerBuilder: () => const ClassicFooter(
idleText: "上拉加载",
loadingText: "加载中…",
canLoadingText: "松手开始加载数据",
failedText: "加载失败",
noDataText: "没有更多数据了",
),
// 头部触发刷新的越界距离
headerTriggerDistance: 60.0,
// 底部触发刷新的越界距离,距离底部多少开始刷新
footerTriggerDistance: 0,
// 头部最大可以拖动的范围,如果发生冲出视图范围区域,请设置这个属性
maxOverScrollExtent: 100,
// 这个属性不兼容PageView和TabBarView,如果你特别需要TabBarView左右滑动,你需要把它设置为true
enableScrollWhenRefreshCompleted: false,
// 在加载失败的状态下,用户仍然可以通过手势上拉来触发加载更多
enableLoadingWhenFailed: true,
enableBallisticRefresh: true,
// Viewport不满一屏时,禁用上拉加载更多功能
hideFooterWhenNotFull: false,
// 可以通过惯性滑动触发加载更多
enableBallisticLoad: false,
// 子包
child: child,
);
}
// 主题
static final ThemeData theme = AppTheme.theme;
}

Some files were not shown because too many files have changed in this diff Show More