Revert "add widget SliderNew"
26
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@ -1,26 +0,0 @@
|
||||
---
|
||||
name: "\U0001F41B Bug Report"
|
||||
about: Something isn't working as expected
|
||||
---
|
||||
|
||||
## Bug Report
|
||||
|
||||
**仅限中文与英文**, 其他语言的提交将直接被关闭
|
||||
|
||||
请先确认查找了已有的 issue [GitHub issues](https://github.com/apache/incubator-shardingsphere-example/issues).
|
||||
|
||||
为了更好的收录您反馈或者提交的相关pr. 请您关注您提交的问题, 我们可能需要更多的详细信息, 我们会在issue下先您收集相关信息,
|
||||
如果长时间未得到您的回复, 如果我们无法在某些环境上重现该问题, 并且您**超过7天未回复**, 我们可能会关 **闭掉issue**, 谢谢
|
||||
|
||||
|
||||
### 您当前的flutter doctor信息
|
||||
|
||||
### 预期的表现
|
||||
|
||||
### 实际的表现
|
||||
|
||||
### 预期的分析 (给出您能想到, 任何您能想到的)
|
||||
|
||||
### 重现的方式, 例如从 A界面 点击 b, 跳转到B页面, 界面出现溢出乱码等.
|
||||
|
||||
### 用于重现此问题或者可能解决以上问题的示例代码(例如github 链接代码)
|
18
.github/ISSUE_TEMPLATE/feature-request.md
vendored
@ -1,18 +0,0 @@
|
||||
---
|
||||
name: "\U0001F680 Feature Request"
|
||||
about: I have a suggestion
|
||||
---
|
||||
|
||||
## Feature Request
|
||||
|
||||
**仅限中文与英文**, 其他语言的提交将直接被关闭
|
||||
|
||||
请先确认查找了已有的 issue [GitHub issues](https://github.com/apache/incubator-shardingsphere-example/issues).
|
||||
|
||||
为了更好的收录您反馈或者提交的相关pr. 请您关注您提交的问题, 我们可能需要更多的详细信息, 我们会在issue下先您收集相关信息,
|
||||
如果长时间未得到您的回复, 如果我们无法在某些环境上重现该问题, 并且您**超过7天未回复**, 我们可能会关 **闭掉issue**, 谢谢
|
||||
|
||||
|
||||
### 您的功能需求是否与哪些问题有关?
|
||||
|
||||
### 描述您想要的功能.
|
62
.github/ISSUE_TEMPLATE/page-about.md
vendored
@ -1,62 +0,0 @@
|
||||
---
|
||||
name: "📄 Page About"
|
||||
about: something about page
|
||||
---
|
||||
|
||||
## Page About
|
||||
|
||||
**仅限中文与英文**, 其他语言的提交将直接被关闭
|
||||
|
||||
请先确认查找了已有的 issue [GitHub issues](https://github.com/apache/incubator-shardingsphere-example/issues).
|
||||
|
||||
为了更好的收录您反馈或者提交的相关pr. 请您关注您提交的问题, 我们可能需要更多的详细信息, 我们会在issue下先您收集相关信息,
|
||||
如果长时间未得到您的回复, 如果我们无法在某些环境上重现该问题, 并且您**超过7天未回复**, 我们可能会关 **闭掉issue**, 谢谢
|
||||
|
||||
|
||||
|
||||
|
||||
## 界面增加或者更新的内容概括
|
||||
|
||||
## 界面数据
|
||||
|
||||
例如:
|
||||
```
|
||||
{
|
||||
"name": "standard_for_slider",
|
||||
"screenShot": "",
|
||||
"author":"sanfan",
|
||||
"title":"slider组件",
|
||||
"email": "hanxu@qq.com",
|
||||
"desc": "slider, new Slider",
|
||||
"id": "8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096"
|
||||
}
|
||||
|
||||
```
|
||||
## Page 关联的 DEMO 信息
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
{
|
||||
"name": "intor page",
|
||||
"screenShot": "",
|
||||
"author":"sanfan",
|
||||
"title":"介绍页",
|
||||
"email": "hanxu317@qq.com",
|
||||
"desc": "desc",
|
||||
"id": "ee4feb8e_32ae_4241_9c8a_5c9e1f92b096"
|
||||
},
|
||||
{
|
||||
"name": "intor pag2e",
|
||||
"screenShot": "",
|
||||
"author":"sanfan",
|
||||
"title":"介绍页",
|
||||
"email": "hanxu317@qq.com",
|
||||
"desc": "desc",
|
||||
"id": "ee4feb8e_32ae_4241_9c8a_5c9e1f92b097"
|
||||
}
|
||||
```
|
||||
|
||||
## 引入第三方包的文件与版本号(如果有引入, 请标明)
|
||||
|
||||
|
14
.github/ISSUE_TEMPLATE/question.md
vendored
@ -1,14 +0,0 @@
|
||||
---
|
||||
name: "\U0001F914 Question"
|
||||
about: Usage question that isn't answered in docs or discussion
|
||||
---
|
||||
|
||||
## Question
|
||||
|
||||
**仅限中文与英文**, 其他语言的提交将直接被关闭
|
||||
|
||||
请先确认查找了已有的 issue [GitHub issues](https://github.com/apache/incubator-shardingsphere-example/issues).
|
||||
|
||||
为了更好的收录您反馈或者提交的相关pr. 请您关注您提交的问题, 我们可能需要更多的详细信息, 我们会在issue下先您收集相关信息,
|
||||
如果长时间未得到您的回复, 如果我们无法在某些环境上重现该问题, 并且您**超过7天未回复**, 我们可能会关 **闭掉issue**, 谢谢
|
||||
|
0
.github/issue_template.md
vendored
Normal file
1
.gitignore
vendored
@ -18,7 +18,6 @@
|
||||
.metadata
|
||||
|
||||
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
|
@ -85,4 +85,4 @@ The advantages of Flutter mainly include:
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Powered by Alibaba Auction Front-end Team<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width= 20 height=20>
|
||||
Powered by [Alibaba Auction Front-end Team](https://github.com/alibaba-paimai-frontend)<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width= 20 height=20>
|
||||
|
33
README.md
@ -1,8 +1,6 @@
|
||||
Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.md) | [中文简体](https://github.com/alibaba/flutter-go/blob/master/README.md)
|
||||
## Flutter Go
|
||||
|
||||
# test
|
||||
|
||||

|
||||
|
||||
> 帮助开发者快速上手 Flutter **Flutter Go 1.0 Android版已正式发布**
|
||||
@ -22,37 +20,17 @@ Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.
|
||||
|
||||
<img src="https://img.alicdn.com/tfs/TB19UahQQzoK1RjSZFlXXai4VXa-1500-1106.png" width="600px">
|
||||
|
||||
## 运行方式
|
||||
|
||||
- 查看一下版本号是否正确
|
||||
```dart
|
||||
flutter --version
|
||||
```
|
||||
- 运行以下命令查看是否需要安装其它依赖项来完成安装
|
||||
```dart
|
||||
flutter doctor
|
||||
```
|
||||
- 运行启动您的应用
|
||||
```dart
|
||||
flutter packages get
|
||||
flutter run
|
||||
```
|
||||
|
||||
- 如果有其他问题,请参考
|
||||
- https://flutterchina.club/setup-macos/
|
||||
- https://flutter.dev/docs/get-started/install/macos
|
||||
|
||||
## Release安装包下载地址
|
||||
|
||||
### android正式版,下载地址:
|
||||
android下载地址:
|
||||
|
||||
- 华为市场已上线,华为应用市场搜索 "Fluttergo"或者直接[点击下载](https://appstore.huawei.com/search/fluttergo)
|
||||
<img src="https://img.alicdn.com/tfs/TB1LbEYarys3KVjSZFnXXXFzpXa-378-380.jpg" width=200>
|
||||
<img src="https://img.alicdn.com/tfs/TB1ylxGTMHqK1RjSZFgXXa7JXXa-436-432.png" width="200px">
|
||||
|
||||
### iphone正式版,下载地址:
|
||||
iphone下载地址: AppStore上面进行搜索fluttego
|
||||
|
||||
- AppStore 搜索 "Fluttergo" 或者直接[点击下载](https://itunes.apple.com/cn/app/flutter-go/id1462026296?mt=8)
|
||||
<img src="https://img.alicdn.com/tfs/TB1PygPaBWD3KVjSZFsXXcqkpXa-380-376.jpg" width=200>
|
||||
<img src="https://img.alicdn.com/tfs/TB1trMgV7PoK1RjSZKbXXX1IXXa-620-1343.png" width=200> <img src="https://img.alicdn.com/tfs/TB1w_MbV7voK1RjSZFDXXXY3pXa-620-1343.png" width=200>
|
||||
|
||||
|
||||
## 基础环境
|
||||
@ -145,5 +123,6 @@ flutter优点主要包括:
|
||||
|
||||
- 大家的互相信任,尊重与支持,才是开源社区前进的动力和来源.
|
||||
|
||||
Powered by 阿里拍卖前端团队<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width=20 height=20>
|
||||
Powered by [阿里拍卖前端团队](https://github.com/alibaba-paimai-frontend)<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width=20 height=20>
|
||||
|
||||
+++++++
|
@ -51,23 +51,8 @@ android {
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
manifestPlaceholders = [
|
||||
JPUSH_PKGNAME : "com.alibaba.fluttergo",
|
||||
JPUSH_APPKEY : "62eb07d227d1f11dd7fa6239", //JPush上注册的包名对应的appkey.
|
||||
JPUSH_CHANNEL : "developer-default",
|
||||
]
|
||||
|
||||
// ndk {
|
||||
// //选择要添加的对应cpu类型的.so库。
|
||||
// abiFilters 'armeabi', 'armeabi-v7a','x86', 'x86_64', 'mips'//, 'arm64-v8a'
|
||||
// // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
@ -101,8 +86,6 @@ dependencies {
|
||||
///implementation 'com.google.firebase:firebase-perf:16.2.3'
|
||||
// 登陆
|
||||
////implementation 'com.google.firebase:firebase-auth:16.0.3'
|
||||
|
||||
|
||||
}
|
||||
//firebase
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
|
@ -1 +1 @@
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0.6","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"0.0.5","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
|
@ -7,22 +7,20 @@
|
||||
additional functionality it is fine to subclass or reimplement
|
||||
FlutterApplication and put your custom class here. -->
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.MODE_WORLD_READABLE" />
|
||||
<uses-permission android:name="android.permission.MODE_WORLD_WRITEABLE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.MODE_WORLD_READABLE"/>
|
||||
<uses-permission android:name="android.permission.MODE_WORLD_WRITEABLE"/>
|
||||
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="FlutterGo"
|
||||
android:icon="@mipmap/ic_launcher_logo"
|
||||
android:usesCleartextTraffic="true">
|
||||
android:label="fluttergo"
|
||||
android:icon="@mipmap/ic_launcher_logo">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- This keeps the window background of the activity showing
|
||||
until Flutter renders its first frame. It can be removed if
|
||||
@ -32,36 +30,9 @@
|
||||
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
|
||||
android:value="true" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
||||
<provider
|
||||
android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
|
||||
android:authorities="${applicationId}.flutter_downloader.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name="androidx.work.impl.WorkManagerInitializer"
|
||||
android:authorities="${applicationId}.workmanager-init"
|
||||
android:enabled="false"
|
||||
android:exported="false" />
|
||||
|
||||
<provider
|
||||
android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer"
|
||||
android:authorities="${applicationId}.flutter-downloader-init"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS"
|
||||
android:value="5" />
|
||||
</provider>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.6 KiB |
BIN
docs/17_02_18__11_13_2018.jpg
Normal file
After Width: | Height: | Size: 360 KiB |
BIN
docs/17_47_49__11_13_2018.jpg
Normal file
After Width: | Height: | Size: 673 KiB |
BIN
docs/20_03_01__11_13_2018.jpg
Normal file
After Width: | Height: | Size: 215 KiB |
BIN
docs/36B53C6F-98F1-452B-B45A-A93293CC6B3C.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
docs/Screenshot_20181121-170331_Samsung Notes.jpg
Normal file
After Width: | Height: | Size: 192 KiB |
@ -1,38 +0,0 @@
|
||||
# Flutter Go 共建
|
||||
|
||||
# 共建说明
|
||||
|
||||
由于 **Flutter 版本迭代速度较快**,产生的内容较多, 而我们**人力有限**无法更加全面快速的支持Flutter Go的日常维护迭代, 如果您对flutter go的共建感兴趣, 欢迎您来参与本项目的共建.
|
||||
|
||||
**凡是参与共建的成员. 我们会将您的头像与github个人地址收纳进我们的官方网站中.**
|
||||
|
||||
# 共建方式
|
||||
|
||||
1. 共建组件
|
||||
- 本次更新, 开放了 **Widget 内容收录** 的功能, 您需要通过 [goCli](https://github.com/alibaba/flutter-go/blob/master/docs/go-cli.md) 工具编写markdown代码。
|
||||
|
||||
- 然后通过 **Pull Request** 的形式将您的文章内容, api描述, 组件使用方法等加入进我们的Widget界面。
|
||||
|
||||
- 为了更好记录您的改动目的, 内容信息, 交流过程, 每一条PR都需要对应一条 **Issue**, 即提交你发现的BUG或者想加入的功能, 或者想要加入的WidgetPage(共建组件), 选择你issue在类型。
|
||||
|
||||

|
||||
|
||||
2. 提交文章和修改bug
|
||||
- 您也可以将例如**日常bug.** **未来feature**等的功能性PR, 申请提交到我们的的主仓库。
|
||||
|
||||
|
||||
# 参与共建
|
||||
我们采用 **Pull Request(简称PR)** 的方式, 进行三方共建.
|
||||
|
||||
关于如何提PR请先阅读以下文档
|
||||
|
||||
- [如何向仓库提交 Pull Request](https://github.com/alibaba/flutter-go/blob/master/docs/push-pr.md)
|
||||
- [dart 代码规范](https://github.com/alibaba/flutter-go/blob/master/Flutter_Go%20%E4%BB%A3%E7%A0%81%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md)
|
||||
- [如何使用go-cli 创建 Widget Page](https://github.com/alibaba/flutter-go/blob/master/docs/go-cli.md)
|
||||
|
||||
|
||||
|
||||
|
||||
# 贡献指南
|
||||
|
||||
此项目遵循[贡献者行为准则](https://github.com/spring-projects/spring-framework/blob/master/CODE_OF_CONDUCT.adoc)。参与此项目即表示您同意遵守其条款.
|
@ -1,84 +0,0 @@
|
||||
# GoCli 说明
|
||||
|
||||
## 安装
|
||||
|
||||
获取最新flutterGo代码分之后. 在项目下会有 **go-cli** 的文件夹.
|
||||
|
||||
首先进入该文件夹并安装go-cli所需要的依赖
|
||||
|
||||
```
|
||||
cd go-cli
|
||||
pub get
|
||||
```
|
||||
|
||||
然后使用pub global命令将文件包注册到全局
|
||||
|
||||
```
|
||||
pub global activate --source path /{your project absolute path}/flutter-go/go-cli
|
||||
|
||||
```
|
||||
|
||||
使用pub global list命令查看全局包列表 如果看到有 **goCli 1.0.0**则证明安装成功
|
||||
|
||||
```
|
||||
goCli 1.0.0 at path "/{youpath}/flutter-go/go-cli"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 固定命令
|
||||
|
||||
### goCli createPage
|
||||
|
||||
初始化并创建一个Widget详情页, 通常来说. 当我们需要在Widget Tab下. 新加入一个界面内容, 执行该条命令, 会根据您的输入, 自动在本项目中创建对应的文件夹, 并记录相关配置信息, 在创建的目录中, 您可以通过编写markdown代码, 进行文章内容的编写.
|
||||
|
||||
### goCli createDemo
|
||||
|
||||
初始化并创建一个可实例化的Widget Demo(实例块), 按照在命令行中的提示, 输入我们的相关信息, 我们会创建一个 关于demo 的文件夹. 并会得到一个唯一的 **ID**. 我们可以通过这条ID,在我们的markdown代码中, 进行直接调用.
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
```
|
||||
|
||||
### goCli build
|
||||
|
||||
将本地的界面与实例资源进行打包开成统一的独立的入口. 在拉取flutter-go的项目代码后. 需要执行当前命令. 否则会报错.
|
||||
|
||||
|
||||
### goCli watch
|
||||
|
||||
动态便宜Widget Page, 动态进行markdown => dart 代码的转换. 通常在我们编辑Widget page的index.md的时候进行文件监听. 动态生成, 进行本地热更新.
|
||||
|
||||
|
||||
|
||||
## 注意
|
||||
|
||||
- 在修改**page\_demo\_package**或者standard\_pages目录下的文件操作时. 请先执行 **goCLi watch**
|
||||
- **name**, **author** 字段必须使用英文开头, 不允许使用特殊符号. 正常的示范 name ='name_test' author = 'abcdefg';
|
||||
- 以下文件目录, 显示**不可人为修改的文件**, 凡是被**合进master主分支的代码**不允许进行任何修改.
|
||||
|
||||
```
|
||||
// demo 文件结构
|
||||
demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/
|
||||
├── .demo.json (不可人为修改)
|
||||
├── index.dart (不可人为修改)
|
||||
└── src
|
||||
└── index.dart (可修改)
|
||||
|
||||
|
||||
// widget page 文件结构
|
||||
|
||||
standard_pages/
|
||||
├── index.dart (不可人为修改)
|
||||
└── standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
├── .page.json (不可人为修改)
|
||||
├── index.dart (不可人为修改)
|
||||
└── index.md (可修改)
|
||||
```
|
||||
|
BIN
docs/jiegou.png
Normal file
After Width: | Height: | Size: 106 KiB |
@ -1,35 +0,0 @@
|
||||
# 如何为一个项目提PR
|
||||
|
||||
|
||||
## PR 的含义
|
||||
|
||||
PR的全称是 **pull request**, 可以理解成. 让开源项目拉取合并他方的请求.
|
||||
|
||||
|
||||
## pull request
|
||||
|
||||
1. 将 开源flutter go项目 fork到我们自己的仓库.
|
||||
|
||||

|
||||
|
||||
2. 将Fork的仓库 clone 到本地,进行本地修改.
|
||||
|
||||
3. 将改动push到自己的仓库中
|
||||
|
||||
|
||||
```
|
||||
git add {some change file}
|
||||
git commit ...
|
||||
git push origin {your branch}
|
||||
|
||||
```
|
||||
|
||||
|
||||
4. 登陆github, 从**自己的仓库**向**开源项目仓库** 发起 **pull request** (合并申请);
|
||||
|
||||
过程参考:
|
||||
|
||||

|
||||
|
||||
|
||||
5. 开源项目维护者会review您的 **pull request**,展开讨论或者修改, 一旦通过审核,开源项目维护者合并该分支到正式仓库然后并关闭合并申请。
|
@ -1,62 +0,0 @@
|
||||
# 如何在Widget新增界面
|
||||
|
||||
阅读文档前, 请先阅读 go-cli 文档
|
||||
|
||||
在Widget列表页, 我们设有一个组, 名叫 **Developer**, 这个分组的作用是用来展示第三方作者提交的内容. 正常情况下会显示以下内容
|
||||
|
||||
<img src="https://img.alicdn.com/tfs/TB1RCfZc1H2gK0jSZJnXXaT1FXa-798-1582.png" width='300px' />
|
||||
|
||||
|
||||
## 新建 Page
|
||||
|
||||
在项目的根目录下使用 **goCLi createPage** 固定命令, 按照命令行提示信息. 输入新建界面的相关信息
|
||||
|
||||
```
|
||||
goCli createPage
|
||||
```
|
||||
参考:
|
||||

|
||||
按照以上操作会得到以下信息输出:
|
||||
```
|
||||
{
|
||||
界面位于 : lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096
|
||||
Id : 8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096
|
||||
文件夹名称 : standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 字段注意事项
|
||||
|
||||
**name** 必须**英文开头**, 统一用小写的英文字母,数字和下划线的组合,不得包含汉字空格和特殊字符, 需要与文章内容相关
|
||||
|
||||
|
||||
**author** 可以为中文英文以及任意组合, 但是不得有歧义, 暴力, 辱骂等词汇, 否则可能会被拒绝合并
|
||||
|
||||
**desc** 相关的简要描述, 需要对添加的组件或者界面进行简要描述, 方便后期搜索引擎采集
|
||||
|
||||
**email** 创建者的邮箱
|
||||
|
||||
## 查看创建的 Page
|
||||
|
||||
为了能正确的加载出新的界面, 建议重新启动当前项目. 在**Widget -> Developer -> 本地代码**中,您可以找到您新建的界面
|
||||
|
||||
<image src='https://img.alicdn.com/tfs/TB1eNLYc7Y2gK0jSZFgXXc5OFXa-744-722.png' width='300px' />
|
||||
|
||||
|
||||
## 编辑界面
|
||||
|
||||
为了能动态的将**markdown**转化成**可识别**的内容, 需要在您项目中调用 **goCli watch**, 然后可以编辑以下位置的md文件, 更改当前文件内容, 即可动态更新我们详情页的内容.
|
||||
|
||||
```
|
||||
lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.md
|
||||
```
|
||||
|
||||
参考:
|
||||
|
||||

|
||||
|
||||
|
||||
## 引用Flutter 实例
|
||||
|
||||
如何在markdown中引用flutter widget实例请参考: [WidgetDemo](https://github.com/alibaba/flutter-go/blob/beta/go-cli/utils/tpl.md)
|
110
go-cli/Readme.md
@ -1,110 +0,0 @@
|
||||
# GoCli 使用方式
|
||||
|
||||
## 安装
|
||||
|
||||
获取最新flutterGo代码分之后. 在源文件下会有 **go-cli** 的文件.
|
||||
|
||||
首先进入该文件夹并安装go-cli所需要的依赖
|
||||
|
||||
```
|
||||
cd go-cli
|
||||
pub get
|
||||
```
|
||||
|
||||
然后使用pub global命令将文件包注册到全局
|
||||
|
||||
```
|
||||
pub global activate --source path /{your flutter go absolute path}/fluttergo/go-cli
|
||||
|
||||
```
|
||||
|
||||
使用pub global list命令查看全局包列表 如果看到有 **goCli 1.0.0**则证明安装成功
|
||||
|
||||
```
|
||||
goCli 1.0.0 at path "/{youpath}/flutter-go/go-cli"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 使用方式
|
||||
|
||||
现在支持以下几种命令
|
||||
|
||||
- createDemo 新增flutter go demo.
|
||||
- createPage 新增flutter go page.
|
||||
- watch 动态生成文档与demo相关
|
||||
- build 生成文档与demo相关
|
||||
|
||||
### createDemo
|
||||
|
||||
动态生成widget demo, 可以创建demo.以便详情页中使用
|
||||
|
||||
|
||||
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
|
||||
|
||||
[✓] 请输入新增加的demo名称? demoName
|
||||
|
||||
[✓] 请输入您的姓名(使用英文) yourName
|
||||
|
||||
[✓] 请输入您的github的email地址 yourEmail
|
||||
|
||||
[✓] 请输入您demo的描述 这是一个测试的标准demo
|
||||
|
||||
|
||||
在完成以上操作后, 可以得到这样的输出:
|
||||
|
||||
|
||||
```
|
||||
------------------
|
||||
您新增的组件信息如下
|
||||
==================
|
||||
{
|
||||
name : demoName
|
||||
author : yourName
|
||||
email : yourEmail
|
||||
desc : 这是一个测试的标准demo
|
||||
}
|
||||
==================
|
||||
[✓] Is this the config you want ? (Y/n) y
|
||||
{
|
||||
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
}
|
||||
|
||||
```
|
||||
您可以在任意详情页中, 通过以下方式调用
|
||||
|
||||
```
|
||||
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
```
|
||||
|
||||
|
||||
|
||||
### createPage
|
||||
|
||||
使用方式同上. 通过该命令可以创建标准的详情页.您可以通过修改index.md进行动态的更新您所创建的详情页.
|
||||
|
||||
目录结构为
|
||||
|
||||
```
|
||||
standard_pages/
|
||||
├── index.dart (不可人为修改)
|
||||
└── standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
├── .page.json (不可人为修改)
|
||||
├── index.dart (不可人为修改)
|
||||
└── index.md (可修改)
|
||||
```
|
||||
|
||||
### watch
|
||||
|
||||
监听并编译standard_pages与page_demo_package下的的文件改动. 动态处理demo目录与文件markdown转化等.
|
||||
|
||||
## 注意
|
||||
|
||||
- 在修改page_demo_package或者standard_pages目录下的文件操作时. 建议在flutterGo目录执行goCLi watch 开启文件动态编译
|
||||
- name, author 字段必须使用英文开头, 不允许使用特殊符号. 正常的示范 name ='name_test' author = 'abcdefg';
|
||||
- 暂时阶段demo与page,一经过创建不允许修改名称作者等信息. 凡是被收录进主分支的不允许被删除
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
import 'package:args/args.dart'; // 使用其中两个类ArgParser和ArgResults
|
||||
import 'package:args/command_runner.dart';
|
||||
import '../src/cli_command_runder.dart';
|
||||
ArgResults argResults; // 声明ArgResults类型的顶级变量,保存解析的参数结果
|
||||
|
||||
// 同时,argResults也是ArgResults的实例
|
||||
void main(List<String> args) async {
|
||||
// createDemo();
|
||||
try {
|
||||
await run(args);
|
||||
} on UsageException catch (e) {
|
||||
|
||||
print(' ');
|
||||
print(e.usage);
|
||||
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"name": "sanfan"
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
name: goCli
|
||||
description: bin_go
|
||||
|
||||
# The following defines the version and build number for your application.
|
||||
# A version number is three numbers separated by dots, like 1.2.43
|
||||
# followed by an optional build number separated by a +.
|
||||
# Both the version and the builder number may be overridden in flutter
|
||||
# build by specifying --build-name and --build-number, respectively.
|
||||
# Read more about versioning at semver.org.
|
||||
version: 1.0.0
|
||||
executables:
|
||||
goCli:
|
||||
environment:
|
||||
sdk: ">=2.1.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
args: '^1.5.1'
|
||||
dart_inquirer: '^1.0.0'
|
||||
watcher: ^0.9.7+10
|
||||
mustache: ^1.1.1
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
|
@ -1,95 +0,0 @@
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import '../../utils/util.dart';
|
||||
import '../config.dart';
|
||||
import '../exception/demo.dart';
|
||||
|
||||
|
||||
Future<List> buildDemoListJson() async {
|
||||
List<FileSystemEntity> childList = await readeDirChildren(TARGET_DEMO_DIC, false);
|
||||
List<String> demoPathList = [];
|
||||
List<Map<String, dynamic>> detailList = []; // 存放所有demo的详情的列表
|
||||
for(FileSystemEntity entity in childList) {
|
||||
//文件、目录和链接都继承自FileSystemEntity
|
||||
//FileSystemEntity.type静态函数返回值为FileSystemEntityType
|
||||
//FileSystemEntityType有三个常量:
|
||||
//Directory、FILE、LINK、NOT_FOUND
|
||||
//FileSystemEntity.isFile .isLink .isDerectory可用于判断类型
|
||||
Uri url = entity.uri;
|
||||
if (await FileSystemEntity.isDirectory(entity.path)) {
|
||||
try {
|
||||
await checkDemo(entity.path);
|
||||
demoPathList.add(entity.path);
|
||||
} on InvalidDemo catch (e) {
|
||||
print("不存在 $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String dicPath in demoPathList) {
|
||||
String target = '$dicPath/.demo.json';
|
||||
String jsonString = await readeFile(target);
|
||||
try {
|
||||
Map<String, dynamic> item = json.decode(jsonString);
|
||||
detailList.add(item);
|
||||
} catch (err) {
|
||||
print("err $err");
|
||||
throw new Exception('$dicPath');
|
||||
}
|
||||
}
|
||||
print("本次编译: 获取${detailList.length}条demo数据");
|
||||
|
||||
String demoTplString = renderDemosDart(detailList);
|
||||
|
||||
// 生成 page_demo_package/index.dart
|
||||
writeContent2Path(TARGET_DEMO_DIC, 'index.dart', demoTplString.replaceAll(new RegExp('-'), '_'));
|
||||
// 生成 page_demo_package/.demo.dart
|
||||
writeContent2Path(TARGET_DEMO_DIC, '.demo.json', json.encode(detailList));
|
||||
return Future(() => childList);
|
||||
// return ;
|
||||
}
|
||||
|
||||
String renderDemosDart(List<Map<String, dynamic>> data) {
|
||||
// 自定义前缀 避免出现数字非法字符等
|
||||
String pre = "StandardDemo";
|
||||
String head = '';
|
||||
String foot = 'var demoObjects = { \r\n';
|
||||
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
Map<String, dynamic> item = data[i];
|
||||
String demoImportName = '${item['name']}_${item['id']}';
|
||||
head += "import '${item['name']}_${item['author']}_${item['id']}/index.dart' as StandardDemo_$demoImportName;\r\n";
|
||||
|
||||
foot += " '${item['id']}': ${pre}_${demoImportName}.demoWidgets";
|
||||
|
||||
if (i != data.length - 1) {
|
||||
foot += ',\r\n';
|
||||
}
|
||||
|
||||
}
|
||||
foot += "\r\n};";
|
||||
|
||||
return head + foot;
|
||||
}
|
||||
Future<bool> checkDemo(String path) async {
|
||||
List files = [
|
||||
'index.dart',
|
||||
'.demo.json',
|
||||
'src/'
|
||||
];
|
||||
bool success = true;
|
||||
for (String name in files) {
|
||||
bool isDic = name.indexOf('/') != -1;
|
||||
bool isExist ;
|
||||
String detailPath = '$path/$name';
|
||||
if (isDic) {
|
||||
isExist = await Directory(detailPath).exists();
|
||||
} else {
|
||||
isExist = await File(detailPath).exists();
|
||||
}
|
||||
if (!isExist) {
|
||||
throw new InvalidDemo('$path$name not exit');
|
||||
}
|
||||
}
|
||||
return Future(() => true);
|
||||
}
|
@ -1,186 +0,0 @@
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'package:mustache/mustache.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import '../../utils/util.dart';
|
||||
import '../config.dart';
|
||||
import '../exception/demo.dart';
|
||||
|
||||
|
||||
String prettyJson(Map json) {
|
||||
String res = "{";
|
||||
json.forEach((k, v) {
|
||||
res += (
|
||||
"\t'$k': '$v'");
|
||||
});
|
||||
res +='}';
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Future<List> buildPageListJson() async {
|
||||
List<FileSystemEntity> childList = await readeDirChildren(TARGET_PAGE_DIC, false);
|
||||
List<String> pagePathList = [];
|
||||
List<Map<String, dynamic>> detailList = []; // 存放所有demo的详情的列表
|
||||
int errCount = 0;
|
||||
int pageCount = 0;
|
||||
for(FileSystemEntity entity in childList) {
|
||||
//文件、目录和链接都继承自FileSystemEntity
|
||||
//FileSystemEntity.type静态函数返回值为FileSystemEntityType
|
||||
//FileSystemEntityType有三个常量:
|
||||
//Directory、FILE、LINK、NOT_FOUND
|
||||
//FileSystemEntity.isFile .isLink .isDerectory可用于判断类型
|
||||
if (await FileSystemEntity.isDirectory(entity.path)) {
|
||||
pageCount++;
|
||||
try {
|
||||
await checkPage(entity.path);
|
||||
pagePathList.add(entity.path);
|
||||
} on InvalidDemo catch (e) {
|
||||
errCount++;
|
||||
print("不存在 $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String dicPath in pagePathList) {
|
||||
String target = '$dicPath/.page.json';
|
||||
String jsonString = await readeFile(target);
|
||||
try {
|
||||
Map<String, dynamic> item = json.decode(jsonString);
|
||||
detailList.add(item);
|
||||
} catch (err) {
|
||||
print("err $err");
|
||||
|
||||
throw new Exception('$dicPath');
|
||||
}
|
||||
}
|
||||
print("本次编译: 总${pageCount}个界面, 成功${detailList.length}条, 失败${errCount}条");
|
||||
|
||||
String demoTplString = renderPagesDart(detailList);
|
||||
//
|
||||
// // 生成 page_demo_package/index.dart
|
||||
writeContent2Path(TARGET_PAGE_DIC, 'index.dart', demoTplString.replaceAll(new RegExp('-'), '_'));
|
||||
// // 生成 page_demo_package/.demo.dart
|
||||
writeContent2Path(TARGET_PAGE_DIC, '.pages.json', json.encode(detailList));
|
||||
return Future(() => childList);
|
||||
// return ;
|
||||
}
|
||||
|
||||
String renderPagesDart(List<Map<String, dynamic>> data) {
|
||||
print('data>>> $data');
|
||||
var source = '''
|
||||
|
||||
{{# pages }}
|
||||
import '{{ name }}_{{ author }}_{{ id }}/index.dart' as StandardPage_{{ name }}_{{ id }};
|
||||
{{/ pages }}
|
||||
class StandardPages {
|
||||
Map<String, String> standardPages;
|
||||
Map<String, String> getPages() {
|
||||
return {
|
||||
"0": "0" {{# pages }},
|
||||
"{{ id }}" : StandardPage_{{ name }}_{{ id }}.getMd()
|
||||
{{/ pages }}
|
||||
};
|
||||
}
|
||||
List<Map<String, String>> getLocalList() {
|
||||
return [
|
||||
{}{{# pages }},
|
||||
{ "id": "{{ id }}", "name": "{{ name }}", "email": "{{ email }}", "author": "{{ author }}"}
|
||||
{{/ pages }}
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
''';
|
||||
var template = new Template(source, name: 'template-filename.html');
|
||||
|
||||
|
||||
// 自定义前缀 避免出现数字非法字符等
|
||||
Map<String, List> formatData = {
|
||||
"pages": data
|
||||
};
|
||||
|
||||
String output = template.renderString(formatData);
|
||||
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
Future<bool> checkPage(String path) async {
|
||||
List files = [
|
||||
'index.dart',
|
||||
'index.md',
|
||||
'.page.json'
|
||||
];
|
||||
for (String name in files) {
|
||||
bool isDic = name.indexOf('/') != -1;
|
||||
bool isExist ;
|
||||
String detailPath = '$path/$name';
|
||||
if (isDic) {
|
||||
isExist = await Directory(detailPath).exists();
|
||||
} else {
|
||||
isExist = await File(detailPath).exists();
|
||||
}
|
||||
if (!isExist) {
|
||||
throw new InvalidDemo('$path$name not exit');
|
||||
}
|
||||
}
|
||||
return Future(() => true);
|
||||
}
|
||||
|
||||
|
||||
Future<void> transformMd2Dart(String path) async{
|
||||
print("pathLL: $path");
|
||||
String mdContent = await readeFile(p.absolute(path,'index.md'));
|
||||
|
||||
|
||||
String result = """
|
||||
String getMd() {
|
||||
return \"\"\"
|
||||
${mdContent}\"\"\";
|
||||
|
||||
|
||||
}
|
||||
""";
|
||||
writeContent2Path(p.absolute(path), 'index.dart', result);
|
||||
return '';
|
||||
}
|
||||
//main() {
|
||||
// buildPageListJson();
|
||||
//}
|
||||
|
||||
|
||||
////
|
||||
//// Created with Android Studio.
|
||||
//// User: 三帆
|
||||
//// Date: 25/05/2019
|
||||
//// Time: 21:23
|
||||
//// email: sanfan.hx@alibaba-inc.com
|
||||
//// target: 该文件用在打包后的代码中.日常开发的时候, 获取markdown不走该目录
|
||||
////
|
||||
//import 'package:flutter/material.dart';
|
||||
//import 'page1_hanxu_172ba42f_0520_401e_b568_ba7f7f6835e4/index.dart' as page1_hanxu_172ba42f_0520_401e_b568_ba7f7f6835e4;
|
||||
//
|
||||
//
|
||||
//class StandardPages {
|
||||
// Map<String, String> standardPages;
|
||||
// Map<String, String> getPages() {
|
||||
// return {
|
||||
// 'page1_hanxu_172ba42f_0520_401e_b568_ba7f7f6835e4': page1_hanxu_172ba42f_0520_401e_b568_ba7f7f6835e4.stringMd
|
||||
// };
|
||||
// }
|
||||
//}
|
||||
|
||||
//var stringMd = """# page
|
||||
//
|
||||
//this is page markdown
|
||||
//
|
||||
//you can load demo like this
|
||||
//
|
||||
//```
|
||||
//[demo: xxxid]
|
||||
//```
|
||||
//
|
||||
//""";
|
||||
//
|
@ -1,35 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:args/command_runner.dart';
|
||||
import './version.dart';
|
||||
import './command/create_demo.dart';
|
||||
import './command/create_page.dart';
|
||||
import './command/watch_md.dart';
|
||||
import './command/build.dart';
|
||||
|
||||
|
||||
|
||||
Future<int> run(List<String> args) => _CommandRunner().run(args);
|
||||
|
||||
class _CommandRunner extends CommandRunner<int> {
|
||||
_CommandRunner() : super('goCli', 'A tool to develop flutter go projects.') {
|
||||
argParser.addFlag('version',
|
||||
negatable: false, help: 'Prints the version of goCi.');
|
||||
addCommand(CreateDemoCommand());
|
||||
addCommand(CreatePageCommand());
|
||||
addCommand(WatchCommand());
|
||||
addCommand(Build());
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> runCommand(ArgResults topLevelResults) async {
|
||||
if (topLevelResults['version'] as bool) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// In the case of `help`, `null` is returned. Treat that as success.
|
||||
return await super.runCommand(topLevelResults) ?? 0;
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
//
|
||||
// Created with Android Studio.
|
||||
// User: 三帆
|
||||
// Date: 30/07/2019
|
||||
// Time: 16:51
|
||||
// email: sanfan.hx@alibaba-inc.com
|
||||
// target: build
|
||||
//
|
||||
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import '../build/build_demo_list.dart';
|
||||
import '../build/build_page_list.dart';
|
||||
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
|
||||
class Build extends Command<int> {
|
||||
@override
|
||||
final name = 'build';
|
||||
@override
|
||||
final description = '生成索引等';
|
||||
|
||||
|
||||
@override
|
||||
Future<int> run() async {
|
||||
buildPageListJson();
|
||||
buildDemoListJson();
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
import 'dart:io';
|
||||
import 'package:args/args.dart'; // 使用其中两个类ArgParser和ArgResults
|
||||
import 'package:dart_inquirer/dart_inquirer.dart';
|
||||
import 'package:console/console.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:args/command_runner.dart';
|
||||
import '../build/build_demo_list.dart';
|
||||
|
||||
import '../config.dart';
|
||||
import '../../utils/util.dart';
|
||||
|
||||
|
||||
|
||||
ArgResults argResults; // 声明ArgResults类型的顶级变量,保存解析的参数结果
|
||||
|
||||
class DemoDetail {
|
||||
String name;
|
||||
String author;
|
||||
String email;
|
||||
String desc;
|
||||
String id;
|
||||
DemoDetail.fromJson(Map<dynamic, dynamic> json) {
|
||||
name = json['name'].trim();
|
||||
author = json['author'].trim();
|
||||
email = json['email'].trim();
|
||||
desc = json['desc'].trim();
|
||||
id = json['id'] ?? generateId();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
// 同时,argResults也是ArgResults的实例
|
||||
void createDemo() async {
|
||||
Map environmentVars = Platform.environment;
|
||||
List<Question> questions = [
|
||||
InputQuestion('name', '请输入新增加的demo名称?'),
|
||||
InputQuestion('author', '请输入您的姓名(使用英文)'),
|
||||
InputQuestion('email', '请输入您的github的email地址'),
|
||||
InputQuestion('desc', '请输入您demo的描述'),
|
||||
];
|
||||
|
||||
Map<dynamic, dynamic> answers = {};
|
||||
// 获取初次信息
|
||||
Prompt prompt = Prompt(questions);
|
||||
DemoDetail demoDetail;
|
||||
answers = await prompt.execute();
|
||||
|
||||
print(Seperator());
|
||||
print('您新增的组件信息如下');
|
||||
print(Seperator('='));
|
||||
prettyPrintJson(answers);
|
||||
print(Seperator('='));
|
||||
|
||||
questions =[ConfirmQuestion('confirm', 'Is this the config you want ?')];
|
||||
prompt = Prompt(questions);
|
||||
Map confirmAnswers = await prompt.execute();
|
||||
if (confirmAnswers['confirm'] != true) {
|
||||
return createDemo();
|
||||
}
|
||||
demoDetail = DemoDetail.fromJson(answers);
|
||||
|
||||
var demoPath = '$TARGET_DEMO_DIC/${demoDetail.name}_${demoDetail.author}_${demoDetail.id}';
|
||||
|
||||
// 创建root文件
|
||||
await createFile(demoPath);
|
||||
await createFile('$demoPath/src');
|
||||
// print("demoPath>>>> ${environmentVars['PWD']}/${demoPath}");
|
||||
writeContent2Path('$demoPath/src/', 'index.dart', """
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
@override
|
||||
_State createState() => _State();
|
||||
}
|
||||
|
||||
class _State extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Text("this is flutter go init demo"),
|
||||
);
|
||||
}
|
||||
}
|
||||
""");
|
||||
|
||||
writeContent2Path('$demoPath/', '.demo.json', """
|
||||
{
|
||||
"name": "${demoDetail.name}",
|
||||
"screenShot": "",
|
||||
"author":"${demoDetail.author}",
|
||||
"email": "${demoDetail.email}",
|
||||
"desc": "${demoDetail.desc}",
|
||||
"id": "${demoDetail.id}"
|
||||
}
|
||||
""");
|
||||
|
||||
writeContent2Path('$demoPath/', 'index.dart', """
|
||||
//
|
||||
// Created with flutter go cli
|
||||
// User: ${demoDetail.author}
|
||||
// Time: ${new DateTime.now()}
|
||||
// email: ${demoDetail.email}
|
||||
// desc: ${demoDetail.desc}
|
||||
//
|
||||
|
||||
import 'src/index.dart';
|
||||
|
||||
var demoWidgets = [
|
||||
new Demo()
|
||||
];
|
||||
|
||||
""");
|
||||
// format('{color.red}Invalid demo happends: $details {color.normal}');
|
||||
prettyPrintJson({
|
||||
'新建的demo文件位于': p.absolute((demoPath)),
|
||||
'demoId为': demoDetail.id,
|
||||
'markdown中调用方式': '[demo:${demoDetail.id}]'
|
||||
});
|
||||
buildDemoListJson();
|
||||
}
|
||||
|
||||
|
||||
class CreateDemoCommand extends Command<int> {
|
||||
@override
|
||||
final name = 'createDemo';
|
||||
@override
|
||||
final description = '新增flutter go demo.';
|
||||
|
||||
CreateDemoCommand() {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> run() async {
|
||||
createDemo();
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
import 'dart:io';
|
||||
import 'package:args/args.dart'; // 使用其中两个类ArgParser和ArgResults
|
||||
import 'package:dart_inquirer/dart_inquirer.dart';
|
||||
import 'package:args/command_runner.dart';
|
||||
|
||||
import '../build/build_page_list.dart';
|
||||
import '../config.dart';
|
||||
import '../../utils/util.dart';
|
||||
|
||||
var pageMarkdown = """
|
||||
# page
|
||||
|
||||
this is page markdown
|
||||
|
||||
you can load demo like this
|
||||
|
||||
```
|
||||
[demo: xxxid]
|
||||
```
|
||||
|
||||
""";
|
||||
|
||||
|
||||
ArgResults argResults; // 声明ArgResults类型的顶级变量,保存解析的参数结果
|
||||
|
||||
class PageDetail {
|
||||
String name;
|
||||
String author;
|
||||
String title;
|
||||
String email;
|
||||
String desc;
|
||||
String id;
|
||||
PageDetail.fromJson(Map<dynamic, dynamic> json) {
|
||||
name = json['name'];
|
||||
author = json['author'];
|
||||
title = json['title'];
|
||||
email = json['email'];
|
||||
desc = json['desc'];
|
||||
id = json['id'] ?? generateId();
|
||||
}
|
||||
}
|
||||
// 同时,argResults也是ArgResults的实例
|
||||
void createPage() async {
|
||||
Map environmentVars = Platform.environment;
|
||||
List<Question> questions = [
|
||||
InputQuestion('name', '请输入文件名称?'),
|
||||
InputQuestion('title', '请输入界面名称?'),
|
||||
InputQuestion('author', '请输入您的姓名(使用英文)'),
|
||||
InputQuestion('email', '请输入您的email地址'),
|
||||
InputQuestion('desc', '请输入您界面的简要'),
|
||||
];
|
||||
|
||||
Map<dynamic, dynamic> answers = {};
|
||||
// 获取初次信息
|
||||
Prompt prompt = Prompt(questions);
|
||||
PageDetail pageDetail;
|
||||
answers = await prompt.execute();
|
||||
print(Seperator());
|
||||
print('您新增的界面信息如下');
|
||||
print(Seperator('='));
|
||||
prettyPrintJson(answers);
|
||||
print(Seperator('='));
|
||||
|
||||
questions =[ConfirmQuestion('confirm', 'Is this the config you want ?')];
|
||||
prompt = Prompt(questions);
|
||||
Map confirmAnswers = await prompt.execute();
|
||||
if (confirmAnswers['confirm'] != true) {
|
||||
return createPage();
|
||||
}
|
||||
pageDetail = PageDetail.fromJson(answers);
|
||||
|
||||
var demoPath = '$TARGET_PAGE_DIC/${pageDetail.name}_${pageDetail.author}_${pageDetail.id}';
|
||||
|
||||
// 创建root文件
|
||||
await createFile(demoPath);
|
||||
|
||||
pageMarkdown = await readeFile("${environmentVars['PWD']}/go-cli/utils/tpl.md");
|
||||
|
||||
writeContent2Path('$demoPath/', 'index.dart', """
|
||||
String getMd() {
|
||||
return \"\"\"
|
||||
${pageMarkdown}\"\"\";
|
||||
|
||||
}
|
||||
""");
|
||||
|
||||
writeContent2Path('$demoPath/', '.page.json', """
|
||||
{
|
||||
"name": "${pageDetail.name}",
|
||||
"screenShot": "",
|
||||
"author":"${pageDetail.author}",
|
||||
"title":"${pageDetail.title}",
|
||||
"email": "${pageDetail.email}",
|
||||
"desc": "${pageDetail.desc}",
|
||||
"id": "${pageDetail.id}"
|
||||
}
|
||||
""");
|
||||
|
||||
writeContent2Path('$demoPath/', 'index.md', pageMarkdown);
|
||||
buildPageListJson();
|
||||
prettyPrintJson({
|
||||
'界面位于': demoPath,
|
||||
'Id': pageDetail.id,
|
||||
'文件夹名称': '${pageDetail.name}_${pageDetail.author}_${pageDetail.id}'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
class CreatePageCommand extends Command<int> {
|
||||
@override
|
||||
final name = 'createPage';
|
||||
@override
|
||||
final description = '新增flutter go page.';
|
||||
|
||||
CreateDemoCommand() {
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> run() async {
|
||||
createPage();
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
//
|
||||
// Created with Android Studio.
|
||||
// User: 三帆
|
||||
// Date: 08/06/2019
|
||||
// Time: 16:34
|
||||
// email: sanfan.hx@alibaba-inc.com
|
||||
// target: 监听demo与md
|
||||
//
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:args/command_runner.dart';
|
||||
import '../build/build_demo_list.dart';
|
||||
import '../build/build_page_list.dart';
|
||||
|
||||
import 'package:watcher/watcher.dart';
|
||||
import '../config.dart';
|
||||
import 'dart:async';
|
||||
|
||||
void watch() {
|
||||
Timer _changeTimer;
|
||||
List<Map<String, String>> config = [
|
||||
{
|
||||
"type": "demo",
|
||||
"path": '$TARGET_DEMO_DIC'
|
||||
}
|
||||
];
|
||||
List<String> demoIgnore = [
|
||||
'.demo.json',
|
||||
'index.dart',
|
||||
'info.json',
|
||||
'readme.md',
|
||||
];
|
||||
var watcherDemo = DirectoryWatcher(p.absolute('$TARGET_DEMO_DIC'));
|
||||
watcherDemo.events.listen((event) {
|
||||
|
||||
if (isIgnore(demoIgnore, TARGET_DEMO_DIC, event.path)) {
|
||||
return ;
|
||||
}
|
||||
if (event.type == ChangeType.ADD || event.type == ChangeType.REMOVE) {
|
||||
if (_changeTimer != null && _changeTimer.isActive) {
|
||||
_changeTimer.cancel();
|
||||
}
|
||||
_changeTimer = new Timer(Duration(milliseconds: 1000), () {
|
||||
buildDemoListJson();
|
||||
});
|
||||
}
|
||||
|
||||
}, onError: (error) {
|
||||
print('watch 发生错误: $error');
|
||||
});
|
||||
|
||||
List<String> pageIgnore = [
|
||||
'index.dart',
|
||||
'.pages.json'
|
||||
];
|
||||
var watcherPage = DirectoryWatcher(p.absolute('$TARGET_PAGE_DIC'));
|
||||
watcherPage.events.listen((event) {
|
||||
if (isIgnore(pageIgnore, TARGET_PAGE_DIC, event.path)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (event.type == ChangeType.ADD || event.type == ChangeType.REMOVE) {
|
||||
print("buildPageListJson:::");
|
||||
buildPageListJson();
|
||||
return ;
|
||||
}
|
||||
|
||||
if (event.type == ChangeType.MODIFY) {
|
||||
if (event.path.contains('index.md')) {
|
||||
transformMd2Dart(event.path.replaceAll('/index.md', ''));
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
print(event);
|
||||
});
|
||||
}
|
||||
bool isIgnore (List<String> ignorePath, parentPath, currentPath) {
|
||||
for (String ignore in ignorePath) {
|
||||
String path = p.absolute(parentPath, ignore);
|
||||
if (currentPath.contains(path)) {
|
||||
// print("修改的文件, 是忽略列表中的文件, 跳过编译!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
class WatchCommand extends Command<int> {
|
||||
@override
|
||||
final name = 'watch';
|
||||
@override
|
||||
final description = '动态生成文档与demo相关';
|
||||
|
||||
CreateDemoCommand() {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> run() async {
|
||||
watch();
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
// 生成Demo的目录位置
|
||||
const TARGET_PAGE_DIC = 'lib/standard_pages';
|
||||
const TARGET_DEMO_DIC = 'lib/page_demo_package';
|
||||
|
@ -1,21 +0,0 @@
|
||||
//
|
||||
// Created with Android Studio.
|
||||
// User: 三帆
|
||||
// Date: 25/05/2019
|
||||
// Time: 21:20
|
||||
// email: sanfan.hx@alibaba-inc.com
|
||||
// target: xxx
|
||||
//
|
||||
|
||||
|
||||
import 'package:console/console.dart';
|
||||
|
||||
class InvalidDemo implements Exception {
|
||||
final String details;
|
||||
InvalidDemo(this.details);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return format('{color.red}Invalid demo happends: $details {color.normal}');
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
const packageVersion = '1.0.0';
|
@ -1,60 +0,0 @@
|
||||
# 标准的详情页
|
||||
|
||||
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
|
||||
|
||||
您可以通过goCli固定命令创建详情页所需要的 **Flutter 实例**
|
||||
|
||||
```
|
||||
goCLi createDemo
|
||||
```
|
||||
|
||||
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
|
||||
|
||||
[✓] 请输入新增加的demo名称? demoName
|
||||
|
||||
[✓] 请输入您的姓名(使用英文) yourName
|
||||
|
||||
[✓] 请输入您的github的email地址 yourEmail
|
||||
|
||||
[✓] 请输入您demo的描述 这是一个测试的标准demo
|
||||
|
||||
|
||||
在完成以上操作后, 可以得到这样的输出:
|
||||
|
||||
|
||||
```
|
||||
------------------
|
||||
您新增的组件信息如下
|
||||
==================
|
||||
{
|
||||
name : demoName
|
||||
author : yourName
|
||||
email : yourEmail
|
||||
desc : 这是一个测试的标准demo
|
||||
}
|
||||
==================
|
||||
[✓] Is this the config you want ? (Y/n) y
|
||||
{
|
||||
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
}
|
||||
|
||||
```
|
||||
您可以在任意详情页中, 通过以下方式调用
|
||||
|
||||
```
|
||||
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
```
|
||||
|
||||
# 注意事项
|
||||
|
||||
**name** 必须**英文开头**, 统一用小写的英文字母,数字和下划线的组合,不得包含汉字空格和特殊字符, 需要与文章内容相关
|
||||
|
||||
|
||||
**author** 可以为中文英文以及任意组合, 但是不得有歧义, 暴力, 辱骂等词汇, 否则可能会被拒绝合并
|
||||
|
||||
**desc** 相关的简要描述, 需要对添加的组件或者界面进行简要描述, 方便后期搜索引擎采集
|
||||
|
||||
**email** 创建者的邮箱
|
||||
|
@ -1,64 +0,0 @@
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
Future<bool> createFile(String path) async {
|
||||
final tempDic = new Directory(path);
|
||||
var exits = await tempDic.exists();
|
||||
|
||||
if (exits) {
|
||||
print("文件当前已存在");
|
||||
return Future(() => false);
|
||||
}
|
||||
|
||||
await tempDic.createSync(recursive: true);
|
||||
return Future(() => true);
|
||||
}
|
||||
Future<String> readeFile(String path) async {
|
||||
String content = await new File(path).readAsString();
|
||||
return Future(() => content);
|
||||
}
|
||||
|
||||
// 该文件调用的时候. 必须存在父级文件夹
|
||||
Future<void> writeContent2Path(String path,String fileName, String content) async {
|
||||
var file = File('$path/$fileName');
|
||||
var sink = file.openWrite();
|
||||
sink.write(content);
|
||||
await sink.flush();
|
||||
await sink.close();
|
||||
return Future.value();
|
||||
}
|
||||
String generateId() {
|
||||
int d = DateTime.now().millisecondsSinceEpoch;
|
||||
var random = new Random(1);
|
||||
var template = 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx';
|
||||
var id = template.replaceAllMapped(new RegExp(r"[x|y]"), (c) {
|
||||
var r = ((d + random.nextDouble() * 16) % 16).toInt();
|
||||
d = d ~/ 16;
|
||||
var t = c.group(0) == 'x' ? r : (1 & 0x3 | 0x8);
|
||||
return t.toRadixString(16);
|
||||
});
|
||||
return id;
|
||||
}
|
||||
|
||||
/// 该文件调用的时候. 必须存在父级文件夹
|
||||
/// @param path 目录地址
|
||||
/// @param recursive 是否显示子目录或者子文件
|
||||
Future<List<FileSystemEntity>> readeDirChildren(String path, [bool recursive = false]) async {
|
||||
try {
|
||||
var dirParent = Directory(path);
|
||||
Stream<FileSystemEntity> entityList = dirParent.list(recursive: false, followLinks: false);
|
||||
List<FileSystemEntity> fileChildren = [];
|
||||
|
||||
await for(FileSystemEntity entity in entityList) {
|
||||
fileChildren.add(entity);
|
||||
}
|
||||
|
||||
return Future(() => fileChildren);
|
||||
} catch (e) {
|
||||
print('读取文件失败 ${e.toString()}');
|
||||
return Future(() => []);
|
||||
}
|
||||
}
|
||||
|
||||
//void main() {
|
||||
// readeFile('/Users/ontwo/Documents/ali/flutter/flutter-common-widgets-app/LICENSE');
|
||||
//}
|
@ -25,23 +25,18 @@
|
||||
0828E4A52206936100A59437 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0828E4A42206936100A59437 /* Images.xcassets */; };
|
||||
084A20882202E4FD00428FF5 /* flutter go.png in Resources */ = {isa = PBXBuildFile; fileRef = 084A20872202E4FD00428FF5 /* flutter go.png */; };
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
17DB4C25EDB98B3648015B9E /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 813A089174EBE6F8695A172E /* libPods-Runner.a */; };
|
||||
333E5DAE7FC10AC69FEC26C0 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA792F029EDD7A11295D192 /* libPods-Runner.a */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
|
||||
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
94722E5C22511D3600F63900 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 94722E5B22511D3600F63900 /* GoogleService-Info.plist */; };
|
||||
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
|
||||
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
|
||||
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
FA240D7922F2857D003025F3 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0115F22F1B9DF0016E673 /* Flutter.framework */; };
|
||||
FA240D7A22F2857D003025F3 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0115F22F1B9DF0016E673 /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
FA240D7B22F28581003025F3 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0116122F1B9DF0016E673 /* App.framework */; };
|
||||
FA240D7C22F28581003025F3 /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0116122F1B9DF0016E673 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
FAD0116422F1B9DF0016E673 /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = FAD0115E22F1B9DF0016E673 /* Debug.xcconfig */; };
|
||||
FAD0116522F1B9DF0016E673 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0115F22F1B9DF0016E673 /* Flutter.framework */; };
|
||||
FAD0116622F1B9DF0016E673 /* Release.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = FAD0116022F1B9DF0016E673 /* Release.xcconfig */; };
|
||||
FAD0116722F1B9DF0016E673 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0116122F1B9DF0016E673 /* App.framework */; };
|
||||
FAD0116822F1B9DF0016E673 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = FAD0116222F1B9DF0016E673 /* AppFrameworkInfo.plist */; };
|
||||
FAD0116922F1B9DF0016E673 /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = FAD0116322F1B9DF0016E673 /* Generated.xcconfig */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -51,8 +46,8 @@
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
FA240D7C22F28581003025F3 /* App.framework in Embed Frameworks */,
|
||||
FA240D7A22F2857D003025F3 /* Flutter.framework in Embed Frameworks */,
|
||||
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
|
||||
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -77,27 +72,26 @@
|
||||
0828E494220692B500A59437 /* iPhone XR Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone XR Landscape.png"; sourceTree = "<group>"; };
|
||||
0828E4A42206936100A59437 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
084A20872202E4FD00428FF5 /* flutter go.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "flutter go.png"; sourceTree = "<group>"; };
|
||||
10D9E78922B7651B003C2C98 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
813A089174EBE6F8695A172E /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94722E5B22511D3600F63900 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
A4868A865F318D337B7500AF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
B7B77D3AD1E975E5BE03D770 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
FAD0115E22F1B9DF0016E673 /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||
FAD0115F22F1B9DF0016E673 /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Flutter.framework; sourceTree = "<group>"; };
|
||||
FAD0116022F1B9DF0016E673 /* Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
||||
FAD0116122F1B9DF0016E673 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = App.framework; sourceTree = "<group>"; };
|
||||
FAD0116222F1B9DF0016E673 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
FAD0116322F1B9DF0016E673 /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Generated.xcconfig; sourceTree = "<group>"; };
|
||||
A9941E6EA19A9CEF6B117A70 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
CBA6E34746642008D95A119D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
DDA792F029EDD7A11295D192 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -105,11 +99,9 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
17DB4C25EDB98B3648015B9E /* libPods-Runner.a in Frameworks */,
|
||||
FAD0116722F1B9DF0016E673 /* App.framework in Frameworks */,
|
||||
FAD0116522F1B9DF0016E673 /* Flutter.framework in Frameworks */,
|
||||
FA240D7922F2857D003025F3 /* Flutter.framework in Frameworks */,
|
||||
FA240D7B22F28581003025F3 /* App.framework in Frameworks */,
|
||||
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
|
||||
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
|
||||
333E5DAE7FC10AC69FEC26C0 /* libPods-Runner.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -138,24 +130,46 @@
|
||||
path = launch;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8B83D3FCE2CD78ED2CD9BC84 /* Frameworks */ = {
|
||||
0C172CA58CDB230D5DA80034 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
813A089174EBE6F8695A172E /* libPods-Runner.a */,
|
||||
CBA6E34746642008D95A119D /* Pods-Runner.debug.xcconfig */,
|
||||
A9941E6EA19A9CEF6B117A70 /* Pods-Runner.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2EC8A3499721CE770475DCE7 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DDA792F029EDD7A11295D192 /* libPods-Runner.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B80C3931E831B6300D905FE /* App.framework */,
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||
9740EEBA1CF902C7004384FC /* Flutter.framework */,
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */,
|
||||
);
|
||||
name = Flutter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146E51CF9000F007C117D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FAD0115D22F1B9DF0016E673 /* Flutter */,
|
||||
0828E485220692A700A59437 /* launch */,
|
||||
084A20872202E4FD00428FF5 /* flutter go.png */,
|
||||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
F1785F83FDEE22F813679AE5 /* Pods */,
|
||||
8B83D3FCE2CD78ED2CD9BC84 /* Frameworks */,
|
||||
0C172CA58CDB230D5DA80034 /* Pods */,
|
||||
2EC8A3499721CE770475DCE7 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@ -170,7 +184,6 @@
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
10D9E78922B7651B003C2C98 /* Runner.entitlements */,
|
||||
94722E5B22511D3600F63900 /* GoogleService-Info.plist */,
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
|
||||
@ -194,28 +207,6 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F1785F83FDEE22F813679AE5 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A4868A865F318D337B7500AF /* Pods-Runner.debug.xcconfig */,
|
||||
B7B77D3AD1E975E5BE03D770 /* Pods-Runner.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAD0115D22F1B9DF0016E673 /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FAD0115E22F1B9DF0016E673 /* Debug.xcconfig */,
|
||||
FAD0115F22F1B9DF0016E673 /* Flutter.framework */,
|
||||
FAD0116022F1B9DF0016E673 /* Release.xcconfig */,
|
||||
FAD0116122F1B9DF0016E673 /* App.framework */,
|
||||
FAD0116222F1B9DF0016E673 /* AppFrameworkInfo.plist */,
|
||||
FAD0116322F1B9DF0016E673 /* Generated.xcconfig */,
|
||||
);
|
||||
path = Flutter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@ -223,15 +214,14 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
FBE7DB4E8DD084FE99B9ED05 /* [CP] Check Pods Manifest.lock */,
|
||||
443E32A5789BE5CCDA6B5E59 /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
B34D03FFEA3831330E64E5C7 /* [CP] Embed Pods Frameworks */,
|
||||
E54A6BDEF16ACE4A6988913A /* [CP] Copy Pods Resources */,
|
||||
C38E5EAE601417DA9DF11753 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -248,26 +238,22 @@
|
||||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1020;
|
||||
LastUpgradeCheck = 1000;
|
||||
ORGANIZATIONNAME = "The Chromium Authors";
|
||||
TargetAttributes = {
|
||||
97C146ED1CF9000F007C117D = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
DevelopmentTeam = 4WLT68XRNA;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.Push = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
ProvisioningStyle = Manual;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = en;
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
@ -286,7 +272,6 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FAD0116622F1B9DF0016E673 /* Release.xcconfig in Resources */,
|
||||
0828E4A0220692B500A59437 /* iPad Landscape.png in Resources */,
|
||||
0828E4A1220692B500A59437 /* iPhone XR Portrait.png in Resources */,
|
||||
0828E49F220692B500A59437 /* iPhone XS Max Landscape.png in Resources */,
|
||||
@ -294,20 +279,18 @@
|
||||
0828E4A3220692B500A59437 /* iPhone XR Landscape.png in Resources */,
|
||||
0828E4A2220692B500A59437 /* iPhone Portrait-Retina HD 5.5.png in Resources */,
|
||||
0828E49A220692B500A59437 /* iPhone X_XS Portrait.png in Resources */,
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||
0828E49E220692B500A59437 /* iPad Portrait@2x.png in Resources */,
|
||||
0828E49D220692B500A59437 /* iPhone Portrait@2x.png in Resources */,
|
||||
0828E499220692B500A59437 /* iPhone Portrait-Retina HD 4.7.png in Resources */,
|
||||
FAD0116822F1B9DF0016E673 /* AppFrameworkInfo.plist in Resources */,
|
||||
084A20882202E4FD00428FF5 /* flutter go.png in Resources */,
|
||||
0828E497220692B500A59437 /* iPhone X_XS Landscape.png in Resources */,
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||
0828E4A52206936100A59437 /* Images.xcassets in Resources */,
|
||||
FAD0116922F1B9DF0016E673 /* Generated.xcconfig in Resources */,
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||
0828E49B220692B500A59437 /* iPad Landscape@2x.png in Resources */,
|
||||
0828E495220692B500A59437 /* iPhone Portrait-Retina 4.png in Resources */,
|
||||
0828E498220692B500A59437 /* iPhone XS Max Portrait.png in Resources */,
|
||||
FAD0116422F1B9DF0016E673 /* Debug.xcconfig in Resources */,
|
||||
94722E5C22511D3600F63900 /* GoogleService-Info.plist in Resources */,
|
||||
0828E496220692B500A59437 /* iPad Portrait.png in Resources */,
|
||||
0828E49C220692B500A59437 /* iPhone Landscape-Retina HD 5.5.png in Resources */,
|
||||
@ -329,11 +312,29 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n";
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
|
||||
};
|
||||
443E32A5789BE5CCDA6B5E59 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 12;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
@ -343,15 +344,15 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
B34D03FFEA3831330E64E5C7 /* [CP] Embed Pods Frameworks */ = {
|
||||
C38E5EAE601417DA9DF11753 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
@ -360,47 +361,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
E54A6BDEF16ACE4A6988913A /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/flutter_downloader/FlutterDownloaderDatabase.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FlutterDownloaderDatabase.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FBE7DB4E8DD084FE99B9ED05 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
@ -440,9 +401,9 @@
|
||||
/* Begin XCBuildConfiguration section */
|
||||
97C147031CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
@ -467,7 +428,7 @@
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
@ -496,9 +457,9 @@
|
||||
};
|
||||
97C147041CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
@ -546,13 +507,12 @@
|
||||
};
|
||||
97C147061CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FAD0115E22F1B9DF0016E673 /* Debug.xcconfig */;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Launch2;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = 4WLT68XRNA;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -566,24 +526,21 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.fluttergo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
PROVISIONING_PROFILE_SPECIFIER = FlutterGO_alibaba_distribution_app_store;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147071CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FAD0116022F1B9DF0016E673 /* Release.xcconfig */;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Launch2;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = 4WLT68XRNA;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -597,11 +554,9 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.fluttergo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
PROVISIONING_PROFILE_SPECIFIER = FlutterGO_alibaba_distribution_ad_hoc;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
@ -616,7 +571,7 @@
|
||||
97C147041CF9000F007C117D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Debug;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
@ -625,7 +580,7 @@
|
||||
97C147071CF9000F007C117D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Debug;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildSystemType</key>
|
||||
<string>Original</string>
|
||||
</dict>
|
||||
</plist>
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1000"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -42,7 +42,7 @@
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
@ -51,7 +51,8 @@
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
@ -59,12 +60,12 @@
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
@ -84,7 +85,7 @@
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -1,6 +1,5 @@
|
||||
#include "AppDelegate.h"
|
||||
#include "GeneratedPluginRegistrant.h"
|
||||
#include "FlutterJPushPlugin.h"
|
||||
|
||||
@import Firebase;//增加 firebase 支持
|
||||
|
||||
@ -11,8 +10,6 @@
|
||||
|
||||
[FIRApp configure];//增加 firebase 支持
|
||||
|
||||
[self startupJPush:launchOptions appKey:@"62eb07d227d1f11dd7fa6239" channel:@"jpush" isProduction:FALSE];
|
||||
|
||||
[GeneratedPluginRegistrant registerWithRegistry:self];
|
||||
// Override point for customization after application launch.
|
||||
[NSThread sleepForTimeInterval:2];
|
||||
|
@ -1,12 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<device id="retina6_1" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
@ -18,9 +14,9 @@
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
|
@ -22,8 +22,6 @@
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string></string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
</dict>
|
||||
</plist>
|
@ -1,36 +1,10 @@
|
||||
class Api{
|
||||
// static const String BASE_URL = 'http://flutter-go.alibaba.net/';
|
||||
static const String BASE_URL = 'https://flutter-go.pub/api/';
|
||||
// static const String BASE_URL = 'http://127.0.0.1:6001/';
|
||||
static const String BASE_URL = 'http://flutter-go.alibaba.net/';
|
||||
|
||||
static const String DO_LOGIN = BASE_URL+'doLogin';//登陆
|
||||
|
||||
static const String CHECK_LOGIN = BASE_URL+'checkLogin';//验证登陆
|
||||
|
||||
static const String LOGOUT = BASE_URL+'logout';//退出登陆
|
||||
|
||||
static const String GET_USER_INFO = BASE_URL+'getUserInfo';//获取用户信息
|
||||
|
||||
|
||||
static const String VERSION = BASE_URL+'getAppVersion';//检查版本
|
||||
|
||||
static const String FEEDBACK = BASE_URL+'auth/feedback';//建议反馈
|
||||
|
||||
// static const String LOTOUT = BASE_URL+'logout';//退出登陆
|
||||
|
||||
static const String GET_ALL_COLLECTION = BASE_URL+'auth/getAllUserCollection';//获取全部收藏
|
||||
|
||||
static const String REMOVE_COLLECTION = BASE_URL+'auth/removeCollection';//移除收藏
|
||||
|
||||
static const String ADD_COLLECTION = BASE_URL+'auth/addCollection';//添加收藏
|
||||
|
||||
static const String CHECK_COLLECTED = BASE_URL+'checkCollected';//校验收藏
|
||||
|
||||
static const String SET_THEMECOLOR = BASE_URL+'auth/setThemeColor';//设置主题颜色
|
||||
|
||||
static const String GET_THEMECOLOR = BASE_URL +'/getThemeColor';//获取主题颜色
|
||||
|
||||
static const String GET_WIDGET_TREE = BASE_URL + 'getCateList';//获取widget列表树
|
||||
|
||||
static const String SEARCH_WIDGET = BASE_URL+'searchWidget';//搜索组件
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../model/cat.dart';
|
||||
import '../resources/widget_name_to_icon.dart';
|
||||
import '../components/widget_item_container.dart';
|
||||
import '../model/widget.dart';
|
||||
|
||||
class CateCard extends StatefulWidget {
|
||||
final CategoryComponent category;
|
||||
final Cat category;
|
||||
CateCard({@required this.category});
|
||||
@override
|
||||
_CateCardState createState() => _CateCardState();
|
||||
@ -13,15 +13,28 @@ class CateCard extends StatefulWidget {
|
||||
|
||||
class _CateCardState extends State<CateCard> {
|
||||
// 一级菜单目录下的二级Cat集合
|
||||
List<CommonItem> _firstChildList;
|
||||
List<Cat> _firstChildList = new List();
|
||||
CatControlModel catControl = new CatControlModel();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_firstChildList = widget.category.children;
|
||||
getFirstChildCategoriesByParentId();
|
||||
}
|
||||
|
||||
// 获取一层目录下的二级内容
|
||||
getFirstChildCategoriesByParentId() async {
|
||||
int parentId = widget.category.id;
|
||||
// 构建查询条件
|
||||
Cat childCateCondition = new Cat(parentId: parentId);
|
||||
|
||||
List<Cat> list = await catControl.getList(childCateCondition);
|
||||
if (list.isNotEmpty&&list.length>=1 && this.mounted) {
|
||||
setState(() {
|
||||
_firstChildList = list;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -30,6 +43,7 @@ class _CateCardState extends State<CateCard> {
|
||||
//首字母转为大写
|
||||
widget.category.name.substring(0, 1),
|
||||
widget.category.name.substring(0, 1).toUpperCase());
|
||||
|
||||
return Container(
|
||||
width: screenWidth,
|
||||
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
|
||||
@ -105,8 +119,9 @@ class _CateCardState extends State<CateCard> {
|
||||
),
|
||||
),
|
||||
child: WidgetItemContainer(
|
||||
commonItems: this._firstChildList,
|
||||
columnCount: 3
|
||||
categories: this._firstChildList,
|
||||
columnCount: 3,
|
||||
isWidgetPoint:false
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -8,12 +8,11 @@ import '../model/widget.dart';
|
||||
import '../widgets/index.dart';
|
||||
import '../components/widget_item_container.dart';
|
||||
|
||||
|
||||
enum CateOrWigdet { Cat, WidgetDemo }
|
||||
|
||||
class CategoryHome extends StatefulWidget {
|
||||
CategoryHome(this.token);
|
||||
final String token;
|
||||
|
||||
CategoryHome(this.name);
|
||||
final String name;
|
||||
|
||||
@override
|
||||
_CategoryHome createState() => new _CategoryHome();
|
||||
@ -22,11 +21,12 @@ class CategoryHome extends StatefulWidget {
|
||||
class _CategoryHome extends State<CategoryHome> {
|
||||
String title = '';
|
||||
// 显示列表 cat or widget;
|
||||
List<CommonItem> items = [];
|
||||
List<Object> widgetPoints = [];
|
||||
List<CommonItem> catHistory = new List();
|
||||
|
||||
List<Cat> categories = [];
|
||||
List<WidgetPoint> widgetPoints = [];
|
||||
List<Cat> catHistory = new List();
|
||||
|
||||
CatControlModel catControl = new CatControlModel();
|
||||
WidgetControlModel widgetControl = new WidgetControlModel();
|
||||
// 所有的可用demos;
|
||||
List widgetDemosList = new WidgetDemoList().getDemos();
|
||||
|
||||
@ -34,60 +34,80 @@ class _CategoryHome extends State<CategoryHome> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
// 初始化加入顶级的name
|
||||
print("这是新界面的id:>>> ${widget.token}");
|
||||
|
||||
CommonItem targetGroup = Application.widgetTree.find(widget.token) ?? [];
|
||||
print("targetGroup::: $targetGroup");
|
||||
|
||||
catHistory.add(
|
||||
targetGroup
|
||||
);
|
||||
this.setState(() {
|
||||
items = targetGroup.children;
|
||||
this.getCatByName(widget.name).then((Cat cat) {
|
||||
catHistory.add(cat);
|
||||
searchCatOrWigdet();
|
||||
});
|
||||
searchCatOrWidget();
|
||||
}
|
||||
|
||||
|
||||
Future<Cat> getCatByName(String name) async {
|
||||
return await catControl.getCatByName(name);
|
||||
}
|
||||
|
||||
Future<bool> back() {
|
||||
// if (catHistory.length == 1) {
|
||||
// return Future<bool>.value(true);
|
||||
// }
|
||||
// catHistory.removeLast();
|
||||
// searchCatOrWidget();
|
||||
return Future<bool>.value(true);
|
||||
if (catHistory.length == 1) {
|
||||
return Future<bool>.value(true);
|
||||
}
|
||||
catHistory.removeLast();
|
||||
searchCatOrWigdet();
|
||||
return Future<bool>.value(false);
|
||||
}
|
||||
|
||||
void go(CommonItem cat) {
|
||||
void go(Cat cat) {
|
||||
catHistory.add(cat);
|
||||
searchCatOrWidget();
|
||||
searchCatOrWigdet();
|
||||
}
|
||||
|
||||
void searchCatOrWidget() async {
|
||||
CommonItem widgetTree = Application.widgetTree;
|
||||
// 假设进入这个界面的parent一定存在
|
||||
CommonItem targetGroup = catHistory.last;
|
||||
void searchCatOrWigdet() async {
|
||||
// 假设进入这个界面的parent一定存在
|
||||
Cat parentCat = catHistory.last;
|
||||
|
||||
|
||||
// 继续搜索显示下一级depth: depth + 1, parentId: parentCat.id
|
||||
List<Cat> _categories =
|
||||
await catControl.getList(new Cat(parentId: parentCat.id));
|
||||
List<WidgetPoint> _widgetPoints = new List();
|
||||
if (_categories.isEmpty) {
|
||||
_widgetPoints =
|
||||
await widgetControl.getList(new WidgetPoint(catId: parentCat.id));
|
||||
}
|
||||
|
||||
this.setState(() {
|
||||
title = targetGroup.name;
|
||||
categories = _categories;
|
||||
title = parentCat.name;
|
||||
widgetPoints = _widgetPoints;
|
||||
});
|
||||
}
|
||||
|
||||
void onCatgoryTap(CommonItem cat) {
|
||||
void onCatgoryTap(Cat cat) {
|
||||
go(cat);
|
||||
}
|
||||
|
||||
|
||||
void onWidgetTap(WidgetPoint widgetPoint) {
|
||||
String targetName = widgetPoint.name;
|
||||
String targetRouter = '/category/error/404';
|
||||
widgetDemosList.forEach((item) {
|
||||
// print("targetRouter = item.routerName> ${[item.name,targetName]}");
|
||||
if (item.name == targetName) {
|
||||
targetRouter = item.routerName;
|
||||
}
|
||||
});
|
||||
Application.router.navigateTo(context, "$targetRouter");
|
||||
}
|
||||
|
||||
Widget _buildContent() {
|
||||
WidgetItemContainer wiContaienr = WidgetItemContainer(
|
||||
columnCount: 3,
|
||||
commonItems: items
|
||||
categories: categories,
|
||||
isWidgetPoint:false
|
||||
);
|
||||
|
||||
|
||||
if (widgetPoints.length > 0) {
|
||||
wiContaienr = WidgetItemContainer(
|
||||
categories: widgetPoints,
|
||||
columnCount: 3,
|
||||
isWidgetPoint:true
|
||||
);
|
||||
}
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(bottom: 10.0, top: 5.0),
|
||||
decoration: BoxDecoration(
|
||||
@ -102,18 +122,14 @@ class _CategoryHome extends State<CategoryHome> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("$title"),
|
||||
title: Text(title),
|
||||
),
|
||||
body: WillPopScope(
|
||||
|
||||
onWillPop: () {
|
||||
return back();
|
||||
},
|
||||
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
_buildContent(),
|
||||
|
@ -1,27 +0,0 @@
|
||||
// Copyright 2017 Google, Inc. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,39 +0,0 @@
|
||||
# Flutter Markdown
|
||||
[](https://pub.dartlang.org/packages/flutter_markdown)
|
||||
[](https://travis-ci.org/flutter/flutter_markdown)
|
||||
|
||||
|
||||
A markdown renderer for Flutter. It supports the
|
||||
[original format](https://daringfireball.net/projects/markdown/), but no inline
|
||||
html.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Using the Markdown widget is simple, just pass in the source markdown as a
|
||||
string:
|
||||
|
||||
new Markdown(data: markdownSource);
|
||||
|
||||
If you do not want the padding or scrolling behavior, use the MarkdownBody
|
||||
instead:
|
||||
|
||||
new MarkdownBody(data: markdownSource);
|
||||
|
||||
By default, Markdown uses the formatting from the current material design theme,
|
||||
but it's possible to create your own custom styling. Use the MarkdownStyle class
|
||||
to pass in your own style. If you don't want to use Markdown outside of material
|
||||
design, use the MarkdownRaw class.
|
||||
|
||||
## Image support
|
||||
|
||||
The `Img` tag only supports the following image locations:
|
||||
|
||||
* From the network: Use a URL prefixed by either `http://` or `https://`.
|
||||
|
||||
* From local files on the device: Use an absolute path to the file, for example by
|
||||
concatenating the file name with the path returned by a known storage location,
|
||||
such as those provided by the [`path_provider`](https://pub.dartlang.org/packages/path_provider)
|
||||
plugin.
|
||||
|
||||
* From image locations referring to bundled assets: Use an asset name prefixed by `resource:`.
|
||||
like `resource:assets/image.png`.
|
@ -1,10 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/// A library to render markdown formatted text.
|
||||
library flutter_markdown;
|
||||
|
||||
export 'src/builder.dart';
|
||||
export 'src/style_sheet.dart';
|
||||
export 'src/widget.dart';
|
@ -1,376 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:markdown/markdown.dart' as md;
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'style_sheet.dart';
|
||||
|
||||
typedef Widget DemoBuilder(Map<String, dynamic> attrs);
|
||||
|
||||
final Set<String> _kBlockTags = new Set<String>.from(<String>[
|
||||
'p',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'li',
|
||||
'blockquote',
|
||||
'pre',
|
||||
'ol',
|
||||
'ul',
|
||||
'hr',
|
||||
]);
|
||||
|
||||
const List<String> _kListTags = const <String>['ul', 'ol'];
|
||||
|
||||
bool _isBlockTag(String tag) => _kBlockTags.contains(tag);
|
||||
bool _isListTag(String tag) => _kListTags.contains(tag);
|
||||
|
||||
class _BlockElement {
|
||||
_BlockElement(this.tag);
|
||||
|
||||
final String tag;
|
||||
final List<Widget> children = <Widget>[];
|
||||
|
||||
int nextListIndex = 0;
|
||||
}
|
||||
|
||||
/// A collection of widgets that should be placed adjacent to (inline with)
|
||||
/// other inline elements in the same parent block.
|
||||
///
|
||||
/// Inline elements can be textual (a/em/strong) represented by [RichText]
|
||||
/// widgets or images (img) represented by [Image.network] widgets.
|
||||
///
|
||||
/// Inline elements can be nested within other inline elements, inheriting their
|
||||
/// parent's style along with the style of the block they are in.
|
||||
///
|
||||
/// When laying out inline widgets, first, any adjacent RichText widgets are
|
||||
/// merged, then, all inline widgets are enclosed in a parent [Wrap] widget.
|
||||
class _InlineElement {
|
||||
_InlineElement(this.tag, {this.style});
|
||||
|
||||
final String tag;
|
||||
|
||||
/// Created by merging the style defined for this element's [tag] in the
|
||||
/// delegate's [MarkdownStyleSheet] with the style of its parent.
|
||||
final TextStyle style;
|
||||
|
||||
final List<Widget> children = <Widget>[];
|
||||
}
|
||||
|
||||
/// A delegate used by [MarkdownBuilder] to control the widgets it creates.
|
||||
abstract class MarkdownBuilderDelegate {
|
||||
/// Returns a gesture recognizer to use for an `a` element with the given
|
||||
/// `href` attribute.
|
||||
GestureRecognizer createLink(String href);
|
||||
|
||||
/// Returns formatted text to use to display the given contents of a `pre`
|
||||
/// element.
|
||||
///
|
||||
/// The `styleSheet` is the value of [MarkdownBuilder.styleSheet].
|
||||
TextSpan formatText(MarkdownStyleSheet styleSheet, String code);
|
||||
}
|
||||
|
||||
/// Builds a [Widget] tree from parsed Markdown.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [Markdown], which is a widget that parses and displays Markdown.
|
||||
class MarkdownBuilder implements md.NodeVisitor {
|
||||
/// Creates an object that builds a [Widget] tree from parsed Markdown.
|
||||
MarkdownBuilder({
|
||||
this.delegate,
|
||||
this.styleSheet,
|
||||
this.imageDirectory,
|
||||
this.demoParser
|
||||
});
|
||||
|
||||
/// A delegate that controls how link and `pre` elements behave.
|
||||
final MarkdownBuilderDelegate delegate;
|
||||
|
||||
/// Defines which [TextStyle] objects to use for each type of element.
|
||||
final MarkdownStyleSheet styleSheet;
|
||||
|
||||
final DemoBuilder demoParser;
|
||||
/// The base directory holding images referenced by Img tags with local file paths.
|
||||
final Directory imageDirectory;
|
||||
|
||||
final List<String> _listIndents = <String>[];
|
||||
final List<_BlockElement> _blocks = <_BlockElement>[];
|
||||
final List<_InlineElement> _inlines = <_InlineElement>[];
|
||||
final List<GestureRecognizer> _linkHandlers = <GestureRecognizer>[];
|
||||
|
||||
|
||||
/// Returns widgets that display the given Markdown nodes.
|
||||
///
|
||||
/// The returned widgets are typically used as children in a [ListView].
|
||||
List<Widget> build(List<md.Node> nodes) {
|
||||
_listIndents.clear();
|
||||
_blocks.clear();
|
||||
_inlines.clear();
|
||||
_linkHandlers.clear();
|
||||
|
||||
_blocks.add(new _BlockElement(null));
|
||||
|
||||
for (md.Node node in nodes) {
|
||||
assert(_blocks.length == 1);
|
||||
node.accept(this);
|
||||
}
|
||||
|
||||
assert(_inlines.isEmpty);
|
||||
return _blocks.single.children;
|
||||
}
|
||||
|
||||
@override
|
||||
void visitText(md.Text text) {
|
||||
if (_blocks.last.tag == null) // Don't allow text directly under the root.
|
||||
return;
|
||||
|
||||
_addParentInlineIfNeeded(_blocks.last.tag);
|
||||
|
||||
final TextSpan span = _blocks.last.tag == 'pre'
|
||||
? delegate.formatText(styleSheet, text.text)
|
||||
: new TextSpan(
|
||||
style: _inlines.last.style,
|
||||
text: text.text,
|
||||
recognizer: _linkHandlers.isNotEmpty ? _linkHandlers.last : null,
|
||||
);
|
||||
|
||||
_inlines.last.children.add(new RichText(
|
||||
textScaleFactor: styleSheet.textScaleFactor,
|
||||
text: span,
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitElementBefore(md.Element element) {
|
||||
// print("visitElementBefore ${element.tag}");
|
||||
final String tag = element.tag;
|
||||
if (_isBlockTag(tag)) {
|
||||
_addAnonymousBlockIfNeeded(styleSheet.styles[tag]);
|
||||
if (_isListTag(tag))
|
||||
_listIndents.add(tag);
|
||||
_blocks.add(new _BlockElement(tag));
|
||||
} else {
|
||||
_addParentInlineIfNeeded(_blocks.last.tag);
|
||||
|
||||
TextStyle parentStyle = _inlines.last.style;
|
||||
_inlines.add(new _InlineElement(
|
||||
tag,
|
||||
style: parentStyle.merge(styleSheet.styles[tag]),
|
||||
));
|
||||
}
|
||||
|
||||
if (tag == 'a') {
|
||||
_linkHandlers.add(delegate.createLink(element.attributes['href']));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
void visitElementAfter(md.Element element) {
|
||||
final String tag = element.tag;
|
||||
if (_isBlockTag(tag)) {
|
||||
_addAnonymousBlockIfNeeded(styleSheet.styles[tag]);
|
||||
|
||||
final _BlockElement current = _blocks.removeLast();
|
||||
Widget child;
|
||||
|
||||
if (current.children.isNotEmpty) {
|
||||
child = new Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: current.children,
|
||||
);
|
||||
} else {
|
||||
child = const SizedBox();
|
||||
}
|
||||
|
||||
if (_isListTag(tag)) {
|
||||
assert(_listIndents.isNotEmpty);
|
||||
_listIndents.removeLast();
|
||||
} else if (tag == 'li') {
|
||||
if (_listIndents.isNotEmpty) {
|
||||
child = new Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new SizedBox(
|
||||
width: styleSheet.listIndent,
|
||||
child: _buildBullet(_listIndents.last),
|
||||
),
|
||||
new Expanded(child: child)
|
||||
],
|
||||
);
|
||||
}
|
||||
} else if (tag == 'blockquote') {
|
||||
child = new DecoratedBox(
|
||||
decoration: styleSheet.blockquoteDecoration,
|
||||
child: new Padding(
|
||||
padding: new EdgeInsets.all(styleSheet.blockquotePadding),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
} else if (tag == 'pre') {
|
||||
child = new DecoratedBox(
|
||||
decoration: styleSheet.codeblockDecoration,
|
||||
child: new Padding(
|
||||
padding: new EdgeInsets.all(styleSheet.codeblockPadding),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
} else if (tag == 'hr') {
|
||||
child = new DecoratedBox(
|
||||
decoration: styleSheet.horizontalRuleDecoration,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
_addBlockChild(child);
|
||||
} else {
|
||||
|
||||
final _InlineElement current = _inlines.removeLast();
|
||||
final _InlineElement parent = _inlines.last;
|
||||
|
||||
if (tag == 'img') {
|
||||
// create an image widget for this image
|
||||
current.children.add(_buildImage(element.attributes['src']));
|
||||
} else if (tag == 'a') {
|
||||
_linkHandlers.removeLast();
|
||||
} else if (tag == 'demo') {
|
||||
current.children.add(_buildGoDemos(element.attributes));
|
||||
}
|
||||
|
||||
|
||||
if (current.children.isNotEmpty) {
|
||||
parent.children.addAll(current.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
Widget _buildGoDemos(Map<String, dynamic> attrs) {
|
||||
Widget targetGoDemos;
|
||||
|
||||
if (demoParser != null) {
|
||||
targetGoDemos = demoParser(attrs);
|
||||
}
|
||||
|
||||
return targetGoDemos ?? new Text('demo not exits');
|
||||
}
|
||||
|
||||
Widget _buildImage(String src) {
|
||||
final List<String> parts = src.split('#');
|
||||
if (parts.isEmpty)
|
||||
return const SizedBox();
|
||||
|
||||
final String path = parts.first;
|
||||
double width;
|
||||
double height;
|
||||
if (parts.length == 2) {
|
||||
final List<String> dimensions = parts.last.split('x');
|
||||
if (dimensions.length == 2) {
|
||||
width = double.parse(dimensions[0]);
|
||||
height = double.parse(dimensions[1]);
|
||||
}
|
||||
}
|
||||
|
||||
Uri uri = Uri.parse(path);
|
||||
Widget child;
|
||||
if (uri.scheme == 'http' || uri.scheme == 'https') {
|
||||
child = new Image.network(uri.toString(), width: width, height: height);
|
||||
} else if (uri.scheme == 'data') {
|
||||
child = _handleDataSchemeUri(uri, width, height);
|
||||
} else if (uri.scheme == "resource") {
|
||||
child = new Image.asset(path.substring(9), width: width, height: height);
|
||||
} else {
|
||||
String filePath = (imageDirectory == null
|
||||
? uri.toFilePath()
|
||||
: p.join(imageDirectory.path, uri.toFilePath()));
|
||||
child = new Image.file(new File(filePath), width: width, height: height);
|
||||
}
|
||||
|
||||
if (_linkHandlers.isNotEmpty) {
|
||||
TapGestureRecognizer recognizer = _linkHandlers.last;
|
||||
return new GestureDetector(child: child, onTap: recognizer.onTap);
|
||||
} else {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
Widget _handleDataSchemeUri(Uri uri, final double width, final double height) {
|
||||
final String mimeType = uri.data.mimeType;
|
||||
if (mimeType.startsWith('image/')) {
|
||||
return new Image.memory(uri.data.contentAsBytes(), width: width, height: height);
|
||||
} else if (mimeType.startsWith('text/')) {
|
||||
return new Text(uri.data.contentAsString());
|
||||
}
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
Widget _buildBullet(String listTag) {
|
||||
if (listTag == 'ul')
|
||||
return new Text('•', textAlign: TextAlign.center, style: styleSheet.styles['li']);
|
||||
|
||||
final int index = _blocks.last.nextListIndex;
|
||||
return new Padding(
|
||||
padding: const EdgeInsets.only(right: 5.0),
|
||||
child: new Text('${index + 1}.', textAlign: TextAlign.right, style: styleSheet.styles['li']),
|
||||
);
|
||||
}
|
||||
|
||||
void _addParentInlineIfNeeded(String tag) {
|
||||
if (_inlines.isEmpty) {
|
||||
_inlines.add(new _InlineElement(
|
||||
tag,
|
||||
style: styleSheet.styles[tag],
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void _addBlockChild(Widget child) {
|
||||
final _BlockElement parent = _blocks.last;
|
||||
if (parent.children.isNotEmpty)
|
||||
parent.children.add(new SizedBox(height: styleSheet.blockSpacing));
|
||||
parent.children.add(child);
|
||||
parent.nextListIndex += 1;
|
||||
}
|
||||
|
||||
void _addAnonymousBlockIfNeeded(TextStyle style) {
|
||||
if (_inlines.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final _InlineElement inline = _inlines.single;
|
||||
if (inline.children.isNotEmpty) {
|
||||
List<Widget> mergedInlines = _mergeInlineChildren(inline);
|
||||
final Wrap wrap = new Wrap(children: mergedInlines);
|
||||
_addBlockChild(wrap);
|
||||
_inlines.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// Merges adjacent [TextSpan] children of the given [_InlineElement]
|
||||
List<Widget> _mergeInlineChildren(_InlineElement inline) {
|
||||
List<Widget> mergedTexts = <Widget>[];
|
||||
for (Widget child in inline.children) {
|
||||
if (mergedTexts.isNotEmpty && mergedTexts.last is RichText && child is RichText) {
|
||||
RichText previous = mergedTexts.removeLast();
|
||||
List<TextSpan> children = previous.text.children != null
|
||||
? new List.from(previous.text.children)
|
||||
: [previous.text];
|
||||
children.add(child.text);
|
||||
TextSpan mergedSpan = new TextSpan(children: children);
|
||||
mergedTexts.add(new RichText(
|
||||
textScaleFactor: styleSheet.textScaleFactor,
|
||||
text: mergedSpan,
|
||||
));
|
||||
} else {
|
||||
mergedTexts.add(child);
|
||||
}
|
||||
}
|
||||
return mergedTexts;
|
||||
}
|
||||
}
|
@ -1,307 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Defines which [TextStyle] objects to use for which Markdown elements.
|
||||
class MarkdownStyleSheet {
|
||||
/// Creates an explicit mapping of [TextStyle] objects to Markdown elements.
|
||||
MarkdownStyleSheet({
|
||||
this.a,
|
||||
this.p,
|
||||
this.code,
|
||||
this.h1,
|
||||
this.h2,
|
||||
this.h3,
|
||||
this.h4,
|
||||
this.h5,
|
||||
this.h6,
|
||||
this.em,
|
||||
this.strong,
|
||||
this.blockquote,
|
||||
this.img,
|
||||
this.blockSpacing,
|
||||
this.listIndent,
|
||||
this.blockquotePadding,
|
||||
this.blockquoteDecoration,
|
||||
this.codeblockPadding,
|
||||
this.codeblockDecoration,
|
||||
this.horizontalRuleDecoration,
|
||||
this.textScaleFactor = 1.0
|
||||
}) : _styles = <String, TextStyle>{
|
||||
'a': a,
|
||||
'p': p,
|
||||
'li': p,
|
||||
'code': code,
|
||||
'pre': p,
|
||||
'h1': h1,
|
||||
'h2': h2,
|
||||
'h3': h3,
|
||||
'h4': h4,
|
||||
'h5': h5,
|
||||
'h6': h6,
|
||||
'em': em,
|
||||
'strong': strong,
|
||||
'blockquote': blockquote,
|
||||
'img': img,
|
||||
};
|
||||
|
||||
/// Creates a [MarkdownStyleSheet] from the [TextStyle]s in the provided [ThemeData].
|
||||
factory MarkdownStyleSheet.fromTheme(ThemeData theme) {
|
||||
assert(theme?.textTheme?.body1?.fontSize != null);
|
||||
return new MarkdownStyleSheet(
|
||||
a: const TextStyle(color: Colors.blue),
|
||||
p: theme.textTheme.body1,
|
||||
code: new TextStyle(
|
||||
color: Colors.grey.shade700,
|
||||
fontFamily: "monospace",
|
||||
fontSize: theme.textTheme.body1.fontSize * 0.85
|
||||
),
|
||||
h1: theme.textTheme.headline,
|
||||
h2: theme.textTheme.title,
|
||||
h3: theme.textTheme.subhead,
|
||||
h4: theme.textTheme.body2,
|
||||
h5: theme.textTheme.body2,
|
||||
h6: theme.textTheme.body2,
|
||||
em: const TextStyle(fontStyle: FontStyle.italic),
|
||||
strong: const TextStyle(fontWeight: FontWeight.bold),
|
||||
blockquote: theme.textTheme.body1,
|
||||
img: theme.textTheme.body1,
|
||||
blockSpacing: 8.0,
|
||||
listIndent: 32.0,
|
||||
blockquotePadding: 8.0,
|
||||
blockquoteDecoration: new BoxDecoration(
|
||||
color: Colors.blue.shade100,
|
||||
borderRadius: new BorderRadius.circular(2.0)
|
||||
),
|
||||
codeblockPadding: 8.0,
|
||||
codeblockDecoration: new BoxDecoration(
|
||||
color: Colors.grey.shade100,
|
||||
borderRadius: new BorderRadius.circular(2.0)
|
||||
),
|
||||
horizontalRuleDecoration: new BoxDecoration(
|
||||
border: new Border(
|
||||
top: new BorderSide(width: 5.0, color: Colors.grey.shade300)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a [MarkdownStyle] from the [TextStyle]s in the provided [ThemeData].
|
||||
///
|
||||
/// This constructor uses larger fonts for the headings than in
|
||||
/// [MarkdownStyle.fromTheme].
|
||||
factory MarkdownStyleSheet.largeFromTheme(ThemeData theme) {
|
||||
return new MarkdownStyleSheet(
|
||||
a: const TextStyle(color: Colors.blue),
|
||||
p: theme.textTheme.body1,
|
||||
code: new TextStyle(
|
||||
color: Colors.grey.shade700,
|
||||
fontFamily: "monospace",
|
||||
fontSize: theme.textTheme.body1.fontSize * 0.85
|
||||
),
|
||||
h1: theme.textTheme.display3,
|
||||
h2: theme.textTheme.display2,
|
||||
h3: theme.textTheme.display1,
|
||||
h4: theme.textTheme.headline,
|
||||
h5: theme.textTheme.title,
|
||||
h6: theme.textTheme.subhead,
|
||||
em: const TextStyle(fontStyle: FontStyle.italic),
|
||||
strong: const TextStyle(fontWeight: FontWeight.bold),
|
||||
blockquote: theme.textTheme.body1,
|
||||
img: theme.textTheme.body1,
|
||||
blockSpacing: 8.0,
|
||||
listIndent: 32.0,
|
||||
blockquotePadding: 8.0,
|
||||
blockquoteDecoration: new BoxDecoration(
|
||||
color: Colors.blue.shade100,
|
||||
borderRadius: new BorderRadius.circular(2.0)
|
||||
),
|
||||
codeblockPadding: 8.0,
|
||||
codeblockDecoration: new BoxDecoration(
|
||||
color: Colors.grey.shade100,
|
||||
borderRadius: new BorderRadius.circular(2.0)
|
||||
),
|
||||
horizontalRuleDecoration: new BoxDecoration(
|
||||
border: new Border(
|
||||
top: new BorderSide(width: 5.0, color: Colors.grey.shade300)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a new [MarkdownStyleSheet] based on the current style, with the
|
||||
/// provided parameters overridden.
|
||||
MarkdownStyleSheet copyWith({
|
||||
TextStyle a,
|
||||
TextStyle p,
|
||||
TextStyle code,
|
||||
TextStyle h1,
|
||||
TextStyle h2,
|
||||
TextStyle h3,
|
||||
TextStyle h4,
|
||||
TextStyle h5,
|
||||
TextStyle h6,
|
||||
TextStyle em,
|
||||
TextStyle strong,
|
||||
TextStyle blockquote,
|
||||
TextStyle img,
|
||||
double blockSpacing,
|
||||
double listIndent,
|
||||
double blockquotePadding,
|
||||
Decoration blockquoteDecoration,
|
||||
double codeblockPadding,
|
||||
Decoration codeblockDecoration,
|
||||
Decoration horizontalRuleDecoration,
|
||||
double textScaleFactor,
|
||||
}) {
|
||||
return new MarkdownStyleSheet(
|
||||
a: a ?? this.a,
|
||||
p: p ?? this.p,
|
||||
code: code ?? this.code,
|
||||
h1: h1 ?? this.h1,
|
||||
h2: h2 ?? this.h2,
|
||||
h3: h3 ?? this.h3,
|
||||
h4: h4 ?? this.h4,
|
||||
h5: h5 ?? this.h5,
|
||||
h6: h6 ?? this.h6,
|
||||
em: em ?? this.em,
|
||||
strong: strong ?? this.strong,
|
||||
blockquote: blockquote ?? this.blockquote,
|
||||
img: img ?? this.img,
|
||||
blockSpacing: blockSpacing ?? this.blockSpacing,
|
||||
listIndent: listIndent ?? this.listIndent,
|
||||
blockquotePadding: blockquotePadding ?? this.blockquotePadding,
|
||||
blockquoteDecoration: blockquoteDecoration ?? this.blockquoteDecoration,
|
||||
codeblockPadding: codeblockPadding ?? this.codeblockPadding,
|
||||
codeblockDecoration: codeblockDecoration ?? this.codeblockDecoration,
|
||||
horizontalRuleDecoration: horizontalRuleDecoration ?? this.horizontalRuleDecoration,
|
||||
textScaleFactor : textScaleFactor ?? this.textScaleFactor,
|
||||
);
|
||||
}
|
||||
|
||||
/// The [TextStyle] to use for `a` elements.
|
||||
final TextStyle a;
|
||||
|
||||
/// The [TextStyle] to use for `p` elements.
|
||||
final TextStyle p;
|
||||
|
||||
/// The [TextStyle] to use for `code` elements.
|
||||
final TextStyle code;
|
||||
|
||||
/// The [TextStyle] to use for `h1` elements.
|
||||
final TextStyle h1;
|
||||
|
||||
/// The [TextStyle] to use for `h2` elements.
|
||||
final TextStyle h2;
|
||||
|
||||
/// The [TextStyle] to use for `h3` elements.
|
||||
final TextStyle h3;
|
||||
|
||||
/// The [TextStyle] to use for `h4` elements.
|
||||
final TextStyle h4;
|
||||
|
||||
/// The [TextStyle] to use for `h5` elements.
|
||||
final TextStyle h5;
|
||||
|
||||
/// The [TextStyle] to use for `h6` elements.
|
||||
final TextStyle h6;
|
||||
|
||||
/// The [TextStyle] to use for `em` elements.
|
||||
final TextStyle em;
|
||||
|
||||
/// The [TextStyle] to use for `strong` elements.
|
||||
final TextStyle strong;
|
||||
|
||||
/// The [TextStyle] to use for `blockquote` elements.
|
||||
final TextStyle blockquote;
|
||||
|
||||
/// The [TextStyle] to use for `img` elements.
|
||||
final TextStyle img;
|
||||
|
||||
/// The amount of vertical space to use between block-level elements.
|
||||
final double blockSpacing;
|
||||
|
||||
/// The amount of horizontal space to indent list items.
|
||||
final double listIndent;
|
||||
|
||||
/// The padding to use for `blockquote` elements.
|
||||
final double blockquotePadding;
|
||||
|
||||
/// The decoration to use behind `blockquote` elements.
|
||||
final Decoration blockquoteDecoration;
|
||||
|
||||
/// The padding to use for `pre` elements.
|
||||
final double codeblockPadding;
|
||||
|
||||
/// The decoration to use behind for `pre` elements.
|
||||
final Decoration codeblockDecoration;
|
||||
|
||||
/// The decoration to use for `hr` elements.
|
||||
final Decoration horizontalRuleDecoration;
|
||||
|
||||
// The text scale factor to use in textual elements
|
||||
final double textScaleFactor;
|
||||
|
||||
/// A [Map] from element name to the corresponding [TextStyle] object.
|
||||
Map<String, TextStyle> get styles => _styles;
|
||||
Map<String, TextStyle> _styles;
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
if (identical(this, other))
|
||||
return true;
|
||||
if (other.runtimeType != MarkdownStyleSheet)
|
||||
return false;
|
||||
final MarkdownStyleSheet typedOther = other;
|
||||
return typedOther.a == a
|
||||
&& typedOther.p == p
|
||||
&& typedOther.code == code
|
||||
&& typedOther.h1 == h1
|
||||
&& typedOther.h2 == h2
|
||||
&& typedOther.h3 == h3
|
||||
&& typedOther.h4 == h4
|
||||
&& typedOther.h5 == h5
|
||||
&& typedOther.h6 == h6
|
||||
&& typedOther.em == em
|
||||
&& typedOther.strong == strong
|
||||
&& typedOther.blockquote == blockquote
|
||||
&& typedOther.img == img
|
||||
&& typedOther.blockSpacing == blockSpacing
|
||||
&& typedOther.listIndent == listIndent
|
||||
&& typedOther.blockquotePadding == blockquotePadding
|
||||
&& typedOther.blockquoteDecoration == blockquoteDecoration
|
||||
&& typedOther.codeblockPadding == codeblockPadding
|
||||
&& typedOther.codeblockDecoration == codeblockDecoration
|
||||
&& typedOther.horizontalRuleDecoration == horizontalRuleDecoration
|
||||
&& typedOther.textScaleFactor == textScaleFactor;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashList([
|
||||
a,
|
||||
p,
|
||||
code,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
em,
|
||||
strong,
|
||||
blockquote,
|
||||
img,
|
||||
blockSpacing,
|
||||
listIndent,
|
||||
blockquotePadding,
|
||||
blockquoteDecoration,
|
||||
codeblockPadding,
|
||||
codeblockDecoration,
|
||||
horizontalRuleDecoration,
|
||||
textScaleFactor,
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,247 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:markdown/markdown.dart' as md;
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import 'builder.dart';
|
||||
import 'style_sheet.dart';
|
||||
//
|
||||
typedef Widget ItemDemoBuilder(Map<String, dynamic> attrs);
|
||||
|
||||
/// Signature for callbacks used by [MarkdownWidget] when the user taps a link.
|
||||
///
|
||||
/// Used by [MarkdownWidget.onTapLink].
|
||||
typedef void MarkdownTapLinkCallback(String href);
|
||||
|
||||
/// Creates a format [TextSpan] given a string.
|
||||
///
|
||||
/// Used by [MarkdownWidget] to highlight the contents of `pre` elements.
|
||||
abstract class SyntaxHighlighter { // ignore: one_member_abstracts
|
||||
/// Returns the formated [TextSpan] for the given string.
|
||||
TextSpan format(String source);
|
||||
}
|
||||
|
||||
/// A base class for widgets that parse and display Markdown.
|
||||
///
|
||||
/// Supports all standard Markdown from the original
|
||||
/// [Markdown specification](https://daringfireball.net/projects/markdown/).
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [Markdown], which is a scrolling container of Markdown.
|
||||
/// * [MarkdownBody], which is a non-scrolling container of Markdown.
|
||||
/// * <https://daringfireball.net/projects/markdown/>
|
||||
abstract class MarkdownWidget extends StatefulWidget {
|
||||
/// Creates a widget that parses and displays Markdown.
|
||||
///
|
||||
/// The [data] argument must not be null.
|
||||
const MarkdownWidget({
|
||||
Key key,
|
||||
@required this.data,
|
||||
this.styleSheet,
|
||||
this.syntaxHighlighter,
|
||||
this.onTapLink,
|
||||
this.imageDirectory,
|
||||
this.demoBuilder,
|
||||
}) : assert(data != null),
|
||||
super(key: key);
|
||||
|
||||
/// The Markdown to display.
|
||||
final String data;
|
||||
|
||||
/// The styles to use when displaying the Markdown.
|
||||
///
|
||||
/// If null, the styles are inferred from the current [Theme].
|
||||
final MarkdownStyleSheet styleSheet;
|
||||
|
||||
/// The syntax highlighter used to color text in `pre` elements.
|
||||
///
|
||||
/// If null, the [MarkdownStyleSheet.code] style is used for `pre` elements.
|
||||
final SyntaxHighlighter syntaxHighlighter;
|
||||
|
||||
/// Called when the user taps a link.
|
||||
final MarkdownTapLinkCallback onTapLink;
|
||||
|
||||
/// The base directory holding images referenced by Img tags with local file paths.
|
||||
final Directory imageDirectory;
|
||||
|
||||
final ItemDemoBuilder demoBuilder;
|
||||
/// Subclasses should override this function to display the given children,
|
||||
/// which are the parsed representation of [data].
|
||||
@protected
|
||||
Widget build(BuildContext context, List<Widget> children);
|
||||
|
||||
@override
|
||||
_MarkdownWidgetState createState() => new _MarkdownWidgetState();
|
||||
}
|
||||
|
||||
class DemosSyntax extends md.InlineSyntax {
|
||||
DemosSyntax() : super('\\[demo:([a-z0-9_+-]+)\\]');
|
||||
bool onMatch(parser, match) {
|
||||
var anchor = new md.Element.empty('demo');
|
||||
anchor.attributes['id'] = match[1];
|
||||
parser.addNode(anchor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class _MarkdownWidgetState extends State<MarkdownWidget> implements MarkdownBuilderDelegate {
|
||||
List<Widget> _children;
|
||||
final List<GestureRecognizer> _recognizers = <GestureRecognizer>[];
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
_parseMarkdown();
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(MarkdownWidget oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.data != oldWidget.data
|
||||
|| widget.styleSheet != oldWidget.styleSheet)
|
||||
_parseMarkdown();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_disposeRecognizers();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _parseMarkdown() {
|
||||
final MarkdownStyleSheet styleSheet = widget.styleSheet ?? new MarkdownStyleSheet.fromTheme(Theme.of(context));
|
||||
|
||||
_disposeRecognizers();
|
||||
|
||||
// TODO: This can be optimized by doing the split and removing \r at the same time
|
||||
final List<String> lines = widget.data.replaceAll('\r\n', '\n').split('\n');
|
||||
final md.ExtensionSet extens = new md.ExtensionSet([
|
||||
md.FencedCodeBlockSyntax()
|
||||
], [
|
||||
new DemosSyntax(),
|
||||
new md.InlineHtmlSyntax(),
|
||||
]);
|
||||
final md.Document document = new md.Document(encodeHtml: false, extensionSet: extens);
|
||||
final MarkdownBuilder builder = new MarkdownBuilder(
|
||||
delegate: this,
|
||||
styleSheet: styleSheet,
|
||||
imageDirectory: widget.imageDirectory,
|
||||
demoParser: widget.demoBuilder
|
||||
);
|
||||
_children = builder.build(document.parseLines(lines));
|
||||
}
|
||||
|
||||
void _disposeRecognizers() {
|
||||
if (_recognizers.isEmpty)
|
||||
return;
|
||||
final List<GestureRecognizer> localRecognizers = new List<GestureRecognizer>.from(_recognizers);
|
||||
_recognizers.clear();
|
||||
for (GestureRecognizer recognizer in localRecognizers)
|
||||
recognizer.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
GestureRecognizer createLink(String href) {
|
||||
final TapGestureRecognizer recognizer = new TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
if (widget.onTapLink != null)
|
||||
widget.onTapLink(href);
|
||||
};
|
||||
_recognizers.add(recognizer);
|
||||
return recognizer;
|
||||
}
|
||||
|
||||
@override
|
||||
TextSpan formatText(MarkdownStyleSheet styleSheet, String code) {
|
||||
if (widget.syntaxHighlighter != null)
|
||||
return widget.syntaxHighlighter.format(code);
|
||||
return new TextSpan(style: styleSheet.code, text: code);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => widget.build(context, _children);
|
||||
}
|
||||
|
||||
/// A non-scrolling widget that parses and displays Markdown.
|
||||
///
|
||||
/// Supports all standard Markdown from the original
|
||||
/// [Markdown specification](https://daringfireball.net/projects/markdown/).
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [Markdown], which is a scrolling container of Markdown.
|
||||
/// * <https://daringfireball.net/projects/markdown/>
|
||||
class MarkdownBody extends MarkdownWidget {
|
||||
/// Creates a non-scrolling widget that parses and displays Markdown.
|
||||
const MarkdownBody({
|
||||
Key key,
|
||||
String data,
|
||||
MarkdownStyleSheet styleSheet,
|
||||
SyntaxHighlighter syntaxHighlighter,
|
||||
MarkdownTapLinkCallback onTapLink,
|
||||
Directory imageDirectory,
|
||||
ItemDemoBuilder demoBuilder,
|
||||
}) : super(
|
||||
key: key,
|
||||
data: data,
|
||||
styleSheet: styleSheet,
|
||||
syntaxHighlighter: syntaxHighlighter,
|
||||
onTapLink: onTapLink,
|
||||
imageDirectory: imageDirectory,
|
||||
demoBuilder: demoBuilder
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, List<Widget> children) {
|
||||
if (children.length == 1)
|
||||
return children.single;
|
||||
return new Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: children,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A scrolling widget that parses and displays Markdown.
|
||||
///
|
||||
/// Supports all standard Markdown from the original
|
||||
/// [Markdown specification](https://daringfireball.net/projects/markdown/).
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [MarkdownBody], which is a non-scrolling container of Markdown.
|
||||
/// * <https://daringfireball.net/projects/markdown/>
|
||||
class Markdown extends MarkdownWidget {
|
||||
/// Creates a scrolling widget that parses and displays Markdown.
|
||||
const Markdown({
|
||||
Key key,
|
||||
String data,
|
||||
MarkdownStyleSheet styleSheet,
|
||||
SyntaxHighlighter syntaxHighlighter,
|
||||
MarkdownTapLinkCallback onTapLink,
|
||||
Directory imageDirectory,
|
||||
this.padding: const EdgeInsets.all(16.0),
|
||||
}) : super(
|
||||
key: key,
|
||||
data: data,
|
||||
styleSheet: styleSheet,
|
||||
syntaxHighlighter: syntaxHighlighter,
|
||||
onTapLink: onTapLink,
|
||||
imageDirectory: imageDirectory,
|
||||
);
|
||||
|
||||
/// The amount of space by which to inset the children.
|
||||
final EdgeInsets padding;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, List<Widget> children) {
|
||||
return new ListView(padding: padding, children: children);
|
||||
}
|
||||
}
|
@ -9,10 +9,9 @@ import 'package:flutter_go/utils/example_code_parser.dart';
|
||||
import 'package:flutter_go/utils/syntax_highlighter.dart';
|
||||
|
||||
class FullScreenCodeDialog extends StatefulWidget {
|
||||
const FullScreenCodeDialog({this.filePath, this.remoteFilePath});
|
||||
const FullScreenCodeDialog({this.filePath});
|
||||
|
||||
final String filePath;
|
||||
final String remoteFilePath;
|
||||
_FullScreenCodeDialogState createState() => _FullScreenCodeDialogState();
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,6 @@ class _ListRefreshState extends State<ListRefresh> {
|
||||
return widget.renderItem(index, items[index]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
controller: _scrollController,
|
||||
),
|
||||
|
@ -1,94 +0,0 @@
|
||||
//
|
||||
// Created with Android Studio.
|
||||
// User: 三帆
|
||||
// Date: 07/08/2019
|
||||
// Time: 08:40
|
||||
// email: sanfan.hx@alibaba-inc.com
|
||||
// tartget: 代码获取自: https://blog.csdn.net/O_time/article/details/86496537
|
||||
//
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class NetLoadingDialog extends StatefulWidget {
|
||||
String loadingText;
|
||||
bool outsideDismiss;
|
||||
bool loading;
|
||||
Function dismissCallback;
|
||||
Future<dynamic> requestCallBack;
|
||||
|
||||
NetLoadingDialog(
|
||||
{Key key,
|
||||
this.loadingText = "loading...",
|
||||
this.outsideDismiss = true,
|
||||
this.dismissCallback,
|
||||
this.loading,
|
||||
this.requestCallBack})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<NetLoadingDialog> createState() => _LoadingDialog();
|
||||
}
|
||||
|
||||
class _LoadingDialog extends State<NetLoadingDialog> {
|
||||
_dismissDialog() {
|
||||
if (widget.dismissCallback != null) {
|
||||
widget.dismissCallback();
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.requestCallBack != null) {
|
||||
widget.requestCallBack.then((_) {
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!widget.loading) {
|
||||
return Container();
|
||||
}
|
||||
return new GestureDetector(
|
||||
onTap: widget.outsideDismiss ? _dismissDialog : null,
|
||||
child: Material(
|
||||
type: MaterialType.transparency,
|
||||
child: new Center(
|
||||
child: new SizedBox(
|
||||
width: 120.0,
|
||||
height: 120.0,
|
||||
child: new Container(
|
||||
decoration: ShapeDecoration(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(8.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: new Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new CircularProgressIndicator(),
|
||||
new Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 20.0,
|
||||
),
|
||||
child: new Text(
|
||||
widget.loadingText,
|
||||
style: new TextStyle(fontSize: 12.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import '../components/flutter_markdown/lib/flutter_markdown.dart' as md;
|
||||
import 'package:flutter_markdown/flutter_markdown.dart' as md;
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_go/utils/high_light_code.dart';
|
||||
|
@ -1,47 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_go/event/event_bus.dart';
|
||||
import 'package:flutter_go/event/event_model.dart';
|
||||
// import 'package:event_bus/event_bus.dart';
|
||||
|
||||
class SingleThemeColor extends StatelessWidget {
|
||||
final int themeColor;
|
||||
final String coloeName;
|
||||
|
||||
const SingleThemeColor({Key key, this.themeColor, this.coloeName})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: (){
|
||||
if(ApplicationEvent.event != null){
|
||||
print('fire ${this.themeColor}');
|
||||
ApplicationEvent.event.fire(UserSettingThemeColorEvent(this.themeColor));
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
margin: const EdgeInsets.all(5.0),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(50),
|
||||
),
|
||||
color: Color(this.themeColor),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
this.coloeName,
|
||||
style: TextStyle(
|
||||
color: Color(this.themeColor),
|
||||
fontSize: 14.0,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@
|
||||
import 'dart:core';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_go/utils/data_utils.dart';
|
||||
|
||||
import '../routers/application.dart';
|
||||
import '../routers/routers.dart';
|
||||
@ -25,8 +24,8 @@ class WidgetDemo extends StatefulWidget {
|
||||
{Key key,
|
||||
@required this.title,
|
||||
@required this.contentList,
|
||||
this.codeUrl,
|
||||
this.docUrl,
|
||||
@required this.codeUrl,
|
||||
@required this.docUrl,
|
||||
this.bottomNaviBar})
|
||||
: super(key: key);
|
||||
|
||||
@ -38,7 +37,7 @@ class _WidgetDemoState extends State<WidgetDemo> {
|
||||
CollectionControlModel _collectionControl = new CollectionControlModel();
|
||||
var _collectionIcons;
|
||||
List widgetDemosList = new WidgetDemoList().getDemos();
|
||||
String widgetType = 'old';
|
||||
String _router = '';
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
List<Widget> _buildContent() {
|
||||
@ -65,67 +64,56 @@ class _WidgetDemoState extends State<WidgetDemo> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// 这里不能直接 使用 ` ModalRoute.of(context)` 会产生报错
|
||||
Future.delayed(Duration.zero, () {
|
||||
String currentPath = ModalRoute.of(context).settings.name;
|
||||
if (currentPath.indexOf('/standard-page') == 0) {
|
||||
widgetType = 'standard';
|
||||
}
|
||||
Map<String, String> params = {
|
||||
'type': widgetType,
|
||||
"url": currentPath,
|
||||
"name": widget.title
|
||||
};
|
||||
DataUtils.checkCollected(params).then((result) {
|
||||
if (this.mounted) {
|
||||
setState(() {
|
||||
_hasCollected = result;
|
||||
});
|
||||
_collectionControl.getRouterByName(widget.title).then((list) {
|
||||
widgetDemosList.forEach((item) {
|
||||
if (item.name == widget.title) {
|
||||
_router = item.routerName;
|
||||
}
|
||||
});
|
||||
if (this.mounted) {
|
||||
setState(() {
|
||||
_hasCollected = list.length > 0;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 点击收藏按钮
|
||||
_getCollection() {
|
||||
String currentRouterPath = ModalRoute.of(context).settings.name;
|
||||
Map<String, String> params = {
|
||||
"type": widgetType,
|
||||
"url": currentRouterPath,
|
||||
"name": widget.title
|
||||
};
|
||||
if (_hasCollected) {
|
||||
// 删除操作
|
||||
DataUtils.removeCollected(params, context).then((result) {
|
||||
if (result) {
|
||||
_collectionControl.deleteByName(widget.title).then((result) {
|
||||
if (result > 0 && this.mounted) {
|
||||
setState(() {
|
||||
_hasCollected = false;
|
||||
});
|
||||
_scaffoldKey.currentState
|
||||
.showSnackBar(SnackBar(content: Text('已取消收藏')));
|
||||
if (ApplicationEvent.event != null) {
|
||||
ApplicationEvent.event
|
||||
.fire(CollectionEvent(widget.title, currentRouterPath, true));
|
||||
}
|
||||
if (this.mounted) {
|
||||
setState(() {
|
||||
_hasCollected = false;
|
||||
});
|
||||
.fire(CollectionEvent(widget.title, _router, true));
|
||||
}
|
||||
return;
|
||||
}
|
||||
print('删除错误');
|
||||
});
|
||||
} else {
|
||||
// 插入操作
|
||||
DataUtils.addCollected(params, context).then((result) {
|
||||
if (result) {
|
||||
if (this.mounted) {
|
||||
setState(() {
|
||||
_hasCollected = true;
|
||||
});
|
||||
}
|
||||
_scaffoldKey.currentState
|
||||
.showSnackBar(SnackBar(content: Text('收藏成功')));
|
||||
_collectionControl
|
||||
.insert(Collection(name: widget.title, router: _router))
|
||||
.then((result) {
|
||||
if (this.mounted) {
|
||||
setState(() {
|
||||
_hasCollected = true;
|
||||
});
|
||||
|
||||
if (ApplicationEvent.event != null) {
|
||||
ApplicationEvent.event
|
||||
.fire(CollectionEvent(widget.title, currentRouterPath, false));
|
||||
.fire(CollectionEvent(widget.title, _router, false));
|
||||
}
|
||||
|
||||
_scaffoldKey.currentState
|
||||
.showSnackBar(SnackBar(content: Text('收藏成功')));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -141,38 +129,7 @@ class _WidgetDemoState extends State<WidgetDemo> {
|
||||
'${Routes.codeView}?filePath=${Uri.encodeComponent(widget.codeUrl)}');
|
||||
}
|
||||
}
|
||||
List<PopupMenuEntry<String>> buildPopupMenu() {
|
||||
List<PopupMenuEntry<String>> comps = [];
|
||||
if (widget.docUrl != null) {
|
||||
comps.add(
|
||||
PopupMenuItem<String>(
|
||||
value: 'doc',
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
Icons.library_books,
|
||||
size: 22.0,
|
||||
),
|
||||
title: Text('查看文档'),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
if (widget.codeUrl != null) {
|
||||
comps.add(
|
||||
PopupMenuItem<String>(
|
||||
value: 'code',
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
Icons.code,
|
||||
size: 22.0,
|
||||
),
|
||||
title: Text('查看Demo'),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
return comps;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_hasCollected) {
|
||||
@ -180,34 +137,50 @@ class _WidgetDemoState extends State<WidgetDemo> {
|
||||
} else {
|
||||
_collectionIcons = Icons.favorite_border;
|
||||
}
|
||||
List<PopupMenuEntry<String>> menus = buildPopupMenu();
|
||||
List<Widget> actions = [
|
||||
new IconButton(
|
||||
tooltip: 'goBack home',
|
||||
onPressed: () {
|
||||
Navigator.popUntil(context, ModalRoute.withName('/'));
|
||||
},
|
||||
icon: Icon(Icons.home),
|
||||
),
|
||||
new IconButton(
|
||||
tooltip: 'collection',
|
||||
onPressed: _getCollection,
|
||||
icon: Icon(_collectionIcons),
|
||||
),
|
||||
];
|
||||
if (menus.length > 0) {
|
||||
actions.add(
|
||||
PopupMenuButton<String>(
|
||||
onSelected: _selectValue,
|
||||
itemBuilder: (BuildContext context) => menus,
|
||||
)
|
||||
);
|
||||
}
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBar(
|
||||
title: Text(widget.title),
|
||||
actions: actions,
|
||||
actions: <Widget>[
|
||||
new IconButton(
|
||||
tooltip: 'goBack home',
|
||||
onPressed: () {
|
||||
Navigator.popUntil(context, ModalRoute.withName('/'));
|
||||
},
|
||||
icon: Icon(Icons.home),
|
||||
),
|
||||
new IconButton(
|
||||
tooltip: 'collection',
|
||||
onPressed: _getCollection,
|
||||
icon: Icon(_collectionIcons),
|
||||
),
|
||||
PopupMenuButton<String>(
|
||||
onSelected: _selectValue,
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
||||
const PopupMenuItem<String>(
|
||||
value: 'doc',
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
Icons.library_books,
|
||||
size: 22.0,
|
||||
),
|
||||
title: Text('查看文档'),
|
||||
),
|
||||
),
|
||||
const PopupMenuDivider(),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'code',
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
Icons.code,
|
||||
size: 22.0,
|
||||
),
|
||||
title: Text('查看Demo'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
|
||||
|
@ -3,89 +3,56 @@ import 'package:fluro/fluro.dart';
|
||||
import './widget_item.dart';
|
||||
import '../routers/application.dart';
|
||||
import '../widgets/index.dart';
|
||||
import '../model/widget.dart';
|
||||
|
||||
class WidgetItemContainer extends StatelessWidget {
|
||||
final int columnCount; //一行几个
|
||||
final List<CommonItem> commonItems;
|
||||
// final bool isWidgetPoint;
|
||||
final List<dynamic> categories;
|
||||
final bool isWidgetPoint;
|
||||
|
||||
// 所有的可用demos;
|
||||
final List widgetDemosList = new WidgetDemoList().getDemos();
|
||||
|
||||
WidgetItemContainer(
|
||||
{Key key,
|
||||
@required this.commonItems,
|
||||
@required this.categories,
|
||||
@required this.columnCount,
|
||||
// @required this.isWidgetPoint
|
||||
})
|
||||
@required this.isWidgetPoint})
|
||||
: super(key: key);
|
||||
|
||||
/// 跳转goup
|
||||
void tapToGroup(CategoryComponent cate, BuildContext context) {
|
||||
Application.router
|
||||
.navigateTo(context, "/category/${cate.token}", transition: TransitionType.inFromRight);
|
||||
}
|
||||
|
||||
/// 跳转到老的widget界面
|
||||
void tapToOldWidget(WidgetLeaf leaf, BuildContext context) {
|
||||
|
||||
String targetName = leaf.name;
|
||||
String targetRouter = '/category/error/404';
|
||||
widgetDemosList.forEach((item) {
|
||||
if (item.name == targetName) {
|
||||
targetRouter = item.routerName;
|
||||
}
|
||||
});
|
||||
Application.router.navigateTo(context, targetRouter, transition: TransitionType.inFromRight);
|
||||
}
|
||||
|
||||
/// 跳转到新的标准页
|
||||
void tapToStandardPage(WidgetLeaf leaf, BuildContext context) {
|
||||
String targetRouter = '/standard-page/${leaf.pageId}';
|
||||
Application.router.navigateTo(context, targetRouter, transition: TransitionType.inFromRight);
|
||||
}
|
||||
|
||||
List<Widget> _buildColumns(context) {
|
||||
List<Widget> _listWidget = [];
|
||||
List<Widget> _listRows = [];
|
||||
int addI;
|
||||
for (int i = 0, length = commonItems.length; i < length; i += columnCount) {
|
||||
for (int i = 0, length = categories.length; i < length; i += columnCount) {
|
||||
_listRows = [];
|
||||
for (int innerI = 0; innerI < columnCount; innerI++) {
|
||||
addI = innerI + i;
|
||||
if (addI < length) {
|
||||
CommonItem item = commonItems[addI];
|
||||
|
||||
|
||||
dynamic item = categories[addI];
|
||||
_listRows.add(
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: WidgetItem(
|
||||
title: item.name,
|
||||
onTap: () {
|
||||
String type = item.type;
|
||||
|
||||
if (type == "category") {
|
||||
return tapToGroup(item as CategoryComponent, context);
|
||||
if (isWidgetPoint) {
|
||||
String targetName = item.name;
|
||||
String targetRouter = '/category/error/404';
|
||||
widgetDemosList.forEach((item) {
|
||||
if (item.name == targetName) {
|
||||
targetRouter = item.routerName;
|
||||
}
|
||||
});
|
||||
Application.router.navigateTo(context, "$targetRouter", transition: TransitionType.inFromRight);
|
||||
} else {
|
||||
Application.router
|
||||
.navigateTo(context, "/category/${item.name}", transition: TransitionType.inFromRight);
|
||||
}
|
||||
if (type == "widget") {
|
||||
WidgetLeaf leaf = item as WidgetLeaf;
|
||||
|
||||
if (leaf.display == "standard") {
|
||||
return tapToStandardPage(leaf, context);
|
||||
} else {
|
||||
return tapToOldWidget(leaf, context);
|
||||
}
|
||||
}
|
||||
|
||||
Application.router
|
||||
.navigateTo(context, "/category/error/404", transition: TransitionType.inFromRight);
|
||||
},
|
||||
index: addI,
|
||||
totalCount: length,
|
||||
rowLength: columnCount,
|
||||
textSize: true ? 'middle' : 'small',
|
||||
textSize: isWidgetPoint ? 'middle' : 'small',
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -114,4 +81,3 @@ class WidgetItemContainer extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,4 +2,4 @@ import 'package:event_bus/event_bus.dart';
|
||||
|
||||
class ApplicationEvent{
|
||||
static EventBus event;
|
||||
}
|
||||
}
|
@ -4,16 +4,4 @@ class CollectionEvent{
|
||||
final bool isRemove;
|
||||
// token uid...
|
||||
CollectionEvent(this.widgetName,this.router,this.isRemove);
|
||||
}
|
||||
|
||||
class UserGithubOAuthEvent{
|
||||
final String loginName;
|
||||
final String token;
|
||||
final bool isSuccess;
|
||||
UserGithubOAuthEvent(this.loginName,this.token,this.isSuccess);
|
||||
}
|
||||
|
||||
class UserSettingThemeColorEvent{
|
||||
final int settingThemeColor;
|
||||
UserSettingThemeColorEvent(this.settingThemeColor);
|
||||
}
|
125
lib/main.dart
@ -11,23 +11,19 @@ import 'package:flutter_go/model/search_history.dart';
|
||||
import 'package:flutter_go/utils/analytics.dart' as Analytics;
|
||||
import 'package:flutter_go/views/login_page/login_page.dart';
|
||||
import 'package:flutter_go/utils/data_utils.dart';
|
||||
import 'package:flutter_go/model/user_info.dart';
|
||||
import 'package:flutter_jpush/flutter_jpush.dart';
|
||||
import 'package:flutter_go/event/event_bus.dart';
|
||||
import 'package:flutter_go/event/event_model.dart';
|
||||
import 'package:event_bus/event_bus.dart';
|
||||
import 'package:flutter_go/model/widget.dart';
|
||||
import 'package:flutter_go/standard_pages/index.dart';
|
||||
|
||||
//import 'views/welcome_page/index.dart';
|
||||
|
||||
const int ThemeColor = 0xFFC91B3A;
|
||||
SpUtil sp;
|
||||
var db;
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
MyApp() {
|
||||
final router = new Router();
|
||||
|
||||
Routes.configureRoutes(router);
|
||||
// 这里设置项目环境
|
||||
|
||||
Application.router = router;
|
||||
}
|
||||
|
||||
@ -38,105 +34,28 @@ class MyApp extends StatefulWidget {
|
||||
class _MyAppState extends State<MyApp> {
|
||||
bool _hasLogin = false;
|
||||
bool _isLoading = true;
|
||||
UserInformation _userInfo;
|
||||
bool isConnected = false;
|
||||
String registrationId;
|
||||
List notificationList = [];
|
||||
int themeColor = 0xFFC91B3A;
|
||||
|
||||
_MyAppState() {
|
||||
final eventBus = new EventBus();
|
||||
ApplicationEvent.event = eventBus;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_startupJpush();
|
||||
|
||||
FlutterJPush.addConnectionChangeListener((bool connected) {
|
||||
setState(() {
|
||||
/// 是否连接,连接了才可以推送
|
||||
print("连接状态改变:$connected");
|
||||
this.isConnected = connected;
|
||||
if (connected) {
|
||||
//在启动的时候会去连接自己的服务器,连接并注册成功之后会返回一个唯一的设备号
|
||||
try {
|
||||
FlutterJPush.getRegistrationID().then((String regId) {
|
||||
print("主动获取设备号:$regId");
|
||||
setState(() {
|
||||
this.registrationId = regId;
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
print('主动获取设备号Error:$error');
|
||||
}
|
||||
;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
FlutterJPush.addReceiveNotificationListener(
|
||||
(JPushNotification notification) {
|
||||
setState(() {
|
||||
/// 收到推送
|
||||
print("收到推送提醒: $notification");
|
||||
notificationList.add(notification);
|
||||
});
|
||||
});
|
||||
|
||||
FlutterJPush.addReceiveOpenNotificationListener(
|
||||
(JPushNotification notification) {
|
||||
setState(() {
|
||||
print("打开了推送提醒: $notification");
|
||||
|
||||
/// 打开了推送提醒
|
||||
notificationList.add(notification);
|
||||
});
|
||||
});
|
||||
|
||||
FlutterJPush.addReceiveCustomMsgListener((JPushMessage msg) {
|
||||
setState(() {
|
||||
print("收到推送消息提醒: $msg");
|
||||
|
||||
/// 打开了推送提醒
|
||||
notificationList.add(msg);
|
||||
});
|
||||
});
|
||||
|
||||
DataUtils.checkLogin().then((hasLogin) {
|
||||
if (hasLogin.runtimeType == UserInformation) {
|
||||
setState(() {
|
||||
_hasLogin = true;
|
||||
_isLoading = false;
|
||||
_userInfo = hasLogin;
|
||||
// 设置初始化的主题色
|
||||
// if (hasLogin.themeColor != 'default') {
|
||||
// themeColor = int.parse(hasLogin.themeColor);
|
||||
// }
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
_hasLogin = hasLogin;
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}).catchError((onError) {
|
||||
setState(() {
|
||||
_hasLogin = false;
|
||||
_hasLogin = hasLogin;
|
||||
_isLoading = false;
|
||||
});
|
||||
}).catchError((onError){
|
||||
setState(() {
|
||||
_hasLogin = true;
|
||||
_isLoading = false;
|
||||
});
|
||||
print('身份信息验证失败:$onError');
|
||||
});
|
||||
ApplicationEvent.event.on<UserSettingThemeColorEvent>().listen((event) {
|
||||
print('接收到的 event $event');
|
||||
});
|
||||
}
|
||||
|
||||
showWelcomePage() {
|
||||
if (_isLoading) {
|
||||
return Container(
|
||||
color: Color(this.themeColor),
|
||||
color: const Color(ThemeColor),
|
||||
child: Center(
|
||||
child: SpinKitPouringHourglass(color: Colors.white),
|
||||
),
|
||||
@ -144,7 +63,7 @@ class _MyAppState extends State<MyApp> {
|
||||
} else {
|
||||
// 判断是否已经登录
|
||||
if (_hasLogin) {
|
||||
return AppPage(_userInfo);
|
||||
return AppPage();
|
||||
} else {
|
||||
return LoginPage();
|
||||
}
|
||||
@ -153,11 +72,10 @@ class _MyAppState extends State<MyApp> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// WidgetTree.getCommonItemByPath([15, 17], Application.widgetTree);
|
||||
return new MaterialApp(
|
||||
title: 'titles',
|
||||
title: 'title',
|
||||
theme: new ThemeData(
|
||||
primaryColor: Color(this.themeColor),
|
||||
primaryColor: Color(ThemeColor),
|
||||
backgroundColor: Color(0xFFEFEFEF),
|
||||
accentColor: Color(0xFF888888),
|
||||
textTheme: TextTheme(
|
||||
@ -165,7 +83,7 @@ class _MyAppState extends State<MyApp> {
|
||||
body1: TextStyle(color: Color(0xFF888888), fontSize: 16.0),
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
color: Color(this.themeColor),
|
||||
color: Color(ThemeColor),
|
||||
size: 35.0,
|
||||
),
|
||||
),
|
||||
@ -177,24 +95,11 @@ class _MyAppState extends State<MyApp> {
|
||||
}
|
||||
}
|
||||
|
||||
void _startupJpush() async {
|
||||
print("初始化jpush");
|
||||
await FlutterJPush.startup();
|
||||
print("初始化jpush成功");
|
||||
}
|
||||
|
||||
void main() async {
|
||||
final provider = new Provider();
|
||||
await provider.init(true);
|
||||
sp = await SpUtil.getInstance();
|
||||
new SearchHistoryList(sp);
|
||||
|
||||
await DataUtils.getWidgetTreeList().then((List json) {
|
||||
List data = WidgetTree.insertDevPagesToList(json, StandardPages().getLocalList());
|
||||
Application.widgetTree = WidgetTree.buildWidgetTree(data);
|
||||
print("Application.widgetTree>>>> ${Application.widgetTree}");
|
||||
});
|
||||
db = Provider.db;
|
||||
runApp(new MyApp());
|
||||
}
|
||||
|
||||
|
@ -1,107 +1,107 @@
|
||||
//
|
||||
//import 'dart:async';
|
||||
//
|
||||
//import 'package:flutter_go/utils/sql.dart';
|
||||
//
|
||||
//abstract class CatInterface{
|
||||
// int get id;
|
||||
// //类目名称
|
||||
// String get name;
|
||||
// //描述
|
||||
// String get desc;
|
||||
// //第几级类目,默认 1
|
||||
// int get depth;
|
||||
// //父类目id,没有为 0
|
||||
// int get parentId;
|
||||
//}
|
||||
//
|
||||
//class Cat implements CatInterface {
|
||||
// int id;
|
||||
// String name;
|
||||
// String desc;
|
||||
// int depth;
|
||||
// int parentId;
|
||||
//
|
||||
// Cat({this.id, this.name, this.desc, this.depth, this.parentId});
|
||||
//
|
||||
// Cat.fromJSON(Map json)
|
||||
// : id = json['id'],
|
||||
// name = json['name'],
|
||||
// desc = json['desc'],
|
||||
// depth = json['depth'],
|
||||
// parentId = json['parentId'];
|
||||
//
|
||||
// String toString() {
|
||||
// return '(Cat $name)';
|
||||
// }
|
||||
//
|
||||
// Map toMap() {
|
||||
// return {
|
||||
// 'id': id,
|
||||
// 'name': name,
|
||||
// 'desc': desc,
|
||||
// 'depth': depth,
|
||||
// 'parentId': parentId
|
||||
// };
|
||||
// }
|
||||
// Map toSqlCondition() {
|
||||
// Map _map = this.toMap();
|
||||
// Map condition = {};
|
||||
// _map.forEach((k, value) {
|
||||
//
|
||||
// if (value != null) {
|
||||
//
|
||||
// condition[k] = value;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// if (condition.isEmpty) {
|
||||
// return {};
|
||||
// }
|
||||
//
|
||||
// return condition;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//
|
||||
//class CatControlModel{
|
||||
// final String table = 'cat';
|
||||
// Sql sql;
|
||||
// CatControlModel() {
|
||||
// sql = Sql.setTable(table);
|
||||
// }
|
||||
//
|
||||
// /// 获取一级类目
|
||||
// Future<List> mainList() async{
|
||||
// List listJson = await sql.getByCondition(conditions: {'parentId': 0});
|
||||
// List<Cat> cats = listJson.map((json) {
|
||||
// return new Cat.fromJSON(json);
|
||||
// }).toList();
|
||||
// return cats;
|
||||
// }
|
||||
//
|
||||
// // 获取Cat不同深度与parent的列表
|
||||
// Future<List<Cat>> getList([Cat cat]) async{
|
||||
//
|
||||
//
|
||||
// if (cat == null) {
|
||||
// cat = new Cat(depth: 1, parentId: 0);
|
||||
// }
|
||||
// // print("cat in getList ${cat.toMap()}");
|
||||
// List listJson = await sql.getByCondition(conditions: cat.toSqlCondition());
|
||||
// List<Cat> cats = listJson.map((json) {
|
||||
// return new Cat.fromJSON(json);
|
||||
// }).toList();
|
||||
// return cats;
|
||||
// }
|
||||
//
|
||||
// // 通过name获取Cat对象信息
|
||||
// Future<Cat> getCatByName(String name) async {
|
||||
// List json = await sql.getByCondition(conditions: {'name': name});
|
||||
// if (json.isEmpty) {
|
||||
// return null;
|
||||
// }
|
||||
// return new Cat.fromJSON(json.first);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_go/utils/sql.dart';
|
||||
|
||||
abstract class CatInterface{
|
||||
int get id;
|
||||
//类目名称
|
||||
String get name;
|
||||
//描述
|
||||
String get desc;
|
||||
//第几级类目,默认 1
|
||||
int get depth;
|
||||
//父类目id,没有为 0
|
||||
int get parentId;
|
||||
}
|
||||
|
||||
class Cat implements CatInterface {
|
||||
int id;
|
||||
String name;
|
||||
String desc;
|
||||
int depth;
|
||||
int parentId;
|
||||
|
||||
Cat({this.id, this.name, this.desc, this.depth, this.parentId});
|
||||
|
||||
Cat.fromJSON(Map json)
|
||||
: id = json['id'],
|
||||
name = json['name'],
|
||||
desc = json['desc'],
|
||||
depth = json['depth'],
|
||||
parentId = json['parentId'];
|
||||
|
||||
String toString() {
|
||||
return '(Cat $name)';
|
||||
}
|
||||
|
||||
Map toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'desc': desc,
|
||||
'depth': depth,
|
||||
'parentId': parentId
|
||||
};
|
||||
}
|
||||
Map toSqlCondition() {
|
||||
Map _map = this.toMap();
|
||||
Map condition = {};
|
||||
_map.forEach((k, value) {
|
||||
|
||||
if (value != null) {
|
||||
|
||||
condition[k] = value;
|
||||
}
|
||||
});
|
||||
|
||||
if (condition.isEmpty) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return condition;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CatControlModel{
|
||||
final String table = 'cat';
|
||||
Sql sql;
|
||||
CatControlModel() {
|
||||
sql = Sql.setTable(table);
|
||||
}
|
||||
|
||||
/// 获取一级类目
|
||||
Future<List> mainList() async{
|
||||
List listJson = await sql.getByCondition(conditions: {'parentId': 0});
|
||||
List<Cat> cats = listJson.map((json) {
|
||||
return new Cat.fromJSON(json);
|
||||
}).toList();
|
||||
return cats;
|
||||
}
|
||||
|
||||
// 获取Cat不同深度与parent的列表
|
||||
Future<List<Cat>> getList([Cat cat]) async{
|
||||
|
||||
|
||||
if (cat == null) {
|
||||
cat = new Cat(depth: 1, parentId: 0);
|
||||
}
|
||||
// print("cat in getList ${cat.toMap()}");
|
||||
List listJson = await sql.getByCondition(conditions: cat.toSqlCondition());
|
||||
List<Cat> cats = listJson.map((json) {
|
||||
return new Cat.fromJSON(json);
|
||||
}).toList();
|
||||
return cats;
|
||||
}
|
||||
|
||||
// 通过name获取Cat对象信息
|
||||
Future<Cat> getCatByName(String name) async {
|
||||
List json = await sql.getByCondition(conditions: {'name': name});
|
||||
if (json.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
return new Cat.fromJSON(json.first);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,21 +49,15 @@ class CollectionControlModel {
|
||||
List list = await sql.getByCondition();
|
||||
List<Collection> resultList = [];
|
||||
list.forEach((item){
|
||||
print('collection item =>> $item');
|
||||
print(item);
|
||||
resultList.add(Collection.fromJSON(item));
|
||||
});
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/// 通过收藏名获取router
|
||||
/// 因为名称很容易重复. 所以这里使用path router做唯一判断
|
||||
// Future getRouterByName(String name) async {
|
||||
// List list = await sql.getByCondition(conditions: {'name': name});
|
||||
// return list;
|
||||
// }
|
||||
|
||||
Future getRouterByUrl(String path) async {
|
||||
List list = await sql.getByCondition(conditions: {'router': path});
|
||||
// 通过收藏名获取router
|
||||
Future getRouterByName(String name) async {
|
||||
List list = await sql.getByCondition(conditions: {'name': name});
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -71,8 +65,4 @@ class CollectionControlModel {
|
||||
Future deleteByName(String name) async{
|
||||
return await sql.delete(name,'name');
|
||||
}
|
||||
// 通过path删除
|
||||
Future deleteByPath(String path) async{
|
||||
return await sql.delete(path,'router');
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
class ResponseData{
|
||||
int status;
|
||||
bool success;
|
||||
String message;
|
||||
|
||||
ResponseData(this.status, this.success,this.message);
|
||||
|
||||
ResponseData.fromJson(Map<String, dynamic> json)
|
||||
: status = json['status'],
|
||||
success = json['success'],
|
||||
message=json['message'];
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
'status': status,
|
||||
'success': success,
|
||||
'messsage': message
|
||||
};
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'status: $status ,success: $success,message: ${message.toString()}';
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +1,24 @@
|
||||
class UserInformation {
|
||||
class UserInfo {
|
||||
String username;
|
||||
int id;
|
||||
String avatarPic;
|
||||
String themeColor;
|
||||
String urlName;
|
||||
|
||||
UserInformation({
|
||||
UserInfo({
|
||||
this.avatarPic,
|
||||
this.id,
|
||||
this.themeColor,
|
||||
this.urlName,
|
||||
this.username,
|
||||
});
|
||||
|
||||
factory UserInformation.fromJson(Map<String, dynamic> json) {
|
||||
print('fromJOSN $json ${json['id'].runtimeType}');
|
||||
String name = json['name'];
|
||||
int userId ;
|
||||
if(json['name'] == null){
|
||||
name = json['url_name'];
|
||||
}
|
||||
if(json['id'].runtimeType == int){
|
||||
userId = json['id'];
|
||||
}else{
|
||||
userId = int.parse(json['id']);
|
||||
}
|
||||
return UserInformation(
|
||||
factory UserInfo.fromJson(Map<String, dynamic> json) {
|
||||
return UserInfo(
|
||||
avatarPic: json['avatar_pic'],
|
||||
id: userId,
|
||||
username: name,
|
||||
themeColor: json['theme_color']);
|
||||
id: int.parse(json['id']),
|
||||
username: json['name'],
|
||||
themeColor: json['theme_color'],
|
||||
urlName: json['url_name']);
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,4 @@ class UserInfoControlModel {
|
||||
Future deleteAll() async{
|
||||
return await sql.deleteAll();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
class Data {
|
||||
String version;
|
||||
String name;
|
||||
|
||||
Data.fromJson(Map<String, dynamic> json)
|
||||
: version = json['version'],
|
||||
name = json['name'];
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'name: $name ,version: $version';
|
||||
}
|
||||
}
|
||||
|
||||
class Version {
|
||||
Data data;
|
||||
int status;
|
||||
bool success;
|
||||
|
||||
Version.formJson(Map<String, dynamic> json)
|
||||
: status = json['status'],
|
||||
success = json['success'],
|
||||
data = Data.fromJson(json['data']);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'status: $status ,success: $success,date: ${data.toString()}';
|
||||
}
|
||||
}
|
@ -2,16 +2,9 @@
|
||||
import 'dart:async';
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_go/routers/application.dart";
|
||||
|
||||
import 'package:flutter_go/utils/sql.dart';
|
||||
|
||||
enum treeNode {
|
||||
CategoryComponent,
|
||||
WidgetLeaf
|
||||
}
|
||||
|
||||
//typedef aaa
|
||||
|
||||
abstract class WidgetInterface {
|
||||
int get id;
|
||||
|
||||
@ -149,226 +142,3 @@ class WidgetControlModel {
|
||||
return widgets;
|
||||
}
|
||||
}
|
||||
// 抽象类
|
||||
abstract class CommonItem<T> {
|
||||
int id;
|
||||
String name;
|
||||
int parentId;
|
||||
String type;
|
||||
List<CommonItem> children;
|
||||
String token;
|
||||
|
||||
/// 父级节点, 存放整个CommonItem对象node = ! null
|
||||
///
|
||||
CommonItem parent;
|
||||
String toString() {
|
||||
return "CommonItem {name: $name, type: $type, parentId: $parentId, token: $token, children长度 ${children}";
|
||||
}
|
||||
|
||||
T getChild(String token);
|
||||
T addChildren(Object item);
|
||||
// 从children树中. 查找任意子节点
|
||||
T find(String token, [CommonItem node]);
|
||||
}
|
||||
|
||||
// tree的group树干
|
||||
class CategoryComponent extends CommonItem {
|
||||
int id;
|
||||
String name;
|
||||
int parentId;
|
||||
CommonItem parent;
|
||||
String token;
|
||||
|
||||
|
||||
List<CommonItem> children = [];
|
||||
|
||||
String type = 'category';
|
||||
|
||||
CategoryComponent({
|
||||
@required this.id,
|
||||
@required this.name,
|
||||
@required this.parentId,
|
||||
this.type = 'categoryw',
|
||||
this.children,
|
||||
this.parent
|
||||
});
|
||||
CategoryComponent.fromJson(Map json) {
|
||||
if (json['id'] != null && json['id'].runtimeType == String) {
|
||||
this.id = int.parse(json['id']);
|
||||
} else {
|
||||
this.id = json['id'];
|
||||
}
|
||||
this.name = json['name'];
|
||||
this.parentId = json['parentId'];
|
||||
this.token = json['id'].toString() + json['type'];
|
||||
}
|
||||
void addChildren(Object item) {
|
||||
if (item is CategoryComponent) {
|
||||
CategoryComponent cate = item;
|
||||
cate.parent = this;
|
||||
this.children.add(
|
||||
cate
|
||||
);
|
||||
}
|
||||
if (item is WidgetLeaf) {
|
||||
WidgetLeaf widget = item;
|
||||
widget.parent = this;
|
||||
this.children.add(
|
||||
widget
|
||||
);
|
||||
}
|
||||
}
|
||||
@override
|
||||
CommonItem getChild(String token) {
|
||||
return children.firstWhere((CommonItem item) => item.token == token, orElse: () => null);
|
||||
}
|
||||
|
||||
@override
|
||||
CommonItem find(String token, [CommonItem node]) {
|
||||
CommonItem ret;
|
||||
if (node !=null) {
|
||||
if (node.token == token) {
|
||||
return node;
|
||||
} else {
|
||||
// 循环到叶子节点, 返回 空
|
||||
if (node.children == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < node.children.length; i++) {
|
||||
CommonItem temp = this.find(token, node.children[i]);
|
||||
if (temp != null) {
|
||||
ret = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = find(token, this);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// 叶子节点
|
||||
class WidgetLeaf extends CommonItem {
|
||||
int id;
|
||||
String name;
|
||||
int parentId;
|
||||
String display; // 展示类型, 区分老的widget文件下的详情
|
||||
String author; // 文档负责人
|
||||
String path; // 路由地址
|
||||
String pageId; // 界面ID
|
||||
CommonItem parent;
|
||||
|
||||
String type = 'widget';
|
||||
WidgetLeaf({
|
||||
@required this.id,
|
||||
@required this.name,
|
||||
@required this.display,
|
||||
this.author,
|
||||
this.path,
|
||||
this.pageId
|
||||
});
|
||||
|
||||
WidgetLeaf.fromJson(Map json) {
|
||||
if (json['id'] != null && json['id'].runtimeType == String) {
|
||||
this.id = int.parse(json['id']);
|
||||
} else {
|
||||
this.id = json['id'];
|
||||
}
|
||||
this.name = json['name'];
|
||||
this.display = json['display'];
|
||||
this.author = json['author'] ?? null;
|
||||
this.path = json['path'] ?? null;
|
||||
this.pageId = json['pageId'] ?? null;
|
||||
this.token = json['id'].toString() + json['type'];
|
||||
}
|
||||
@override
|
||||
CommonItem getChild(String token) {
|
||||
return null;
|
||||
}
|
||||
@override
|
||||
addChildren(Object item) {
|
||||
// TODO: implement addChildren
|
||||
return null;
|
||||
}
|
||||
|
||||
CommonItem find(String token, [CommonItem node]){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class WidgetTree {
|
||||
// 构建树型结构
|
||||
static CategoryComponent buildWidgetTree(List json, [parent]){
|
||||
CategoryComponent current;
|
||||
if (parent != null) {
|
||||
current = parent;
|
||||
} else {
|
||||
current = CategoryComponent(id: 0, name: 'root', parentId: null, children: []);
|
||||
}
|
||||
json.forEach((item) {
|
||||
// 归属分类级别
|
||||
if (['root', 'category'].indexOf(item['type']) != -1) {
|
||||
CategoryComponent cate = CategoryComponent.fromJson(item);
|
||||
if (cate.children != null) {
|
||||
buildWidgetTree(item['children'], cate);
|
||||
}
|
||||
current.addChildren(cate);
|
||||
} else {
|
||||
// 归属最后一层叶子节点
|
||||
WidgetLeaf cate = WidgetLeaf.fromJson(item);
|
||||
current.addChildren(cate);
|
||||
}
|
||||
});
|
||||
return current;
|
||||
}
|
||||
|
||||
static insertDevPagesToList(List list, List devPages) {
|
||||
List devChildren = [];
|
||||
int index = 9999999;
|
||||
if (Application.env == ENV.PRODUCTION) {
|
||||
return list;
|
||||
}
|
||||
devPages.forEach((item) {
|
||||
index++;
|
||||
if (item['id'] != null) {
|
||||
devChildren.add({
|
||||
"id": index.toString(),
|
||||
"name": item['name'],
|
||||
"parentId": "99999999999",
|
||||
"type": "widget",
|
||||
"display": "standard",
|
||||
"author": item['author'],
|
||||
"pageId": item['id']
|
||||
});
|
||||
}
|
||||
});
|
||||
list.forEach((item) {
|
||||
if (item['name'].toString().toUpperCase() == 'DEVELOPER') {
|
||||
List children = item['children'];
|
||||
children.insert(0, {
|
||||
"id": "99999999999",
|
||||
"name": "本地代码",
|
||||
"parentId": item['id'],
|
||||
"type": "category",
|
||||
"children": devChildren
|
||||
});
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
static CategoryComponent getCommonItemById(List<int> path, CategoryComponent root) {
|
||||
print("getCommonItemByPath $path");
|
||||
print("root $root");
|
||||
CommonItem childLeaf;
|
||||
int first = path.first;
|
||||
path = path.sublist(1);
|
||||
print("path:::: $path");
|
||||
if (path.length >= 0) {
|
||||
// childLeaf = root.getChild(path.first);
|
||||
}
|
||||
|
||||
|
||||
return childLeaf;
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
[{"name":"demoName","screenShot":"","author":"yourName","email":"yourEmail","desc":"这是一个测试的标准demo","id":"1a29aa8e_32ae_4241_9c8a_5c9e1f92b096"},{"name":"local","screenShot":"","author":"ab","email":"email","desc":"ags","id":"2c1d57d0_42ae_4241_9c8a_5c9e1f92b096"}]
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "demoName",
|
||||
"screenShot": "",
|
||||
"author":"yourName",
|
||||
"email": "yourEmail",
|
||||
"desc": "这是一个测试的标准demo",
|
||||
"id": "1a29aa8e_32ae_4241_9c8a_5c9e1f92b096"
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
//
|
||||
// Created with flutter go cli
|
||||
// User: yourName
|
||||
// Time: 2019-06-10 20:37:27.289097
|
||||
// email: yourEmail
|
||||
// desc: 这是一个测试的标准demo
|
||||
//
|
||||
|
||||
import 'src/index.dart';
|
||||
|
||||
var demoWidgets = [
|
||||
new Demo()
|
||||
];
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
@override
|
||||
_State createState() => _State();
|
||||
}
|
||||
|
||||
class _State extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: RaisedButton(onPressed: () {}, child: Text('我是md中引入的demo'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
import 'demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardDemo_demoName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096;
|
||||
import 'local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardDemo_local_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096;
|
||||
var demoObjects = {
|
||||
'1a29aa8e_32ae_4241_9c8a_5c9e1f92b096': StandardDemo_demoName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096.demoWidgets,
|
||||
'2c1d57d0_42ae_4241_9c8a_5c9e1f92b096': StandardDemo_local_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096.demoWidgets
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"70c429df-c27d-4843-8e28-1e6885c9276b": {
|
||||
"name": "button-red",
|
||||
"screenShot": "",
|
||||
"author": "sanfan",
|
||||
"email": "sanfan.hx@alibaba-inc.com",
|
||||
"desc": "desc",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "local",
|
||||
"screenShot": "",
|
||||
"author":"ab",
|
||||
"email": "email",
|
||||
"desc": "ags",
|
||||
"id": "2c1d57d0_42ae_4241_9c8a_5c9e1f92b096"
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
//
|
||||
// Created with flutter go cli
|
||||
// User: ab
|
||||
// Time: 2019-08-06 17:26:02.905889
|
||||
// email: email
|
||||
// desc: ags
|
||||
//
|
||||
|
||||
import 'src/index.dart';
|
||||
|
||||
var demoWidgets = [
|
||||
new Demo()
|
||||
];
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
@override
|
||||
_State createState() => _State();
|
||||
}
|
||||
|
||||
class _State extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Text("this is flutter go init demo"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
# 目录说明
|
||||
|
||||
本目录文件结构与文件命名, 使用cli进行更新
|
||||
|
||||
|
||||
# demos 目录文件结构
|
||||
|
||||
```
|
||||
demos
|
||||
├── ${demoName}-${author}-${32位demoID}
|
||||
│ ├── index.dart
|
||||
│ └── src
|
||||
│ ├── .demo.json
|
||||
│ └── ${demoName}.dart
|
||||
├── ...${demoName}-${author}-${32位demoID}
|
||||
├── index.dart
|
||||
├── info.json
|
||||
└── readme.md
|
||||
```
|
||||
|
@ -1,11 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
class WidgetName2Icon {
|
||||
static Map<String,dynamic> icons = {
|
||||
"Developer": Icons.developer_mode,
|
||||
"Standard": Icons.pages ,
|
||||
"Element":Icons.explicit,
|
||||
"Components":Icons.extension,
|
||||
"Theme":Icons.filter_b_and_w,
|
||||
"Themes":Icons.filter_b_and_w,
|
||||
"Form":Icons.table_chart,
|
||||
"Frame":Icons.aspect_ratio,
|
||||
"Media":Icons.subscriptions,
|
||||
|
@ -1,20 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluro/fluro.dart';
|
||||
|
||||
import 'package:flutter_go/utils/shared_preferences.dart';
|
||||
|
||||
import '../model/widget.dart';
|
||||
enum ENV {
|
||||
PRODUCTION,
|
||||
DEV,
|
||||
}
|
||||
class Application {
|
||||
/// 通过Application设计环境变量
|
||||
static ENV env = ENV.DEV;
|
||||
|
||||
static Router router;
|
||||
static TabController controller;
|
||||
static SpUtil sharePeference;
|
||||
static CategoryComponent widgetTree;
|
||||
static SpUtil sharePeferences;
|
||||
|
||||
static Map<String, String> github = {
|
||||
'widgetsURL':'https://github.com/alibaba/flutter-go/blob/develop/lib/widgets/',
|
||||
@ -22,15 +14,4 @@ class Application {
|
||||
//'master':'https://github.com/alibaba-paimai-frontend/flutter-common-widgets-app/tree/master/lib/widgets/'
|
||||
};
|
||||
|
||||
/// 所有获取配置的唯一入口
|
||||
Map<String, String> get config {
|
||||
if (Application.env == ENV.PRODUCTION) {
|
||||
return {};
|
||||
}
|
||||
if (Application.env == ENV.DEV) {
|
||||
return {};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,57 +7,38 @@ import 'package:flutter_go/components/full_screen_code_dialog.dart';
|
||||
import 'package:flutter_go/views/web_page/web_view_page.dart';
|
||||
import 'package:flutter_go/views/home.dart';
|
||||
import 'package:flutter_go/views/login_page/login_page.dart';
|
||||
import 'package:flutter_go/model/user_info.dart';
|
||||
import 'package:flutter_go/views/collection_page/collection_page.dart';
|
||||
import 'package:flutter_go/views/collection_page/collection_full_page.dart';
|
||||
import 'package:flutter_go/views/standard_demo_page/index.dart';
|
||||
import 'package:flutter_go/views/issuse_message_page/issuse_message_page.dart';
|
||||
|
||||
// app的首页
|
||||
var homeHandler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
return new AppPage(UserInformation(id: 0));
|
||||
return new AppPage();
|
||||
},
|
||||
);
|
||||
|
||||
var collectionFullHandler = new Handler(
|
||||
handlerFunc: (BuildContext context,Map<String,List<String>> params){
|
||||
bool hasLogined = params['hasLogin']?.first == 'true';
|
||||
return CollectionFullPage(hasLogined: hasLogined);
|
||||
}
|
||||
);
|
||||
|
||||
var collectionHandler = new Handler(
|
||||
handlerFunc: (BuildContext context,Map<String,List<String>> params){
|
||||
bool hasLogined = params['hasLogin']?.first == 'true';
|
||||
return CollectionPage(hasLogined: hasLogined);
|
||||
}
|
||||
);
|
||||
|
||||
var categoryHandler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
String ids = params["ids"]?.first;
|
||||
String name = params["type"]?.first;
|
||||
|
||||
return new CategoryHome(ids);
|
||||
return new CategoryHome(name);
|
||||
},
|
||||
);
|
||||
|
||||
var widgetNotFoundHandler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
return new WidgetNotFound();
|
||||
});
|
||||
return new WidgetNotFound();
|
||||
});
|
||||
var loginPageHandler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
return LoginPage();
|
||||
});
|
||||
return LoginPage();
|
||||
});
|
||||
|
||||
var fullScreenCodeDialog = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
String path = params['filePath']?.first;
|
||||
return new FullScreenCodeDialog(
|
||||
filePath: path,
|
||||
);
|
||||
});
|
||||
String path = params['filePath']?.first;
|
||||
return new FullScreenCodeDialog(
|
||||
filePath: path,
|
||||
);
|
||||
});
|
||||
|
||||
var webViewPageHand = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
@ -65,17 +46,3 @@ var webViewPageHand = new Handler(
|
||||
String url = params['url']?.first;
|
||||
return new WebViewPage(url, title);
|
||||
});
|
||||
|
||||
|
||||
var standardPageHandler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
String id = params['id']?.first;
|
||||
return StandardView(id: id);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
var issuesMessageHandler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
return IssuesMessagePage();
|
||||
});
|
||||
|
@ -2,21 +2,17 @@
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_go/utils/analytics.dart' show analytics;
|
||||
|
||||
import '../widgets/index.dart';
|
||||
import './router_handler.dart';
|
||||
import '../standard_pages/index.dart';
|
||||
|
||||
class Routes {
|
||||
static String root = "/";
|
||||
static String home = "/home";
|
||||
static String widgetDemo = '/widget-demo';
|
||||
static String codeView = '/code-view';
|
||||
static String githubCodeView = '/github-code-view';
|
||||
static String webViewPage = '/web-view-page';
|
||||
static String loginPage = '/loginpage';
|
||||
static String issuesMessage='/issuesMessage';
|
||||
static String collectionPage = '/collection-page';
|
||||
static String collectionFullPage = '/collection-full-page';
|
||||
static String standardPage = '/standard-page/:id';
|
||||
|
||||
static void configureRoutes(Router router) {
|
||||
List widgetDemosList = new WidgetDemoList().getDemos();
|
||||
@ -24,14 +20,12 @@ class Routes {
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
});
|
||||
router.define(home, handler: homeHandler);
|
||||
router.define(collectionPage,handler:collectionHandler);
|
||||
router.define(collectionFullPage,handler:collectionFullHandler);
|
||||
router.define('/category/:ids', handler: categoryHandler);
|
||||
|
||||
router.define('/category/:type', handler: categoryHandler);
|
||||
router.define('/category/error/404', handler: widgetNotFoundHandler);
|
||||
router.define(loginPage, handler: loginPageHandler);
|
||||
router.define(codeView,handler:fullScreenCodeDialog);
|
||||
router.define(webViewPage,handler:webViewPageHand);
|
||||
router.define(issuesMessage, handler: issuesMessageHandler);
|
||||
widgetDemosList.forEach((demo) {
|
||||
Handler handler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
@ -42,10 +36,5 @@ class Routes {
|
||||
});
|
||||
router.define('${demo.routerName}', handler: handler);
|
||||
});
|
||||
router.define(standardPage,handler:standardPageHandler);
|
||||
// router.define(webViewPage,handler:webViewPageHand);
|
||||
// standardPages.forEach((String id, String md) => {
|
||||
//
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
[{"name":"local","screenShot":"","author":"hnaxu","title":"本地","email":"hanxu@qq.com","desc":"desc","id":"5d7178d0_42ae_4241_9c8a_5c9e1f92b096"},{"name":"test","screenShot":"","author":"abc","title":"ya","email":"adsf.com","desc":"desc","id":"84f38e00_42ae_4241_9c8a_5c9e1f92b096"},{"name":"standard","screenShot":"","author":"sanfan","title":"介绍页","email":"hanxu317@qq.com","desc":"desc","id":"ee4feb8e_32ae_4241_9c8a_5c9e1f92b096"},{"name":"standard_for_slider","screenShot":"","author":"sanfan","title":"slider组件","email":"hanxu@qq.com","desc":"slider, new Slider","id":"8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096"}]
|
@ -1,35 +0,0 @@
|
||||
|
||||
import 'local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_local_5d7178d0_42ae_4241_9c8a_5c9e1f92b096;
|
||||
import 'test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_test_84f38e00_42ae_4241_9c8a_5c9e1f92b096;
|
||||
import 'standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_standard_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096;
|
||||
import 'standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_standard_for_slider_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096;
|
||||
class StandardPages {
|
||||
Map<String, String> standardPages;
|
||||
Map<String, String> getPages() {
|
||||
return {
|
||||
"0": "0" ,
|
||||
"5d7178d0_42ae_4241_9c8a_5c9e1f92b096" : StandardPage_local_5d7178d0_42ae_4241_9c8a_5c9e1f92b096.getMd()
|
||||
,
|
||||
"84f38e00_42ae_4241_9c8a_5c9e1f92b096" : StandardPage_test_84f38e00_42ae_4241_9c8a_5c9e1f92b096.getMd()
|
||||
,
|
||||
"ee4feb8e_32ae_4241_9c8a_5c9e1f92b096" : StandardPage_standard_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096.getMd()
|
||||
,
|
||||
"8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096" : StandardPage_standard_for_slider_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096.getMd()
|
||||
};
|
||||
}
|
||||
List<Map<String, String>> getLocalList() {
|
||||
return [
|
||||
{},
|
||||
{ "id": "5d7178d0_42ae_4241_9c8a_5c9e1f92b096", "name": "local", "email": "hanxu@qq.com", "author": "hnaxu"}
|
||||
,
|
||||
{ "id": "84f38e00_42ae_4241_9c8a_5c9e1f92b096", "name": "test", "email": "adsf.com", "author": "abc"}
|
||||
,
|
||||
{ "id": "ee4feb8e_32ae_4241_9c8a_5c9e1f92b096", "name": "standard", "email": "hanxu317@qq.com", "author": "sanfan"}
|
||||
,
|
||||
{ "id": "8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096", "name": "standard_for_slider", "email": "hanxu@qq.com", "author": "sanfan"}
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "local",
|
||||
"screenShot": "",
|
||||
"author":"hnaxu",
|
||||
"title":"本地",
|
||||
"email": "hanxu@qq.com",
|
||||
"desc": "desc",
|
||||
"id": "5d7178d0_42ae_4241_9c8a_5c9e1f92b096"
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
String getMd() {
|
||||
return """
|
||||
# 标准的详情页
|
||||
|
||||
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
|
||||
|
||||
您可以通过goCli创建详情页所需要的demo
|
||||
|
||||
```
|
||||
goCLi createDemo
|
||||
```
|
||||
|
||||
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
|
||||
|
||||
[✓] 请输入新增加的demo名称? demoName
|
||||
|
||||
[✓] 请输入您的姓名(使用英文) yourName
|
||||
|
||||
[✓] 请输入您的github的email地址 yourEmail
|
||||
|
||||
[✓] 请输入您demo的描述 这是一个测试的标准demo
|
||||
|
||||
|
||||
在完成以上操作后, 可以得到这样的输出:
|
||||
|
||||
|
||||
```
|
||||
------------------
|
||||
您新增的组件信息如下
|
||||
==================
|
||||
{
|
||||
name : demoName
|
||||
author : yourName
|
||||
email : yourEmail
|
||||
desc : 这是一个测试的标准demo
|
||||
}
|
||||
==================
|
||||
[✓] Is this the config you want ? (Y/n) y
|
||||
{
|
||||
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
}
|
||||
|
||||
```
|
||||
您可以在任意详情页中, 通过以下方式调用
|
||||
|
||||
```
|
||||
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
```""";
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
# 标准的详情页
|
||||
|
||||
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
|
||||
|
||||
您可以通过goCli创建详情页所需要的demo
|
||||
|
||||
```
|
||||
goCLi createDemo
|
||||
```
|
||||
|
||||
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
|
||||
|
||||
[✓] 请输入新增加的demo名称? demoName
|
||||
|
||||
[✓] 请输入您的姓名(使用英文) yourName
|
||||
|
||||
[✓] 请输入您的github的email地址 yourEmail
|
||||
|
||||
[✓] 请输入您demo的描述 这是一个测试的标准demo
|
||||
|
||||
|
||||
在完成以上操作后, 可以得到这样的输出:
|
||||
|
||||
|
||||
```
|
||||
------------------
|
||||
您新增的组件信息如下
|
||||
==================
|
||||
{
|
||||
name : demoName
|
||||
author : yourName
|
||||
email : yourEmail
|
||||
desc : 这是一个测试的标准demo
|
||||
}
|
||||
==================
|
||||
[✓] Is this the config you want ? (Y/n) y
|
||||
{
|
||||
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
}
|
||||
|
||||
```
|
||||
您可以在任意详情页中, 通过以下方式调用
|
||||
|
||||
```
|
||||
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
```
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "standard_for_slider",
|
||||
"screenShot": "",
|
||||
"author":"sanfan",
|
||||
"title":"slider组件",
|
||||
"email": "hanxu@qq.com",
|
||||
"desc": "slider, new Slider",
|
||||
"id": "8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096"
|
||||
}
|
||||
|
@ -1,61 +0,0 @@
|
||||
String getMd() {
|
||||
return """
|
||||
# Slider Page
|
||||
|
||||
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
|
||||
|
||||
您可以通过goCli创建详情页所需要的demo
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
goCLi createDemo
|
||||
```
|
||||
|
||||
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
|
||||
|
||||
[✓] 请输入新增加的demo名称? demoName
|
||||
|
||||
[✓] 请输入您的姓名(使用英文) yourName
|
||||
|
||||
[✓] 请输入您的github的email地址 yourEmail
|
||||
|
||||
[✓] 请输入您demo的描述 这是一个测试的标准demo
|
||||
|
||||
|
||||
在完成以上操作后, 可以得到这样的输出:
|
||||
|
||||
|
||||
```
|
||||
------------------
|
||||
您新增的组件信息如下
|
||||
==================
|
||||
{
|
||||
name : demoName
|
||||
author : yourName
|
||||
email : yourEmail
|
||||
desc : 这是一个测试的标准demo
|
||||
}
|
||||
==================
|
||||
[✓] Is this the config you want ? (Y/n) y
|
||||
{
|
||||
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
}
|
||||
|
||||
```
|
||||
您可以在任意详情页中, 通过以下方式调用
|
||||
|
||||
```
|
||||
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
```
|
||||
|
||||
调用效果:
|
||||
|
||||
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]""";
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,55 +0,0 @@
|
||||
# Slider Page
|
||||
|
||||
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
|
||||
|
||||
您可以通过goCli创建详情页所需要的demo
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
goCLi createDemo
|
||||
```
|
||||
|
||||
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
|
||||
|
||||
[✓] 请输入新增加的demo名称? demoName
|
||||
|
||||
[✓] 请输入您的姓名(使用英文) yourName
|
||||
|
||||
[✓] 请输入您的github的email地址 yourEmail
|
||||
|
||||
[✓] 请输入您demo的描述 这是一个测试的标准demo
|
||||
|
||||
|
||||
在完成以上操作后, 可以得到这样的输出:
|
||||
|
||||
|
||||
```
|
||||
------------------
|
||||
您新增的组件信息如下
|
||||
==================
|
||||
{
|
||||
name : demoName
|
||||
author : yourName
|
||||
email : yourEmail
|
||||
desc : 这是一个测试的标准demo
|
||||
}
|
||||
==================
|
||||
[✓] Is this the config you want ? (Y/n) y
|
||||
{
|
||||
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
}
|
||||
|
||||
```
|
||||
您可以在任意详情页中, 通过以下方式调用
|
||||
|
||||
```
|
||||
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
```
|
||||
|
||||
调用效果:
|
||||
|
||||
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "standard",
|
||||
"screenShot": "",
|
||||
"author":"sanfan",
|
||||
"title":"介绍页",
|
||||
"email": "hanxu317@qq.com",
|
||||
"desc": "desc",
|
||||
"id": "ee4feb8e_32ae_4241_9c8a_5c9e1f92b096"
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
String getMd() {
|
||||
return """
|
||||
# 标准的详情页
|
||||
|
||||
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
|
||||
|
||||
您可以通过goCli创建详情页所需要的demo
|
||||
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
|
||||
|
||||
```
|
||||
goCLi createDemo
|
||||
```
|
||||
|
||||
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
|
||||
|
||||
[✓] 请输入新增加的demo名称? demoName
|
||||
|
||||
[✓] 请输入您的姓名(使用英文) yourName
|
||||
|
||||
[✓] 请输入您的github的email地址 yourEmail
|
||||
|
||||
[✓] 请输入您demo的描述 这是一个测试的标准demo
|
||||
|
||||
|
||||
在完成以上操作后, 可以得到这样的输出:
|
||||
|
||||
|
||||
```
|
||||
------------------
|
||||
您新增的组件信息如下
|
||||
==================
|
||||
{
|
||||
name : demoName
|
||||
author : yourName
|
||||
email : yourEmail
|
||||
desc : 这是一个测试的标准demo
|
||||
}
|
||||
==================
|
||||
[✓] Is this the config you want ? (Y/n) y
|
||||
{
|
||||
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
}
|
||||
|
||||
```
|
||||
您可以在任意详情页中, 通过以下方式调用
|
||||
|
||||
```
|
||||
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
```""";
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
# 标准的详情页
|
||||
|
||||
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
|
||||
|
||||
您可以通过goCli创建详情页所需要的demo
|
||||
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
|
||||
|
||||
```
|
||||
goCLi createDemo
|
||||
```
|
||||
|
||||
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
|
||||
|
||||
[✓] 请输入新增加的demo名称? demoName
|
||||
|
||||
[✓] 请输入您的姓名(使用英文) yourName
|
||||
|
||||
[✓] 请输入您的github的email地址 yourEmail
|
||||
|
||||
[✓] 请输入您demo的描述 这是一个测试的标准demo
|
||||
|
||||
|
||||
在完成以上操作后, 可以得到这样的输出:
|
||||
|
||||
|
||||
```
|
||||
------------------
|
||||
您新增的组件信息如下
|
||||
==================
|
||||
{
|
||||
name : demoName
|
||||
author : yourName
|
||||
email : yourEmail
|
||||
desc : 这是一个测试的标准demo
|
||||
}
|
||||
==================
|
||||
[✓] Is this the config you want ? (Y/n) y
|
||||
{
|
||||
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
|
||||
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
}
|
||||
|
||||
```
|
||||
您可以在任意详情页中, 通过以下方式调用
|
||||
|
||||
```
|
||||
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
|
||||
```
|