├── .gitignore
├── .vscode
└── settings.json
├── README.md
├── android
├── .project
├── .settings
│ └── org.eclipse.buildship.core.prefs
├── app
│ ├── .classpath
│ ├── .project
│ ├── .settings
│ │ └── org.eclipse.buildship.core.prefs
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── wing_chat
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── emoji
├── [NO].png
├── [OK].png
├── [乒乓].png
├── [亲亲].png
├── [便便].png
├── [偷笑].png
├── [傲慢].png
├── [再见].png
├── [冷汗].png
├── [凋谢].png
├── [刀].png
├── [勾引].png
├── [发呆].png
├── [发怒].png
├── [可怜].png
├── [右哼哼].png
├── [吐].png
├── [吓].png
├── [呲牙].png
├── [咒骂].png
├── [咖啡].png
├── [哈欠].png
├── [啤酒].png
├── [嘘].png
├── [嘴唇].png
├── [困].png
├── [坏笑].png
├── [大哭].png
├── [太阳].png
├── [奋斗].png
├── [委屈].png
├── [害羞].png
├── [尴尬].png
├── [左哼哼].png
├── [差劲].png
├── [弱].png
├── [强].png
├── [得意].png
├── [微笑].png
├── [心碎].png
├── [快哭了].png
├── [悠闲].png
├── [惊恐].png
├── [惊讶].png
├── [愉快].png
├── [憨笑].png
├── [抓狂].png
├── [抠鼻].png
├── [抱拳].png
├── [拥抱].png
├── [拳头].png
├── [握手].png
├── [撇嘴].png
├── [擦汗].png
├── [敲打].png
├── [晕].png
├── [月亮].png
├── [流汗].png
├── [流泪].png
├── [炸弹].png
├── [爱你].png
├── [爱心].png
├── [猪头].png
├── [玫瑰].png
├── [瓢虫].png
├── [疑问].png
├── [疯了].png
├── [白眼].png
├── [睡].png
├── [礼物].png
├── [篮球].png
├── [糗大了].png
├── [胜利].png
├── [色].png
├── [菜刀].png
├── [蛋糕].png
├── [衰].png
├── [西瓜].png
├── [调皮].png
├── [足球].png
├── [鄙视].png
├── [酷].png
├── [闪电].png
├── [闭嘴].png
├── [阴险].png
├── [难过].png
├── [饥饿].png
├── [饭].png
├── [骷髅].png
└── [鼓掌].png
├── images
├── badge.png
├── chat_emoji.png
├── chat_funcs.png
├── dog.jpg
├── icon_friends_add.png
├── icon_right.png
├── tabbar_chat.png
├── tabbar_chat_hl.png
├── tabbar_discover.png
├── tabbar_discover_hl.png
├── tabbar_friends.png
├── tabbar_friends_hl.png
├── tabbar_mine.png
├── tabbar_mine_hl.png
├── 五角星b.png
├── 五角星w.png
├── 公众号.png
├── 发起群聊.png
├── 圆加.png
├── 小程序.png
├── 微信 支付.png
├── 微信卡包.png
├── 微信收藏.png
├── 微信相册.png
├── 微信表情.png
├── 微信设置.png
├── 扫一扫.png
├── 扫一扫1.png
├── 扫一扫2.png
├── 搜一搜 2.png
├── 搜一搜.png
├── 搜一搜2.png
├── 摇一摇.png
├── 收付款.png
├── 放大镜b.png
├── 放大镜w.png
├── 新的朋友.png
├── 朋友圈.png
├── 标星.png
├── 标签.png
├── 气泡.png
├── 添加朋友.png
├── 游戏.png
├── 游戏2.png
├── 相机.png
├── 看一看icon.png
├── 群聊.png
├── 购物.png
└── 附近的人icon.png
├── ios
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── flutter_export_environment.sh
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── main.dart
├── provider
│ ├── group_chat_provider.dart
│ ├── group_list_provider.dart
│ ├── jmessage_manager_provider.dart
│ ├── root_scene_provider.dart
│ └── single_chat_provider.dart
├── tools
│ ├── app_screen.dart
│ ├── app_toast.dart
│ ├── emoji_text.dart
│ ├── expanded_viewport.dart
│ ├── sp_util.dart
│ └── special_text_span_builder.dart
└── views
│ ├── chat
│ ├── group_chat_scene.dart
│ └── single_chat_scene.dart
│ ├── discover
│ ├── discover_cell.dart
│ ├── discover_child_page.dart
│ └── discover_scene.dart
│ ├── friends
│ ├── friends_data.dart
│ ├── friends_page_cell.dart
│ ├── friends_scene.dart
│ └── index_bar.dart
│ ├── login_scene.dart
│ ├── message
│ └── message_list_scene.dart
│ ├── mine
│ └── mine_page.dart
│ └── root_scene.dart
├── pubspec.yaml
├── show_images
├── 会话列表.jpg
├── 群聊.jpg
└── 表情.jpg
└── test
└── widget_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | .dart_tool/
26 | .flutter-plugins
27 | .packages
28 | .pub-cache/
29 | .pub/
30 | /build/
31 |
32 | # Android related
33 | **/android/**/gradle-wrapper.jar
34 | **/android/.gradle
35 | **/android/captures/
36 | **/android/gradlew
37 | **/android/gradlew.bat
38 | **/android/local.properties
39 | **/android/**/GeneratedPluginRegistrant.java
40 |
41 | # iOS/XCode related
42 | **/ios/**/*.mode1v3
43 | **/ios/**/*.mode2v3
44 | **/ios/**/*.moved-aside
45 | **/ios/**/*.pbxuser
46 | **/ios/**/*.perspectivev3
47 | **/ios/**/*sync/
48 | **/ios/**/.sconsign.dblite
49 | **/ios/**/.tags*
50 | **/ios/**/.vagrant/
51 | **/ios/**/DerivedData/
52 | **/ios/**/Icon?
53 | **/ios/**/Pods/
54 | **/ios/**/.symlinks/
55 | **/ios/**/profile
56 | **/ios/**/xcuserdata
57 | **/ios/.generated/
58 | **/ios/Flutter/App.framework
59 | **/ios/Flutter/Flutter.framework
60 | **/ios/Flutter/Generated.xcconfig
61 | **/ios/Flutter/app.flx
62 | **/ios/Flutter/app.zip
63 | **/ios/Flutter/flutter_assets/
64 | **/ios/ServiceDefinitions.json
65 | **/ios/Runner/GeneratedPluginRegistrant.*
66 |
67 | # Exceptions to above rules.
68 | !**/ios/**/default.mode1v3
69 | !**/ios/**/default.mode2v3
70 | !**/ios/**/default.pbxuser
71 | !**/ios/**/default.perspectivev3
72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
73 | pubspec.lock
74 | android/key.properties
75 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "java.configuration.updateBuildConfiguration": "interactive"
3 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # wing_chat
2 | 极光IM插件开发的即时通讯demo,有聊天界面,包含有文字、图片、表情,可帮助初学者更快切入im开发。demo功能还不完善,期待大家提出宝贵意见!如果可以希望大家给个star
3 |
4 | 
5 | 
6 | 
7 |
--------------------------------------------------------------------------------
/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | android
4 | Project android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/android/app/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app
4 | Project app created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/android/app/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=..
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | // def keystorePropertiesFile = rootProject.file("key.properties")
29 | // def keystoreProperties = new Properties()
30 | // keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
31 |
32 | android {
33 | compileSdkVersion 28
34 |
35 | sourceSets {
36 | main.java.srcDirs += 'src/main/kotlin'
37 | }
38 |
39 | lintOptions {
40 | disable 'InvalidPackage'
41 | }
42 |
43 | defaultConfig {
44 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
45 | applicationId "com.example.wing_chat"
46 | minSdkVersion 16
47 | targetSdkVersion 28
48 | versionCode flutterVersionCode.toInteger()
49 | versionName flutterVersionName
50 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
51 |
52 | ndk {
53 | //选择要添加的对应cpu类型的.so库。
54 | abiFilters 'armeabi', 'armeabi-v7a','arm64-v8a'
55 | }
56 |
57 | manifestPlaceholders = [
58 | JPUSH_PKGNAME : applicationId,
59 | JPUSH_APPKEY : "65e831cf441e2df70442995a", //JPush上注册的包名对应的appkey.
60 | JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
61 | ]
62 | }
63 |
64 | buildTypes {
65 | release {
66 | // TODO: Add your own signing config for the release build.
67 | // Signing with the debug keys for now, so `flutter run --release` works.
68 | signingConfig signingConfigs.debug
69 | }
70 | }
71 | }
72 |
73 | flutter {
74 | source '../..'
75 | }
76 |
77 | dependencies {
78 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
79 | testImplementation 'junit:junit:4.12'
80 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
81 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
82 | }
83 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
13 |
20 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/wing_chat/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.wing_chat
2 |
3 | import android.os.Bundle
4 |
5 | import io.flutter.app.FlutterActivity
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity: FlutterActivity() {
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | GeneratedPluginRegistrant.registerWith(this)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.2.71'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.2.1'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
3 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/emoji/[NO].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[NO].png
--------------------------------------------------------------------------------
/emoji/[OK].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[OK].png
--------------------------------------------------------------------------------
/emoji/[乒乓].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[乒乓].png
--------------------------------------------------------------------------------
/emoji/[亲亲].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[亲亲].png
--------------------------------------------------------------------------------
/emoji/[便便].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[便便].png
--------------------------------------------------------------------------------
/emoji/[偷笑].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[偷笑].png
--------------------------------------------------------------------------------
/emoji/[傲慢].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[傲慢].png
--------------------------------------------------------------------------------
/emoji/[再见].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[再见].png
--------------------------------------------------------------------------------
/emoji/[冷汗].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[冷汗].png
--------------------------------------------------------------------------------
/emoji/[凋谢].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[凋谢].png
--------------------------------------------------------------------------------
/emoji/[刀].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[刀].png
--------------------------------------------------------------------------------
/emoji/[勾引].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[勾引].png
--------------------------------------------------------------------------------
/emoji/[发呆].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[发呆].png
--------------------------------------------------------------------------------
/emoji/[发怒].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[发怒].png
--------------------------------------------------------------------------------
/emoji/[可怜].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[可怜].png
--------------------------------------------------------------------------------
/emoji/[右哼哼].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[右哼哼].png
--------------------------------------------------------------------------------
/emoji/[吐].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[吐].png
--------------------------------------------------------------------------------
/emoji/[吓].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[吓].png
--------------------------------------------------------------------------------
/emoji/[呲牙].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[呲牙].png
--------------------------------------------------------------------------------
/emoji/[咒骂].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[咒骂].png
--------------------------------------------------------------------------------
/emoji/[咖啡].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[咖啡].png
--------------------------------------------------------------------------------
/emoji/[哈欠].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[哈欠].png
--------------------------------------------------------------------------------
/emoji/[啤酒].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[啤酒].png
--------------------------------------------------------------------------------
/emoji/[嘘].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[嘘].png
--------------------------------------------------------------------------------
/emoji/[嘴唇].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[嘴唇].png
--------------------------------------------------------------------------------
/emoji/[困].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[困].png
--------------------------------------------------------------------------------
/emoji/[坏笑].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[坏笑].png
--------------------------------------------------------------------------------
/emoji/[大哭].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[大哭].png
--------------------------------------------------------------------------------
/emoji/[太阳].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[太阳].png
--------------------------------------------------------------------------------
/emoji/[奋斗].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[奋斗].png
--------------------------------------------------------------------------------
/emoji/[委屈].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[委屈].png
--------------------------------------------------------------------------------
/emoji/[害羞].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[害羞].png
--------------------------------------------------------------------------------
/emoji/[尴尬].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[尴尬].png
--------------------------------------------------------------------------------
/emoji/[左哼哼].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[左哼哼].png
--------------------------------------------------------------------------------
/emoji/[差劲].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[差劲].png
--------------------------------------------------------------------------------
/emoji/[弱].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[弱].png
--------------------------------------------------------------------------------
/emoji/[强].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[强].png
--------------------------------------------------------------------------------
/emoji/[得意].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[得意].png
--------------------------------------------------------------------------------
/emoji/[微笑].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[微笑].png
--------------------------------------------------------------------------------
/emoji/[心碎].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[心碎].png
--------------------------------------------------------------------------------
/emoji/[快哭了].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[快哭了].png
--------------------------------------------------------------------------------
/emoji/[悠闲].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[悠闲].png
--------------------------------------------------------------------------------
/emoji/[惊恐].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[惊恐].png
--------------------------------------------------------------------------------
/emoji/[惊讶].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[惊讶].png
--------------------------------------------------------------------------------
/emoji/[愉快].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[愉快].png
--------------------------------------------------------------------------------
/emoji/[憨笑].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[憨笑].png
--------------------------------------------------------------------------------
/emoji/[抓狂].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[抓狂].png
--------------------------------------------------------------------------------
/emoji/[抠鼻].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[抠鼻].png
--------------------------------------------------------------------------------
/emoji/[抱拳].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[抱拳].png
--------------------------------------------------------------------------------
/emoji/[拥抱].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[拥抱].png
--------------------------------------------------------------------------------
/emoji/[拳头].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[拳头].png
--------------------------------------------------------------------------------
/emoji/[握手].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[握手].png
--------------------------------------------------------------------------------
/emoji/[撇嘴].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[撇嘴].png
--------------------------------------------------------------------------------
/emoji/[擦汗].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[擦汗].png
--------------------------------------------------------------------------------
/emoji/[敲打].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[敲打].png
--------------------------------------------------------------------------------
/emoji/[晕].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[晕].png
--------------------------------------------------------------------------------
/emoji/[月亮].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[月亮].png
--------------------------------------------------------------------------------
/emoji/[流汗].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[流汗].png
--------------------------------------------------------------------------------
/emoji/[流泪].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[流泪].png
--------------------------------------------------------------------------------
/emoji/[炸弹].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[炸弹].png
--------------------------------------------------------------------------------
/emoji/[爱你].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[爱你].png
--------------------------------------------------------------------------------
/emoji/[爱心].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[爱心].png
--------------------------------------------------------------------------------
/emoji/[猪头].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[猪头].png
--------------------------------------------------------------------------------
/emoji/[玫瑰].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[玫瑰].png
--------------------------------------------------------------------------------
/emoji/[瓢虫].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[瓢虫].png
--------------------------------------------------------------------------------
/emoji/[疑问].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[疑问].png
--------------------------------------------------------------------------------
/emoji/[疯了].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[疯了].png
--------------------------------------------------------------------------------
/emoji/[白眼].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[白眼].png
--------------------------------------------------------------------------------
/emoji/[睡].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[睡].png
--------------------------------------------------------------------------------
/emoji/[礼物].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[礼物].png
--------------------------------------------------------------------------------
/emoji/[篮球].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[篮球].png
--------------------------------------------------------------------------------
/emoji/[糗大了].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[糗大了].png
--------------------------------------------------------------------------------
/emoji/[胜利].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[胜利].png
--------------------------------------------------------------------------------
/emoji/[色].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[色].png
--------------------------------------------------------------------------------
/emoji/[菜刀].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[菜刀].png
--------------------------------------------------------------------------------
/emoji/[蛋糕].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[蛋糕].png
--------------------------------------------------------------------------------
/emoji/[衰].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[衰].png
--------------------------------------------------------------------------------
/emoji/[西瓜].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[西瓜].png
--------------------------------------------------------------------------------
/emoji/[调皮].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[调皮].png
--------------------------------------------------------------------------------
/emoji/[足球].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[足球].png
--------------------------------------------------------------------------------
/emoji/[鄙视].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[鄙视].png
--------------------------------------------------------------------------------
/emoji/[酷].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[酷].png
--------------------------------------------------------------------------------
/emoji/[闪电].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[闪电].png
--------------------------------------------------------------------------------
/emoji/[闭嘴].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[闭嘴].png
--------------------------------------------------------------------------------
/emoji/[阴险].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[阴险].png
--------------------------------------------------------------------------------
/emoji/[难过].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[难过].png
--------------------------------------------------------------------------------
/emoji/[饥饿].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[饥饿].png
--------------------------------------------------------------------------------
/emoji/[饭].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[饭].png
--------------------------------------------------------------------------------
/emoji/[骷髅].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[骷髅].png
--------------------------------------------------------------------------------
/emoji/[鼓掌].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/emoji/[鼓掌].png
--------------------------------------------------------------------------------
/images/badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/badge.png
--------------------------------------------------------------------------------
/images/chat_emoji.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/chat_emoji.png
--------------------------------------------------------------------------------
/images/chat_funcs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/chat_funcs.png
--------------------------------------------------------------------------------
/images/dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/dog.jpg
--------------------------------------------------------------------------------
/images/icon_friends_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/icon_friends_add.png
--------------------------------------------------------------------------------
/images/icon_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/icon_right.png
--------------------------------------------------------------------------------
/images/tabbar_chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/tabbar_chat.png
--------------------------------------------------------------------------------
/images/tabbar_chat_hl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/tabbar_chat_hl.png
--------------------------------------------------------------------------------
/images/tabbar_discover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/tabbar_discover.png
--------------------------------------------------------------------------------
/images/tabbar_discover_hl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/tabbar_discover_hl.png
--------------------------------------------------------------------------------
/images/tabbar_friends.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/tabbar_friends.png
--------------------------------------------------------------------------------
/images/tabbar_friends_hl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/tabbar_friends_hl.png
--------------------------------------------------------------------------------
/images/tabbar_mine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/tabbar_mine.png
--------------------------------------------------------------------------------
/images/tabbar_mine_hl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/tabbar_mine_hl.png
--------------------------------------------------------------------------------
/images/五角星b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/五角星b.png
--------------------------------------------------------------------------------
/images/五角星w.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/五角星w.png
--------------------------------------------------------------------------------
/images/公众号.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/公众号.png
--------------------------------------------------------------------------------
/images/发起群聊.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/发起群聊.png
--------------------------------------------------------------------------------
/images/圆加.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/圆加.png
--------------------------------------------------------------------------------
/images/小程序.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/小程序.png
--------------------------------------------------------------------------------
/images/微信 支付.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/微信 支付.png
--------------------------------------------------------------------------------
/images/微信卡包.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/微信卡包.png
--------------------------------------------------------------------------------
/images/微信收藏.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/微信收藏.png
--------------------------------------------------------------------------------
/images/微信相册.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/微信相册.png
--------------------------------------------------------------------------------
/images/微信表情.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/微信表情.png
--------------------------------------------------------------------------------
/images/微信设置.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/微信设置.png
--------------------------------------------------------------------------------
/images/扫一扫.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/扫一扫.png
--------------------------------------------------------------------------------
/images/扫一扫1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/扫一扫1.png
--------------------------------------------------------------------------------
/images/扫一扫2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/扫一扫2.png
--------------------------------------------------------------------------------
/images/搜一搜 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/搜一搜 2.png
--------------------------------------------------------------------------------
/images/搜一搜.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/搜一搜.png
--------------------------------------------------------------------------------
/images/搜一搜2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/搜一搜2.png
--------------------------------------------------------------------------------
/images/摇一摇.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/摇一摇.png
--------------------------------------------------------------------------------
/images/收付款.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/收付款.png
--------------------------------------------------------------------------------
/images/放大镜b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/放大镜b.png
--------------------------------------------------------------------------------
/images/放大镜w.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/放大镜w.png
--------------------------------------------------------------------------------
/images/新的朋友.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/新的朋友.png
--------------------------------------------------------------------------------
/images/朋友圈.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/朋友圈.png
--------------------------------------------------------------------------------
/images/标星.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/标星.png
--------------------------------------------------------------------------------
/images/标签.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/标签.png
--------------------------------------------------------------------------------
/images/气泡.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/气泡.png
--------------------------------------------------------------------------------
/images/添加朋友.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/添加朋友.png
--------------------------------------------------------------------------------
/images/游戏.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/游戏.png
--------------------------------------------------------------------------------
/images/游戏2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/游戏2.png
--------------------------------------------------------------------------------
/images/相机.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/相机.png
--------------------------------------------------------------------------------
/images/看一看icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/看一看icon.png
--------------------------------------------------------------------------------
/images/群聊.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/群聊.png
--------------------------------------------------------------------------------
/images/购物.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/购物.png
--------------------------------------------------------------------------------
/images/附近的人icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/images/附近的人icon.png
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/flutter_export_environment.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # This is a generated file; do not edit or check into version control.
3 | export "FLUTTER_ROOT=/Users/shell/flutter"
4 | export "FLUTTER_APPLICATION_PATH=/Users/shell/Desktop/FlutterProject/wing_chat"
5 | export "FLUTTER_TARGET=/Users/shell/Desktop/FlutterProject/wing_chat/lib/main.dart"
6 | export "FLUTTER_BUILD_DIR=build"
7 | export "SYMROOT=${SOURCE_ROOT}/../build/ios"
8 | export "FLUTTER_FRAMEWORK_DIR=/Users/shell/flutter/bin/cache/artifacts/engine/ios"
9 | export "FLUTTER_BUILD_NAME=1.0.0"
10 | export "FLUTTER_BUILD_NUMBER=1"
11 | export "TRACK_WIDGET_CREATION=true"
12 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Using a CDN with CocoaPods 1.7.2 or later can save a lot of time on pod installation, but it's experimental rather than the default.
2 | # source 'https://cdn.cocoapods.org/'
3 |
4 | # Uncomment this line to define a global platform for your project
5 | # platform :ios, '9.0'
6 |
7 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
8 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
9 |
10 | project 'Runner', {
11 | 'Debug' => :debug,
12 | 'Profile' => :release,
13 | 'Release' => :release,
14 | }
15 |
16 | def parse_KV_file(file, separator='=')
17 | file_abs_path = File.expand_path(file)
18 | if !File.exists? file_abs_path
19 | return [];
20 | end
21 | pods_ary = []
22 | skip_line_start_symbols = ["#", "/"]
23 | File.foreach(file_abs_path) { |line|
24 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
25 | plugin = line.split(pattern=separator)
26 | if plugin.length == 2
27 | podname = plugin[0].strip()
28 | path = plugin[1].strip()
29 | podpath = File.expand_path("#{path}", file_abs_path)
30 | pods_ary.push({:name => podname, :path => podpath});
31 | else
32 | puts "Invalid plugin specification: #{line}"
33 | end
34 | }
35 | return pods_ary
36 | end
37 |
38 | target 'Runner' do
39 | use_frameworks!
40 |
41 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
42 | # referring to absolute paths on developers' machines.
43 | system('rm -rf .symlinks')
44 | system('mkdir -p .symlinks/plugins')
45 |
46 | # Flutter Pods
47 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
48 | if generated_xcode_build_settings.empty?
49 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
50 | end
51 | generated_xcode_build_settings.map { |p|
52 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
53 | symlink = File.join('.symlinks', 'flutter')
54 | File.symlink(File.dirname(p[:path]), symlink)
55 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
56 | end
57 | }
58 |
59 | # Plugin Pods
60 | plugin_pods = parse_KV_file('../.flutter-plugins')
61 | plugin_pods.map { |p|
62 | symlink = File.join('.symlinks', 'plugins', p[:name])
63 | File.symlink(p[:path], symlink)
64 | pod p[:name], :path => File.join(symlink, 'ios')
65 | }
66 | end
67 |
68 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
69 | install! 'cocoapods', :disable_input_output_paths => true
70 |
71 | post_install do |installer|
72 | installer.pods_project.targets.each do |target|
73 | target.build_configurations.each do |config|
74 | config.build_settings['ENABLE_BITCODE'] = 'NO'
75 | end
76 | end
77 | end
78 |
--------------------------------------------------------------------------------
/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - fluttertoast (0.0.2):
4 | - Flutter
5 | - image_picker (0.0.1):
6 | - Flutter
7 | - JCore (2.1.1)
8 | - JMessage (3.9.1):
9 | - JCore (< 3.0.0, >= 2.0.0)
10 | - jmessage_flutter (0.0.1):
11 | - Flutter
12 | - JMessage
13 | - path_provider (0.0.1):
14 | - Flutter
15 | - shared_preferences (0.0.1):
16 | - Flutter
17 |
18 | DEPENDENCIES:
19 | - Flutter (from `.symlinks/flutter/ios`)
20 | - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
21 | - image_picker (from `.symlinks/plugins/image_picker/ios`)
22 | - jmessage_flutter (from `.symlinks/plugins/jmessage_flutter/ios`)
23 | - path_provider (from `.symlinks/plugins/path_provider/ios`)
24 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
25 |
26 | SPEC REPOS:
27 | https://github.com/CocoaPods/Specs.git:
28 | - JCore
29 | - JMessage
30 |
31 | EXTERNAL SOURCES:
32 | Flutter:
33 | :path: ".symlinks/flutter/ios"
34 | fluttertoast:
35 | :path: ".symlinks/plugins/fluttertoast/ios"
36 | image_picker:
37 | :path: ".symlinks/plugins/image_picker/ios"
38 | jmessage_flutter:
39 | :path: ".symlinks/plugins/jmessage_flutter/ios"
40 | path_provider:
41 | :path: ".symlinks/plugins/path_provider/ios"
42 | shared_preferences:
43 | :path: ".symlinks/plugins/shared_preferences/ios"
44 |
45 | SPEC CHECKSUMS:
46 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
47 | fluttertoast: b644586ef3b16f67fae9a1f8754cef6b2d6b634b
48 | image_picker: e3eacd46b94694dde7cf2705955cece853aa1a8f
49 | JCore: 4072327557f0b83cc22dd4041f2f839740c0077b
50 | JMessage: 43dfcd5348573b2f4f24357b12e9b19076322606
51 | jmessage_flutter: eb7c42cb2444efae6aa14c2083dc84929ca3c80a
52 | path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
53 | shared_preferences: 430726339841afefe5142b9c1f50cb6bd7793e01
54 |
55 | PODFILE CHECKSUM: 10ae9c18d12c9ffc2275c9a159a3b1e281990db0
56 |
57 | COCOAPODS: 1.8.4
58 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShellPeng/wing_chat/581ba0e4766d9686de4d91938f0d7de23c5dc5da/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | 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.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | zh_CN
7 | CFBundleDisplayName
8 | 星光呓语
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | wing_chat
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSAllowsArbitraryLoads
30 |
31 |
32 | NSCameraUsageDescription
33 | WingChat想使用您的相机,用于拍摄照片
34 | NSPhotoLibraryAddUsageDescription
35 | WingChat想访问您的相册,用于保存照片
36 | NSPhotoLibraryUsageDescription
37 | WingChat想使用您的相册,用于获取相册照片
38 | UILaunchStoryboardName
39 | LaunchScreen
40 | UIMainStoryboardFile
41 | Main
42 | UISupportedInterfaceOrientations
43 |
44 | UIInterfaceOrientationPortrait
45 |
46 | UISupportedInterfaceOrientations~ipad
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationPortraitUpsideDown
50 | UIInterfaceOrientationLandscapeLeft
51 | UIInterfaceOrientationLandscapeRight
52 |
53 | UIViewControllerBasedStatusBarAppearance
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'package:provider/provider.dart';
4 | import 'package:wing_chat/provider/jmessage_manager_provider.dart';
5 | import 'package:wing_chat/views/login_scene.dart';
6 | import 'tools/sp_util.dart';
7 |
8 | final ThemeColor = Color.fromRGBO(237, 237, 237, 1.0);
9 |
10 | void main(){
11 | SystemChrome.setPreferredOrientations(
12 | [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
13 | .then((_) async {
14 | /// 等待sp初始化完成后再运行app。
15 | /// sp初始化时间 release模式下30ms左右,debug模式下100多ms。
16 | await SpUtil.getInstance();
17 | runApp(MultiProvider(providers: [
18 | ChangeNotifierProvider(
19 | create: (_) => JMessageManagerProvider()..initPushMessage())
20 | ], child: MaterialApp(
21 | // supportedLocales: [Locale('zh', ''), Locale('en', '')],
22 | title: '星光呓语',
23 | debugShowCheckedModeBanner: false,
24 | theme: ThemeData(primaryColor: Colors.white),
25 | home: LoginPage(),
26 | )));
27 |
28 | // if (Platform.isAndroid) {
29 | SystemChrome.setSystemUIOverlayStyle(
30 | SystemUiOverlayStyle(statusBarColor: Colors.transparent));
31 | // } else {
32 | });
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/lib/provider/group_chat_provider.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:math';
3 | import 'package:extended_image/extended_image.dart';
4 | import 'package:extended_text/extended_text.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:image_picker/image_picker.dart';
7 | import 'package:jmessage_flutter/jmessage_flutter.dart';
8 | import 'package:pull_to_refresh/pull_to_refresh.dart';
9 | import 'package:wing_chat/tools/special_text_span_builder.dart';
10 | import 'jmessage_manager_provider.dart';
11 |
12 | class GroupChatProvider with ChangeNotifier {
13 | bool isLoading = false;
14 | bool _talkFOT = false;
15 | bool _emojiOpen = false;
16 | double _keyboardHeight = 275.0;
17 |
18 | BuildContext context;
19 | FocusNode fsNode = FocusNode();
20 | TextEditingController textInputController = TextEditingController();
21 | ScrollController scrollController = ScrollController();
22 | RefreshController controller = RefreshController();
23 | PPSpecialTextSpanBuilder mySpecialTextSpanBuilder =
24 | PPSpecialTextSpanBuilder(type: BuilderType.extendedText);
25 |
26 | /// 聊天内容列表
27 | List _chatWidgetChildren = [];
28 |
29 | /// 聊天内容缓存列表
30 | List _chatHistory = [];
31 |
32 | // UserInfoModel mySelf = UserInfoModel.fromJson(SpUtil.getObject("UserInfo"));
33 |
34 | JMGroup kGroup;
35 | JMGroupInfo kGroupInfo;
36 | JMConversationInfo kGroupConver;
37 |
38 | bool get talkFOT => _talkFOT;
39 | bool get emojiOpen => _emojiOpen;
40 | double get keyboardHeight => _keyboardHeight;
41 |
42 | /// 聊天内容列表
43 | List get chatWidgetChildren => _chatWidgetChildren;
44 |
45 | /// 总消息数
46 | int totalMsgCount = 0;
47 | double extraHeight = 0;
48 |
49 | set talkFOT(value) {
50 | _talkFOT = value;
51 | notifyListeners();
52 | }
53 |
54 | set emojiOpen(value) {
55 | fsNode.unfocus();
56 | _emojiOpen = value;
57 | notifyListeners();
58 | }
59 |
60 | set keyboardHeight(value) {
61 | _keyboardHeight = max(_keyboardHeight, value);
62 | // notifyListeners();
63 | }
64 |
65 | reloadInputView() {
66 | notifyListeners();
67 | }
68 |
69 | List emojiArray = [
70 | '[微笑]',
71 | '[撇嘴]',
72 | '[色]',
73 | '[发呆]',
74 | '[得意]',
75 | '[流泪]',
76 | '[害羞]',
77 | '[闭嘴]',
78 | '[睡]',
79 | '[大哭]',
80 | '[尴尬]',
81 | '[发怒]',
82 | '[调皮]',
83 | '[呲牙]',
84 | '[惊讶]',
85 | '[难过]',
86 | '[酷]',
87 | '[冷汗]',
88 | '[抓狂]',
89 | '[吐]',
90 | '[偷笑]',
91 | '[愉快]',
92 | '[白眼]',
93 | '[傲慢]',
94 | '[饥饿]',
95 | '[困]',
96 | '[惊恐]',
97 | '[流汗]',
98 | '[憨笑]',
99 | '[悠闲]',
100 | '[奋斗]',
101 | '[咒骂]',
102 | '[疑问]',
103 | '[嘘]',
104 | '[晕]',
105 | '[疯了]',
106 | '[衰]',
107 | '[骷髅]',
108 | '[敲打]',
109 | '[再见]',
110 | '[擦汗]',
111 | '[抠鼻]',
112 | '[鼓掌]',
113 | '[糗大了]',
114 | '[坏笑]',
115 | '[左哼哼]',
116 | '[右哼哼]',
117 | '[哈欠]',
118 | '[鄙视]',
119 | '[委屈]',
120 | '[快哭了]',
121 | '[阴险]',
122 | '[亲亲]',
123 | '[吓]',
124 | '[可怜]',
125 | '[菜刀]',
126 | '[西瓜]',
127 | '[啤酒]',
128 | '[篮球]',
129 | '[乒乓]',
130 | '[咖啡]',
131 | '[饭]',
132 | '[猪头]',
133 | '[玫瑰]',
134 | '[凋谢]',
135 | '[嘴唇]',
136 | '[爱心]',
137 | '[心碎]',
138 | '[蛋糕]',
139 | '[闪电]',
140 | '[炸弹]',
141 | '[刀]',
142 | '[足球]',
143 | '[瓢虫]',
144 | '[便便]',
145 | '[月亮]',
146 | '[太阳]',
147 | '[礼物]',
148 | '[拥抱]',
149 | '[强]',
150 | '[弱]',
151 | '[握手]',
152 | '[胜利]',
153 | '[抱拳]',
154 | '[勾引]',
155 | '[拳头]',
156 | '[差劲]',
157 | '[爱你]',
158 | '[NO]',
159 | '[OK]',
160 | ];
161 |
162 | /// 初始化数据
163 | initConversation() {
164 | kGroup = JMGroup.fromJson(
165 | {'type': JMGroupType.private, 'groupId': kGroupInfo.id});
166 | _createGroupConversation();
167 | }
168 |
169 | /// 创建会话
170 | _createGroupConversation() async {
171 | kGroupConver = await JMessage.createConversation(target: kGroup);
172 |
173 | JMessage.resetUnreadMessageCount(target: kGroup);
174 |
175 | await JMessage.enterConversation(target: kGroup);
176 | JMessage.addReceiveMessageListener((msg) async {
177 | print('消息监听++++++++++++++++++++++++++++++++++++++++');
178 | isLoading = false;
179 | if (kGroupConver.isMyMessage(msg)) {
180 | _parseMessage(msg, false);
181 | }
182 | });
183 | getHistoryMessages();
184 | }
185 |
186 | /// 获取历史消息
187 | getHistoryMessages() async {
188 | isLoading = true;
189 | var _historyList = await kGroupConver.getHistoryMessages(
190 | from: totalMsgCount, limit: 20, isDescend: true);
191 | if (_historyList == null) {
192 | // PPToast.show('没有更多历史消息');
193 | controller.loadNoData();
194 | } else {
195 | totalMsgCount += _historyList.length;
196 | _historyList.forEach((message) {
197 | _parseMessage(message, true);
198 | });
199 | }
200 | }
201 |
202 | /// 解析消息发送方
203 | JMUserInfo _parseOptUser(message, bool isHistory) {
204 | JMUserInfo optUser;
205 |
206 | if (message.target is JMGroupInfo) {
207 | optUser = message.from;
208 | } else if (message.target is JMUserInfo) {
209 | optUser = message.target;
210 | } else {}
211 |
212 | return optUser;
213 | }
214 |
215 | /// 消息解析
216 | _insertMsgToHistory(PPMessageModel messageModel, bool isHistory) {
217 | if (isHistory) {
218 | _chatHistory.insert(0, messageModel);
219 | } else {
220 | _chatHistory.add(messageModel);
221 | }
222 | _refreshMessageList(isHistory);
223 | }
224 |
225 | /// 消息解析
226 | _parseMessage(msg, bool isHistory) {
227 | if (msg is JMTextMessage) {
228 | JMTextMessage textMessage = JMTextMessage.fromJson(msg.toJson());
229 | JMUserInfo user = _parseOptUser(msg, isHistory);
230 |
231 | PPMessageModel msgModel = PPMessageModel()
232 | ..nickname = user.nickname
233 | ..userId = user.username
234 | ..avatar = user.extras['avatar']
235 | ..text = textMessage.text
236 | ..message = textMessage
237 | ..messageType = JMMessageType.text;
238 |
239 | _insertMsgToHistory(msgModel, isHistory);
240 | } else if (msg is JMImageMessage) {
241 | JMImageMessage imageMessage = JMImageMessage.fromJson(msg.toJson());
242 | JMUserInfo user = _parseOptUser(msg, isHistory);
243 |
244 | File imagefile = File('${imageMessage.thumbPath}');
245 |
246 | PPMessageModel msgModel = PPMessageModel()
247 | ..nickname = user.nickname
248 | ..userId = user.username
249 | ..avatar = user.extras['avatar']
250 | ..imageFile = imagefile
251 | ..message = imageMessage
252 | ..messageType = JMMessageType.image;
253 |
254 | _insertMsgToHistory(msgModel, isHistory);
255 | }
256 | }
257 |
258 | sendTextMessage(content) {
259 | kGroupConver.sendTextMessage(text: content).then((msg) {
260 | if (content != '' && content != null) {
261 | // _sendMessageContent(content, 'text');
262 | _parseMessage(msg, false);
263 | totalMsgCount += 1;
264 | textInputController.clear();
265 | notifyListeners();
266 | }
267 | }).catchError((error) {});
268 | }
269 |
270 | _refreshMessageList(bool isHistory) {
271 | List widgetList = [];
272 | for (var i = 0; i < _chatHistory.length; i++) {
273 | widgetList.add(_layoutMessageCell(_chatHistory[i]));
274 | }
275 | // _chatWidgetChildren = widgetList;
276 | _chatWidgetChildren = widgetList.reversed.toList();
277 | controller.loadComplete();
278 | notifyListeners();
279 | JMessage.resetUnreadMessageCount(target: kGroup);
280 |
281 | if (!isHistory) {
282 | scrollController.animateTo(
283 | 0.0,
284 | curve: Curves.linear,
285 | duration: const Duration(milliseconds: 300),
286 | );
287 | }
288 | }
289 |
290 | void sendImageMessage() async {
291 | var image = await ImagePicker.pickImage(source: ImageSource.gallery);
292 | if (image != null) {
293 | kGroupConver.sendImageMessage(path: image.path).then((msg) async {
294 | _parseMessage(msg, false);
295 | totalMsgCount += 1;
296 | }).catchError((error) {});
297 | }
298 | }
299 |
300 | /// 根据消息类型加载消息内容
301 | _messageContentType(PPMessageModel msgModel, String otherId) {
302 | switch (msgModel.messageType) {
303 | case JMMessageType.image:
304 | return InkWell(
305 | onTap: () {
306 | JMessage
307 | .downloadOriginalImage(
308 | messageId: Platform.isAndroid
309 | ? msgModel.message.serverMessageId
310 | : msgModel.message.id,
311 | target: kGroup)
312 | .then((result) {
313 | if (result.isNotEmpty) {
314 | showDialog(
315 | context: context,
316 | builder: (context) {
317 | return GestureDetector(
318 | onTap: (){
319 | Navigator.pop(context);
320 | },
321 | child: Container(
322 | width: double.infinity,
323 | height: double.infinity,
324 | color: Colors.black,
325 | child: ExtendedImage.file(
326 | File(result['filePath']), fit: BoxFit.contain,
327 | //enableLoadState: false,
328 | mode: ExtendedImageMode.gesture,
329 | onDoubleTap: (tap){
330 | Navigator.pop(context);
331 | },
332 | initGestureConfigHandler: (state) {
333 | return GestureConfig(
334 | minScale: 0.9,
335 | animationMinScale: 0.7,
336 | maxScale: 3.0,
337 | animationMaxScale: 3.5,
338 | speed: 1.0,
339 | inertialSpeed: 100.0,
340 | initialScale: 1.0,
341 | inPageView: false);
342 | },
343 | ),
344 | ),
345 | );
346 | });
347 | }
348 | }).catchError((error) {
349 | print("下载出错:${error.toString()}");
350 | });
351 | },
352 | child: Image.file(
353 | msgModel.imageFile,
354 | height: 200 * 9 / 16.0,
355 | fit: BoxFit.fitWidth,
356 | ),
357 | );
358 | break;
359 | case JMMessageType.text:
360 | return ExtendedText(
361 | msgModel.text,
362 | style: TextStyle(
363 | color: msgModel.message.isSend ? Colors.white : Colors.black),
364 | specialTextSpanBuilder: mySpecialTextSpanBuilder,
365 | );
366 | break;
367 | default:
368 | break;
369 | }
370 | }
371 |
372 | _layoutMessageCell(PPMessageModel msgModel) {
373 | List widgetList = [];
374 | var msgPadding;
375 | var msgMargin;
376 | var msgColor;
377 |
378 | if (msgModel.message.isSend) {
379 | msgMargin = EdgeInsets.only(right: 10, top: 10);
380 | msgColor = Colors.lightBlue;
381 | } else {
382 | msgMargin = EdgeInsets.only(left: 10, top: 10);
383 | msgColor = Colors.white;
384 | }
385 |
386 | if (msgModel.messageType == JMMessageType.image) {
387 | msgPadding = EdgeInsets.all(0);
388 | msgColor = Colors.transparent;
389 | } else {
390 | msgPadding = EdgeInsets.all(10.0);
391 | }
392 |
393 | Widget userAvatar = CircleAvatar(
394 | radius: 25,
395 | backgroundImage: NetworkImage('${msgModel.avatar}'),
396 | );
397 |
398 | Widget msgContent = Container(
399 | margin: msgMargin,
400 | padding: msgPadding,
401 | decoration: BoxDecoration(
402 | color: msgColor, borderRadius: BorderRadius.circular(10.0)),
403 | child: LimitedBox(
404 | maxWidth: MediaQuery.of(context).size.width - 120.0,
405 | child: _messageContentType(msgModel, msgModel.userId),
406 | ));
407 |
408 | if (msgModel.message.isSend) {
409 | widgetList = [msgContent, userAvatar];
410 | } else {
411 | widgetList = [userAvatar, msgContent];
412 | }
413 |
414 | return Container(
415 | width: MediaQuery.of(context).size.width - 120.0,
416 | margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20),
417 | child: Row(
418 | mainAxisAlignment: msgModel.message.isSend
419 | ? MainAxisAlignment.end
420 | : MainAxisAlignment.start,
421 | crossAxisAlignment: CrossAxisAlignment.start,
422 | children: widgetList));
423 | }
424 |
425 | @override
426 | void dispose() {
427 | super.dispose();
428 | controller.dispose();
429 | JMessage.exitConversation(target: kGroup);
430 | JMessage.removeReceiveMessageListener((message) {});
431 | }
432 | }
433 |
434 | class PPMessageModel {
435 | String nickname;
436 | String userId;
437 | String avatar;
438 | String text;
439 | File imageFile;
440 | JMNormalMessage message;
441 | JMMessageType messageType;
442 |
443 | PPMessageModel(
444 | {this.nickname,
445 | this.userId,
446 | this.avatar,
447 | this.text,
448 | this.imageFile,
449 | this.message,
450 | this.messageType});
451 | }
452 |
--------------------------------------------------------------------------------
/lib/provider/group_list_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:jmessage_flutter/jmessage_flutter.dart';
3 | import 'package:wing_chat/tools/sp_util.dart';
4 |
5 | import 'jmessage_manager_provider.dart';
6 |
7 |
8 | class GroupListProvider with ChangeNotifier {
9 | List _groupList = [];
10 |
11 | List get groupList => _groupList;
12 |
13 | // List _groupIdArray = [];
14 | // List get groupIdArray => _groupIdArray;
15 |
16 | int _unreadCount = 0;
17 |
18 | int get unreadCount => _unreadCount;
19 |
20 |
21 | set unreadCount(value){
22 | _unreadCount = value;
23 | notifyListeners();
24 | }
25 |
26 |
27 | // set groupIdArray(value){
28 | // _groupIdArray = value;
29 | // getConversationList();
30 | // }
31 |
32 | loginStatusCheck() async {
33 | // var userModel = UserInfoModel.fromJson(SpUtil.getObject("UserInfo"));
34 | JMessage
35 | .login(username: SpUtil.getString('jUserName'), password: SpUtil.getString('jPassword'))
36 | .then((userInfo) {
37 | print(userInfo);
38 | receiveMessageListener();
39 | receiveApplyJoinGroupApprovalListener();
40 | getConversationList();
41 | // getMyGroup();
42 | }).catchError((error) {
43 | // PPToast.show('用户群聊登录失败!');
44 | print(error);
45 | });
46 | }
47 |
48 | receiveMessageListener() async {
49 | JMessage.addReceiveMessageListener((msg) {
50 | if (msg is JMEventMessage) {
51 | // getMyGroup();
52 | }else{
53 | getConversationList();
54 | }
55 | });
56 | }
57 | /// 监听入群申请
58 | receiveApplyJoinGroupApprovalListener() async {
59 | JMessage.addReceiveApplyJoinGroupApprovalListener((event){
60 | JMessage.processApplyJoinGroup(events: [event.eventId],isAgree: true,reason: '同意', isRespondInviter: false).then((result){
61 |
62 | }).catchError((error){
63 |
64 | });
65 | });
66 | }
67 |
68 | // getMyGroup() {
69 | // jmessage.getGroupIds().then((groupIds) {
70 | // groupIdArray = groupIds;
71 | // }).catchError((error) {});
72 | // }
73 |
74 | getConversationList() async {
75 | print("************************");
76 |
77 | JMessage.getConversations().then((allConversations) {
78 | print("************************");
79 | print(allConversations);
80 |
81 | _groupList = allConversations;
82 | if (_groupList == null) {
83 | _groupList = [];
84 | } else {
85 | int unreadNum = 0;
86 | _groupList.removeWhere((conversation) {
87 | unreadNum += conversation.unreadCount;
88 | return false;
89 | // if (conversation.conversationType == JMConversationType.group) {
90 | // var groupInfo = JMGroupInfo.fromJson(conversation.target.toJson());
91 | // if (_groupIdArray.contains(groupInfo.id)) {
92 | // unreadNum += conversation.unreadCount;
93 | // return false;
94 | // } else {
95 | // jmessage.deleteConversation(
96 | // target: JMGroup.fromJson(
97 | // {'type': JMGroupType.private, 'groupId': groupInfo.id}));
98 | // return true;
99 | // }
100 | // } else {
101 | // return true;
102 | // }
103 | });
104 | unreadCount = unreadNum;
105 | notifyListeners();
106 | }
107 | }).catchError((error) {
108 | print(error);
109 | loginStatusCheck();
110 | });
111 | notifyListeners();
112 |
113 | }
114 |
115 | @override
116 | void dispose() {
117 | super.dispose();
118 | // jmessage.removeReceiveMessageListener((message){});
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/lib/provider/jmessage_manager_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'package:jmessage_flutter/jmessage_flutter.dart';
4 | import 'package:platform/platform.dart';
5 |
6 | MethodChannel channel = MethodChannel('jmessage_flutter');
7 | JmessageFlutter JMessage = JmessageFlutter();
8 |
9 | typedef LoginCallback = void Function(bool isSuccess);
10 |
11 | class JMessageManagerProvider with ChangeNotifier {
12 | // final JPush jpush = JPush();
13 |
14 | initPushMessage() async {
15 | // jpush.getRegistrationID().then((rid) {});
16 |
17 | // jpush.setup(
18 | // appKey: "",
19 | // channel: "dev",
20 | // production: false,
21 | // debug: true,
22 | // );
23 |
24 | // jpush.applyPushAuthority(NotificationSettingsIOS(sound: true, alert: true, badge: true));
25 |
26 | // try {
27 | // jpush.addEventHandler(
28 | // onReceiveNotification: (Map message) async {
29 | // print("flutter onReceiveNotification: $message");
30 | // },
31 | // onOpenNotification: (Map message) async {
32 | // print("flutter onOpenNotification: $message");
33 | // },
34 | // onReceiveMessage: (Map message) async {
35 | // print("flutter onReceiveMessage: $message");
36 | // },
37 | // );
38 | // } on PlatformException {
39 | // // platformVersion = 'Failed to get platform version.';
40 | // }
41 |
42 | JMessage.setDebugMode(enable: true);
43 | JMessage.init(
44 | isOpenMessageRoaming: true, appkey: '65e831cf441e2df70442995a',channel: 'test');
45 | JMessage.applyPushAuthority(
46 | JMNotificationSettingsIOS(sound: true, alert: true, badge: true));
47 | }
48 |
49 | juserLogin(LoginCallback callback, String jUserName, String jUserPWD) async {
50 | // await jmessage.login(
51 | // username: jUserName, password: jUserPWD);
52 | // return loginResult(callback);
53 | JMessage.login(username: jUserName, password: jUserPWD).then((jUser) {
54 | callback(jUser != null);
55 | }).catchError((error) {});
56 | }
57 |
58 | loginResult(LoginCallback callback) async {
59 | JMUserInfo user = await JMessage.getMyInfo();
60 | print(user.toJson());
61 | return callback(user != null);
62 | }
63 |
64 | loginStatusChanged() async {
65 | JMessage.addLoginStateChangedListener((JMLoginStateChangedType type) {
66 | print('flutter receive event receive login state change $type');
67 | switch (type) {
68 | case JMLoginStateChangedType.user_login_status_unexpected:
69 | break;
70 | case JMLoginStateChangedType.user_disabled:
71 | break;
72 | case JMLoginStateChangedType.user_logout:
73 | break;
74 | default:
75 | }
76 | });
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/lib/provider/root_scene_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class RootSceneProvider with ChangeNotifier {
4 | int _currentIndex = 0;
5 | int get currentIndex => _currentIndex;
6 |
7 | set currentIndex(value) {
8 | _currentIndex = value;
9 | notifyListeners();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/lib/provider/single_chat_provider.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:math';
3 | import 'package:extended_image/extended_image.dart';
4 | import 'package:extended_text/extended_text.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:image_picker/image_picker.dart';
7 | import 'package:jmessage_flutter/jmessage_flutter.dart';
8 | import 'package:pull_to_refresh/pull_to_refresh.dart';
9 | import 'package:wing_chat/tools/special_text_span_builder.dart';
10 | import 'jmessage_manager_provider.dart';
11 |
12 | class SingleChatProvider with ChangeNotifier {
13 | bool isLoading = false;
14 | bool _talkFOT = false;
15 | bool _emojiOpen = false;
16 | double _keyboardHeight = 275.0;
17 |
18 | BuildContext context;
19 | FocusNode fsNode = FocusNode();
20 | TextEditingController textInputController = TextEditingController();
21 | ScrollController scrollController = ScrollController();
22 | RefreshController controller = RefreshController();
23 | PPSpecialTextSpanBuilder mySpecialTextSpanBuilder =
24 | PPSpecialTextSpanBuilder(type: BuilderType.extendedText);
25 |
26 | /// 聊天内容列表
27 | List _chatWidgetChildren = [];
28 |
29 | /// 聊天内容缓存列表
30 | List _chatHistory = [];
31 |
32 | // UserInfoModel mySelf = UserInfoModel.fromJson(SpUtil.getObject("UserInfo"));
33 |
34 | JMSingle jmSingle;
35 | JMUserInfo jmUserInfo;
36 | JMConversationInfo jSingleConver;
37 |
38 | bool get talkFOT => _talkFOT;
39 | bool get emojiOpen => _emojiOpen;
40 | double get keyboardHeight => _keyboardHeight;
41 |
42 | /// 聊天内容列表
43 | List get chatWidgetChildren => _chatWidgetChildren;
44 |
45 | /// 总消息数
46 | int totalMsgCount = 0;
47 | double extraHeight = 0;
48 |
49 | set talkFOT(value) {
50 | _talkFOT = value;
51 | notifyListeners();
52 | }
53 |
54 | set emojiOpen(value) {
55 | fsNode.unfocus();
56 | _emojiOpen = value;
57 | notifyListeners();
58 | }
59 |
60 | set keyboardHeight(value) {
61 | _keyboardHeight = max(_keyboardHeight, value);
62 | // notifyListeners();
63 | }
64 |
65 | reloadInputView() {
66 | notifyListeners();
67 | }
68 |
69 | List emojiArray = [
70 | '[微笑]',
71 | '[撇嘴]',
72 | '[色]',
73 | '[发呆]',
74 | '[得意]',
75 | '[流泪]',
76 | '[害羞]',
77 | '[闭嘴]',
78 | '[睡]',
79 | '[大哭]',
80 | '[尴尬]',
81 | '[发怒]',
82 | '[调皮]',
83 | '[呲牙]',
84 | '[惊讶]',
85 | '[难过]',
86 | '[酷]',
87 | '[冷汗]',
88 | '[抓狂]',
89 | '[吐]',
90 | '[偷笑]',
91 | '[愉快]',
92 | '[白眼]',
93 | '[傲慢]',
94 | '[饥饿]',
95 | '[困]',
96 | '[惊恐]',
97 | '[流汗]',
98 | '[憨笑]',
99 | '[悠闲]',
100 | '[奋斗]',
101 | '[咒骂]',
102 | '[疑问]',
103 | '[嘘]',
104 | '[晕]',
105 | '[疯了]',
106 | '[衰]',
107 | '[骷髅]',
108 | '[敲打]',
109 | '[再见]',
110 | '[擦汗]',
111 | '[抠鼻]',
112 | '[鼓掌]',
113 | '[糗大了]',
114 | '[坏笑]',
115 | '[左哼哼]',
116 | '[右哼哼]',
117 | '[哈欠]',
118 | '[鄙视]',
119 | '[委屈]',
120 | '[快哭了]',
121 | '[阴险]',
122 | '[亲亲]',
123 | '[吓]',
124 | '[可怜]',
125 | '[菜刀]',
126 | '[西瓜]',
127 | '[啤酒]',
128 | '[篮球]',
129 | '[乒乓]',
130 | '[咖啡]',
131 | '[饭]',
132 | '[猪头]',
133 | '[玫瑰]',
134 | '[凋谢]',
135 | '[嘴唇]',
136 | '[爱心]',
137 | '[心碎]',
138 | '[蛋糕]',
139 | '[闪电]',
140 | '[炸弹]',
141 | '[刀]',
142 | '[足球]',
143 | '[瓢虫]',
144 | '[便便]',
145 | '[月亮]',
146 | '[太阳]',
147 | '[礼物]',
148 | '[拥抱]',
149 | '[强]',
150 | '[弱]',
151 | '[握手]',
152 | '[胜利]',
153 | '[抱拳]',
154 | '[勾引]',
155 | '[拳头]',
156 | '[差劲]',
157 | '[爱你]',
158 | '[NO]',
159 | '[OK]',
160 | ];
161 |
162 | /// 初始化数据
163 | initConversation() {
164 | jmSingle = JMSingle.fromJson({
165 | "username": jmUserInfo.username,
166 | "appKey": '65e831cf441e2df70442995a'
167 | });
168 | _createGroupConversation();
169 | }
170 |
171 | /// 创建会话
172 | _createGroupConversation() async {
173 | jSingleConver = await JMessage.createConversation(target: jmSingle);
174 |
175 | JMessage.resetUnreadMessageCount(target: jmSingle);
176 |
177 | await JMessage.enterConversation(target: jmSingle);
178 | JMessage.addReceiveMessageListener((msg) async {
179 | print('消息监听++++++++++++++++++++++++++++++++++++++++');
180 | isLoading = false;
181 | if (jSingleConver.isMyMessage(msg)) {
182 | _parseMessage(msg, false);
183 | }
184 | });
185 | getHistoryMessages();
186 | }
187 |
188 | /// 获取历史消息
189 | getHistoryMessages() async {
190 | isLoading = true;
191 | var _historyList = await jSingleConver.getHistoryMessages(
192 | from: totalMsgCount, limit: 20, isDescend: true);
193 | if (_historyList == null) {
194 | // PPToast.show('没有更多历史消息');
195 | controller.loadNoData();
196 | } else {
197 | totalMsgCount += _historyList.length;
198 | _historyList.forEach((message) {
199 | _parseMessage(message, true);
200 | });
201 | }
202 | }
203 |
204 | /// 解析消息发送方
205 | JMUserInfo _parseOptUser(message, bool isHistory) {
206 | JMUserInfo optUser;
207 |
208 | if (message.target is JMGroupInfo) {
209 | optUser = message.from;
210 | } else if (message.target is JMUserInfo) {
211 | optUser = message.target;
212 | } else {}
213 |
214 | return optUser;
215 | }
216 |
217 | /// 消息解析
218 | _insertMsgToHistory(PPMessageModel messageModel, bool isHistory) {
219 | if (isHistory) {
220 | _chatHistory.insert(0, messageModel);
221 | } else {
222 | _chatHistory.add(messageModel);
223 | }
224 | _refreshMessageList(isHistory);
225 | }
226 |
227 | /// 消息解析
228 | _parseMessage(msg, bool isHistory) {
229 | if (msg is JMTextMessage) {
230 | JMTextMessage textMessage = JMTextMessage.fromJson(msg.toJson());
231 | JMUserInfo user = _parseOptUser(msg, isHistory);
232 |
233 | PPMessageModel msgModel = PPMessageModel()
234 | ..nickname = user.nickname
235 | ..userId = user.username
236 | ..avatar = user.extras['avatar']
237 | ..text = textMessage.text
238 | ..message = textMessage
239 | ..messageType = JMMessageType.text;
240 |
241 | _insertMsgToHistory(msgModel, isHistory);
242 | } else if (msg is JMImageMessage) {
243 | JMImageMessage imageMessage = JMImageMessage.fromJson(msg.toJson());
244 | JMUserInfo user = _parseOptUser(msg, isHistory);
245 |
246 | File imagefile = File('${imageMessage.thumbPath}');
247 |
248 | PPMessageModel msgModel = PPMessageModel()
249 | ..nickname = user.nickname
250 | ..userId = user.username
251 | ..avatar = user.extras['avatar']
252 | ..imageFile = imagefile
253 | ..message = imageMessage
254 | ..messageType = JMMessageType.image;
255 |
256 | _insertMsgToHistory(msgModel, isHistory);
257 | }
258 | }
259 |
260 | sendTextMessage(content) {
261 | jSingleConver.sendTextMessage(text: content).then((msg) {
262 | if (content != '' && content != null) {
263 | // _sendMessageContent(content, 'text');
264 | _parseMessage(msg, false);
265 | totalMsgCount += 1;
266 | textInputController.clear();
267 | notifyListeners();
268 | }
269 | }).catchError((error) {});
270 | }
271 |
272 | _refreshMessageList(bool isHistory) {
273 | List widgetList = [];
274 | for (var i = 0; i < _chatHistory.length; i++) {
275 | widgetList.add(_layoutMessageCell(_chatHistory[i]));
276 | }
277 | // _chatWidgetChildren = widgetList;
278 | _chatWidgetChildren = widgetList.reversed.toList();
279 | controller.loadComplete();
280 | notifyListeners();
281 | JMessage.resetUnreadMessageCount(target: jmSingle);
282 |
283 | if (!isHistory) {
284 | scrollController.animateTo(
285 | 0.0,
286 | curve: Curves.linear,
287 | duration: const Duration(milliseconds: 300),
288 | );
289 | }
290 | }
291 |
292 | void sendImageMessage() async {
293 | var image = await ImagePicker.pickImage(source: ImageSource.gallery);
294 | if (image != null) {
295 | jSingleConver.sendImageMessage(path: image.path).then((msg) async {
296 | _parseMessage(msg, false);
297 | totalMsgCount += 1;
298 | }).catchError((error) {});
299 | }
300 | }
301 |
302 | /// 根据消息类型加载消息内容
303 | _messageContentType(PPMessageModel msgModel, String otherId) {
304 | switch (msgModel.messageType) {
305 | case JMMessageType.image:
306 | return InkWell(
307 | onTap: () {
308 | JMessage
309 | .downloadOriginalImage(
310 | messageId: Platform.isAndroid
311 | ? msgModel.message.serverMessageId
312 | : msgModel.message.id,
313 | target: jmSingle)
314 | .then((result) {
315 | if (result.isNotEmpty) {
316 | showDialog(
317 | context: context,
318 | builder: (context) {
319 | return GestureDetector(
320 | onTap: (){
321 | Navigator.pop(context);
322 | },
323 | child: Container(
324 | width: double.infinity,
325 | height: double.infinity,
326 | color: Colors.black,
327 | child: ExtendedImage.file(
328 | File(result['filePath']), fit: BoxFit.contain,
329 | //enableLoadState: false,
330 | mode: ExtendedImageMode.gesture,
331 | onDoubleTap: (tap){
332 | Navigator.pop(context);
333 | },
334 | initGestureConfigHandler: (state) {
335 | return GestureConfig(
336 | minScale: 0.9,
337 | animationMinScale: 0.7,
338 | maxScale: 3.0,
339 | animationMaxScale: 3.5,
340 | speed: 1.0,
341 | inertialSpeed: 100.0,
342 | initialScale: 1.0,
343 | inPageView: false);
344 | },
345 | ),
346 | ),
347 | );
348 | });
349 | }
350 | }).catchError((error) {
351 | print("下载出错:${error.toString()}");
352 | });
353 | },
354 | child: Image.file(
355 | msgModel.imageFile,
356 | height: 200 * 9 / 16.0,
357 | fit: BoxFit.fitWidth,
358 | ),
359 | );
360 | break;
361 | case JMMessageType.text:
362 | return ExtendedText(
363 | msgModel.text,
364 | style: TextStyle(
365 | color: msgModel.message.isSend ? Colors.white : Colors.black),
366 | specialTextSpanBuilder: mySpecialTextSpanBuilder,
367 | );
368 | break;
369 | default:
370 | break;
371 | }
372 | }
373 |
374 | _layoutMessageCell(PPMessageModel msgModel) {
375 | List widgetList = [];
376 | var msgPadding;
377 | var msgMargin;
378 | var msgColor;
379 |
380 | if (msgModel.message.isSend) {
381 | msgMargin = EdgeInsets.only(right: 10, top: 10);
382 | msgColor = Colors.lightBlue;
383 | } else {
384 | msgMargin = EdgeInsets.only(left: 10, top: 10);
385 | msgColor = Colors.white;
386 | }
387 |
388 | if (msgModel.messageType == JMMessageType.image) {
389 | msgPadding = EdgeInsets.all(0);
390 | msgColor = Colors.transparent;
391 | } else {
392 | msgPadding = EdgeInsets.all(10.0);
393 | }
394 |
395 | Widget userAvatar = CircleAvatar(
396 | radius: 25,
397 | backgroundImage: NetworkImage('${msgModel.avatar}'),
398 | );
399 |
400 | Widget msgContent = Container(
401 | margin: msgMargin,
402 | padding: msgPadding,
403 | decoration: BoxDecoration(
404 | color: msgColor, borderRadius: BorderRadius.circular(10.0)),
405 | child: LimitedBox(
406 | maxWidth: MediaQuery.of(context).size.width - 120.0,
407 | child: _messageContentType(msgModel, msgModel.userId),
408 | ));
409 |
410 | if (msgModel.message.isSend) {
411 | widgetList = [msgContent, userAvatar];
412 | } else {
413 | widgetList = [userAvatar, msgContent];
414 | }
415 |
416 | return Container(
417 | width: MediaQuery.of(context).size.width - 120.0,
418 | margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20),
419 | child: Row(
420 | mainAxisAlignment: msgModel.message.isSend
421 | ? MainAxisAlignment.end
422 | : MainAxisAlignment.start,
423 | crossAxisAlignment: CrossAxisAlignment.start,
424 | children: widgetList));
425 | }
426 |
427 | @override
428 | void dispose() {
429 | super.dispose();
430 | controller.dispose();
431 | JMessage.exitConversation(target: jmSingle);
432 | JMessage.removeReceiveMessageListener((message) {});
433 | }
434 | }
435 |
436 | class PPMessageModel {
437 | String nickname;
438 | String userId;
439 | String avatar;
440 | String text;
441 | File imageFile;
442 | JMNormalMessage message;
443 | JMMessageType messageType;
444 |
445 | PPMessageModel(
446 | {this.nickname,
447 | this.userId,
448 | this.avatar,
449 | this.text,
450 | this.imageFile,
451 | this.message,
452 | this.messageType});
453 | }
454 |
--------------------------------------------------------------------------------
/lib/tools/app_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'dart:ui' as ui show window;
4 |
5 | class Screen {
6 | static double get width {
7 | MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
8 | return mediaQuery.size.width;
9 | }
10 |
11 | static double get height {
12 | MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
13 | return mediaQuery.size.height;
14 | }
15 |
16 | static double get scale {
17 | MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
18 | return mediaQuery.devicePixelRatio;
19 | }
20 |
21 | static double get textScaleFactor {
22 | MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
23 | return mediaQuery.textScaleFactor;
24 | }
25 |
26 | static double get navigationBarHeight {
27 | MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
28 | return mediaQuery.padding.top + kToolbarHeight;
29 | }
30 |
31 | static double get topSafeHeight {
32 | MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
33 | return mediaQuery.padding.top;
34 | }
35 |
36 | static double get bottomSafeHeight {
37 | MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
38 | return mediaQuery.padding.bottom;
39 | }
40 |
41 | static updateStatusBarStyle(SystemUiOverlayStyle style) {
42 | SystemChrome.setSystemUIOverlayStyle(style);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/tools/app_toast.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:fluttertoast/fluttertoast.dart';
4 | class AppToast {
5 | static show(String msg) {
6 | Fluttertoast.showToast(msg: msg,gravity: ToastGravity.CENTER,backgroundColor: Color.fromRGBO(231, 236, 242, 1),textColor: Colors.black);
7 | }
8 | }
--------------------------------------------------------------------------------
/lib/tools/emoji_text.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:extended_text/extended_text.dart';
3 |
4 | ///emoji/image text
5 | class EmojiText extends SpecialText {
6 | static const String flag = "[";
7 | final int start;
8 | EmojiText(TextStyle textStyle, {this.start})
9 | : super(EmojiText.flag, "]", textStyle);
10 |
11 | @override
12 | InlineSpan finishText() {
13 | // TODO: implement finishText
14 | var key = toString();
15 | if (EmojiUitl.instance.emojiMap.containsKey(key)) {
16 | //fontsize id define image height
17 | //size = 30.0/26.0 * fontSize
18 | final double size = 20.0;
19 |
20 | ///fontSize 26 and text height =30.0
21 | //final double fontSize = 26.0;
22 |
23 | return ImageSpan(AssetImage(EmojiUitl.instance.emojiMap[key]),
24 | actualText: key,
25 | imageWidth: size,
26 | imageHeight: size,
27 | start: start,
28 | fit: BoxFit.fill,
29 | margin: EdgeInsets.only(left: 2.0, right: 2.0));
30 | }
31 |
32 | return TextSpan(text: toString(), style: textStyle);
33 | }
34 | }
35 |
36 | class EmojiUitl {
37 | final Map _emojiMap = new Map();
38 |
39 | Map get emojiMap => _emojiMap;
40 | List emojiArray = [
41 | '[微笑]', '[撇嘴]', '[色]', '[发呆]', '[得意]', '[流泪]', '[害羞]',
42 | '[闭嘴]', '[睡]', '[大哭]', '[尴尬]', '[发怒]', '[调皮]', '[呲牙]',
43 | '[惊讶]','[难过]','[酷]','[冷汗]','[抓狂]','[吐]','[偷笑]',
44 | '[愉快]','[白眼]','[傲慢]','[饥饿]','[困]','[惊恐]','[流汗]',
45 | '[憨笑]','[悠闲]','[奋斗]','[咒骂]','[疑问]','[嘘]','[晕]',
46 | '[疯了]','[衰]','[骷髅]','[敲打]','[再见]','[擦汗]','[抠鼻]',
47 | '[鼓掌]','[糗大了]','[坏笑]','[左哼哼]','[右哼哼]','[哈欠]','[鄙视]',
48 | '[委屈]','[快哭了]','[阴险]','[亲亲]','[吓]','[可怜]','[菜刀]',
49 | '[西瓜]','[啤酒]','[篮球]','[乒乓]','[咖啡]','[饭]','[猪头]',
50 | '[玫瑰]','[凋谢]','[嘴唇]','[爱心]','[心碎]','[蛋糕]','[闪电]',
51 | '[炸弹]','[刀]','[足球]','[瓢虫]','[便便]','[月亮]','[太阳]',
52 | '[礼物]','[拥抱]','[强]','[弱]','[握手]','[胜利]','[抱拳]',
53 | '[勾引]','[拳头]','[差劲]','[爱你]','[NO]','[OK]',
54 | ];
55 |
56 | final String _emojiFilePath = "emoji";
57 |
58 | static EmojiUitl _instance;
59 | static EmojiUitl get instance {
60 | if (_instance == null) _instance = new EmojiUitl._();
61 | return _instance;
62 | }
63 |
64 | EmojiUitl._() {
65 | for (var emojiName in emojiArray) {
66 | _emojiMap["$emojiName"] = "$_emojiFilePath/$emojiName.png";
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lib/tools/expanded_viewport.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Jpeng
3 | * Email: peng8350@gmail.com
4 | * Time: 2019-07-11 12:23
5 | */
6 | import 'package:flutter/cupertino.dart';
7 | import 'package:flutter/rendering.dart';
8 | import 'package:flutter/widgets.dart';
9 | import 'dart:math' as math;
10 |
11 | /*
12 | aim to implements expand all the free empty place when viewport is not full
13 | ,but this can not correction offset,due to _minScrollExtent,_maxScrollExtent private in RenderViewport
14 | ,no idea how to do. without doing this,chat list (top when not full && reverse = true) can not be done.
15 | in my plugin similar issue:#127,# 118
16 | in flutter similar issue:#12650,#33399,#17444
17 | */
18 |
19 | class ExpandedViewport extends Viewport {
20 | ExpandedViewport({
21 | Key key,
22 | AxisDirection axisDirection = AxisDirection.down,
23 | AxisDirection crossAxisDirection,
24 | double anchor = 0.0,
25 | ScrollPosition offset,
26 | Key center,
27 | double cacheExtent,
28 | List slivers = const [],
29 | }) : super(
30 | key: key,
31 | slivers: slivers,
32 | axisDirection: axisDirection,
33 | crossAxisDirection: crossAxisDirection,
34 | anchor: anchor,
35 | offset: offset,
36 | center: center,
37 | cacheExtent: cacheExtent);
38 |
39 | @override
40 | RenderViewport createRenderObject(BuildContext context) {
41 | // TODO: implement createRenderObject
42 | return _RenderExpandedViewport(
43 | axisDirection: axisDirection,
44 | crossAxisDirection: crossAxisDirection ??
45 | Viewport.getDefaultCrossAxisDirection(context, axisDirection),
46 | anchor: anchor,
47 | offset: offset,
48 | cacheExtent: cacheExtent,
49 | );
50 | }
51 | }
52 |
53 | class _RenderExpandedViewport extends RenderViewport {
54 | _RenderExpandedViewport({
55 | AxisDirection axisDirection = AxisDirection.down,
56 | @required AxisDirection crossAxisDirection,
57 | @required ViewportOffset offset,
58 | double anchor = 0.0,
59 | List children,
60 | RenderSliver center,
61 | double cacheExtent,
62 | }) : super(
63 | axisDirection: axisDirection,
64 | crossAxisDirection: crossAxisDirection,
65 | offset: offset,
66 | anchor: anchor,
67 | children: children,
68 | center: center,
69 | cacheExtent: cacheExtent);
70 |
71 | @override
72 | void performLayout() {
73 | // TODO: implement performLayout
74 | super.performLayout();
75 | RenderSliver expand;
76 | RenderSliver p = firstChild;
77 | double totalLayoutExtent = 0;
78 | double BehindExtent = 0.0, FrontExtent = 0.0;
79 | while (p != null) {
80 | totalLayoutExtent += p.geometry.scrollExtent;
81 | if (p is _RenderExpanded) {
82 | expand = p;
83 | FrontExtent = totalLayoutExtent;
84 | }
85 |
86 | p = childAfter(p);
87 | }
88 | double count = 0;
89 | BehindExtent = totalLayoutExtent - FrontExtent;
90 | if (expand != null && size.height > totalLayoutExtent) {
91 | _attemptLayout(expand, size.height, size.width,
92 | offset.pixels - FrontExtent - (size.height - totalLayoutExtent));
93 | }
94 | }
95 |
96 | // _minScrollExtent private in super,no setter method
97 | double _attemptLayout(RenderSliver expandPosition, double mainAxisExtent,
98 | double crossAxisExtent, double correctedOffset) {
99 | assert(!mainAxisExtent.isNaN);
100 | assert(mainAxisExtent >= 0.0);
101 | assert(crossAxisExtent.isFinite);
102 | assert(crossAxisExtent >= 0.0);
103 | assert(correctedOffset.isFinite);
104 |
105 | // centerOffset is the offset from the leading edge of the RenderViewport
106 | // to the zero scroll offset (the line between the forward slivers and the
107 | // reverse slivers).
108 | final double centerOffset = mainAxisExtent * anchor - correctedOffset;
109 | final double reverseDirectionRemainingPaintExtent =
110 | centerOffset.clamp(0.0, mainAxisExtent);
111 |
112 | final double forwardDirectionRemainingPaintExtent =
113 | (mainAxisExtent - centerOffset).clamp(0.0, mainAxisExtent);
114 | final double fullCacheExtent = mainAxisExtent + 2 * cacheExtent;
115 | final double centerCacheOffset = centerOffset + cacheExtent;
116 | final double reverseDirectionRemainingCacheExtent =
117 | centerCacheOffset.clamp(0.0, fullCacheExtent);
118 | final double forwardDirectionRemainingCacheExtent =
119 | (fullCacheExtent - centerCacheOffset).clamp(0.0, fullCacheExtent);
120 |
121 | final RenderSliver leadingNegativeChild = childBefore(center);
122 | // positive scroll offsets
123 | return layoutChildSequence(
124 | child: expandPosition,
125 | scrollOffset: math.max(0.0, -centerOffset),
126 | overlap:
127 | leadingNegativeChild == null ? math.min(0.0, -centerOffset) : 0.0,
128 | layoutOffset: centerOffset >= mainAxisExtent
129 | ? centerOffset
130 | : reverseDirectionRemainingPaintExtent,
131 | remainingPaintExtent: forwardDirectionRemainingPaintExtent,
132 | mainAxisExtent: mainAxisExtent,
133 | crossAxisExtent: crossAxisExtent,
134 | growthDirection: GrowthDirection.forward,
135 | advance: childAfter,
136 | remainingCacheExtent: forwardDirectionRemainingCacheExtent,
137 | cacheOrigin: centerOffset.clamp(-cacheExtent, 0.0),
138 | );
139 | }
140 | }
141 |
142 | //tag
143 | class SliverExpanded extends SingleChildRenderObjectWidget {
144 | SliverExpanded() : super(child: Container());
145 |
146 | @override
147 | RenderSliver createRenderObject(BuildContext context) {
148 | // TODO: implement createRenderObject
149 | return _RenderExpanded();
150 | }
151 | }
152 |
153 | class _RenderExpanded extends RenderSliver
154 | with RenderObjectWithChildMixin {
155 | @override
156 | void performLayout() {
157 | // TODO: implement performLayout
158 | geometry = SliverGeometry.zero;
159 | }
160 | }
--------------------------------------------------------------------------------
/lib/tools/sp_util.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:convert';
3 |
4 | import 'package:shared_preferences/shared_preferences.dart';
5 | import 'package:synchronized/synchronized.dart';
6 |
7 |
8 | /// SharedPreferences Util.
9 | class SpUtil {
10 | static SpUtil _singleton;
11 | static SharedPreferences _prefs;
12 | static Lock _lock = Lock();
13 |
14 | static Future getInstance() async {
15 | if (_singleton == null) {
16 | await _lock.synchronized(() async {
17 | if (_singleton == null) {
18 | // keep local instance till it is fully initialized.
19 | // 保持本地实例直到完全初始化。
20 | var singleton = SpUtil._();
21 | await singleton._init();
22 | _singleton = singleton;
23 | }
24 | });
25 | }
26 | return _singleton;
27 | }
28 |
29 | SpUtil._();
30 |
31 | Future _init() async {
32 | _prefs = await SharedPreferences.getInstance();
33 | }
34 |
35 | /// put object.
36 | static Future putObject(String key, Object value) {
37 | if (_prefs == null) return null;
38 | return _prefs.setString(key, value == null ? "" : json.encode(value));
39 | }
40 |
41 | /// get obj.
42 | static T getObj(String key, T f(Map v), {T defValue}) {
43 | Map map = getObject(key);
44 | return map == null ? defValue : f(map);
45 | }
46 |
47 | /// get object.
48 | static Map getObject(String key) {
49 | if (_prefs == null) return null;
50 | String _data = _prefs.getString(key);
51 | return (_data == null || _data.isEmpty) ? null : json.decode(_data);
52 | }
53 |
54 | /// put object list.
55 | static Future putObjectList(String key, List