diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md
new file mode 100644
index 00000000..bde1342e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -0,0 +1,26 @@
+---
+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 链接代码)
diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
new file mode 100644
index 00000000..478e88df
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -0,0 +1,18 @@
+---
+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**, 谢谢
+
+
+### 您的功能需求是否与哪些问题有关?
+
+### 描述您想要的功能.
diff --git a/.github/ISSUE_TEMPLATE/page-about.md b/.github/ISSUE_TEMPLATE/page-about.md
new file mode 100644
index 00000000..d79ca10a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/page-about.md
@@ -0,0 +1,62 @@
+---
+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"
+}
+```
+
+## 引入第三方包的文件与版本号(如果有引入, 请标明)
+
+
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 00000000..0a142371
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,14 @@
+---
+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**, 谢谢
+
diff --git a/.github/issue_template.md b/.github/issue_template.md
deleted file mode 100644
index e69de29b..00000000
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index e69de29b..aca9f499 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -0,0 +1,19 @@
+#### What does this PR do?
+
+[TrelloCard/Issue/Story](LINK_TO_STORY)
+
+##### Why are we doing this? Any context or related work?
+
+#### Where should a reviewer start?
+
+#### Manual testing steps?
+
+#### Screenshots
+
+---
+
+#### Database changes
+
+#### Deployment instructions
+
+#### New ENV variables
diff --git a/.gitignore b/.gitignore
index 4f66b1c5..bdc2c7bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@
.metadata
+
# IntelliJ related
*.ipr
@@ -33,9 +34,14 @@
.flutter-plugins
.packages
.pub-cache/
+pubspec.lock
.pub/
/build/
+# goCli related
+go-cli/.packages
+go-cli/pubspec.lock
+
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
diff --git a/CHANGE-LOG.md b/CHANGE-LOG.md
index a625fbfe..88b73e46 100644
--- a/CHANGE-LOG.md
+++ b/CHANGE-LOG.md
@@ -1,86 +1,358 @@
## 更新日志
-
+#### 8/28/2019
+ - [x] Modify: IsOpen 的移步判断
+ - [x] Update index.md
+ - [x] Update index.dart
+#### 5/28/2019
+ - [x] change:async master
+ - [x] modfiy:应用商店
+ - [x] Merge pull request #222 from DeckeDeng/develop
+ - [x] add home scaffold
+#### 8/22/2019
+ - [x] Merge pull request #322 from alibaba/beta
+ - [x] Modify: web view 方法回退
+ - [x] Merge pull request #321 from alibaba/beta
+ - [x] Merge pull request #317 from alibaba/beta
+ - [x] Merge branch 'master' into beta
+ - [x] Update contribute.md
+#### 8/12/2019
+ - [x] update: doc & tpl
+ - [x] Update tpl.md
+ - [x] Merge pull request #313 from Nealyang/beta
+ - [x] 添加登陆错误提醒
+#### 3/11/2019
+ - [x] Update README-en.md
+#### 8/15/2019
+ - [x] update: router path
+ - [x] ci
+ - [x] update: view remote code
+ - [x] 整理文件
+#### 8/13/2019
+ - [x] Modify
+ - [x] Modfiy:
+ - [x] update: page issue template
+#### 8/1/2019
+ - [x] merge code
+#### 7/29/2019
+ - [x] Merge branch 'master' of github.com:alibaba/flutter-go into beta
+ - [x] delete .github no use file
+ - [x] docs(update: pr template):
+ - [x] del: no use file
+ - [x] Merge branch 'master' of github.com:alibaba/flutter-go
+ - [x] docs(add widget about issue):
+ - [x] Merge branch 'temp' into beta
+ - [x] 迁移位置
+ - [x] update: template
+ - [x] update: 处理合并导致的总理2
+#### 8/7/2019
+ - [x] fix bug
+ - [x] Merge pull request #302 from Nealyang/beta
+ - [x] remove get collection
+ - [x] tep
+ - [x] update: 完成markdown动态更新
+#### 8/8/2019
+ - [x] remove user appBar
+ - [x] bottomBar 添加个人中心
+ - [x] Merge pull request #309 from DeckeDeng/beta2
+ - [x] ios project.pbxproj
+ - [x] Merge pull request #308 from DeckeDeng/beta2
+ - [x] Merge pull request #304 from Nealyang/beta
+ - [x] 修改 ios 配置文件
+ - [x] update: 临时增加code-review页
+#### 6/28/2019
+ - [x] Merge pull request #264 from DeckeDeng/beta2
+ - [x] Merge pull request #263 from DeckeDeng/beta2
+ - [x] Merge branch 'beta' into beta2
+ - [x] 消息反馈页面
+#### 2/1/2019
+ - [x] Merge branch 'develop' of https://github.com/alibaba/flutter-go into develop
+ - [x] feat:android splash
+ - [x] feat:add android splash
+ - [x] Merge pull request #116 from hanxu317317/develop
+ - [x] docs(更新Readme中环境信息):
+ - [x] Merge pull request #115 from hanxu317317/develop
+ - [x] feat(首页欢迎图, 加入第一次访问判断.):
+ - [x] Merge branch 'develop' into sptil
+ - [x] update: ios启动图描述
+ - [x] fix:yaml
+ - [x] fix:
+ - [x] Merge pull request #113 from hanxu317317/develop
+ - [x] fix:mtl buidl apk test
+ - [x] refactor(conflict):
+ - [x] add sp
+ - [x] fix(解决由于flutter 版本问题导致的报错):
+ - [x] fix:back
+ - [x] fix:package err
+ - [x] fix:modify github package name fail and test
+ - [x] fix:build before modify package's name
+#### 7/12/2019
+ - [x] Merge pull request #279 from Nealyang/beta
+ - [x] add
+ - [x] d
+#### 8/6/2019
+ - [x] issuse message
+ - [x] Merge pull request #294 from Nealyang/beta
+ - [x] 修改为线上地址
+ - [x] 个人中心、收藏、搜索
+#### 7/25/2019
+ - [x] Merge branch 'beta' of github.com:alibaba/flutter-go
+#### 7/23/2019
+ - [x] zefyr
+#### 7/22/2019
+ - [x] feature:个人设置
+#### 7/15/2019
+ - [x] appstore 反馈错误
+ - [x] readme错误
+ - [x] 标题错误,跳转错误
+#### 7/11/2019
+ - [x] update: 迁移新老数据结构与收藏
+ - [x] update: 增加环境配置. 挂载在application静态属性上
+ - [x] update: 修改文章
+#### 4/8/2019
+ - [x] flutter project switch ios or android by androidstudio
+ - [x] android permission
+ - [x] remove extra files
+#### 6/18/2019
+ - [x] 推送,ios/android,test
+#### 6/15/2019
+ - [x] 删除node相关
+ - [x] Merge branch 'develop' of github.com:alibaba/flutter-common-widgets-app into web
+ - [x] update: 完善demo
+ - [x] update: 界面增加title属性
+ - [x] add: cli使用说明
+#### 6/11/2019
+ - [x] update: 替换markdown包引入方式
+ - [x] add: 加入标准page模板
+ - [x] 加入标准page
+ - [x] 加入初始化demo
+ - [x] 引入三方flutter_markdown gi
+#### 6/10/2019
+ - [x] Merge pull request #249 from Nealyang/beta
+ - [x] 添加收藏功能
+ - [x] update: 标准化代码.
+ - [x] goCli 完成90%
+#### 6/4/2019
+ - [x] markdown
+ - [x] 加入初始gocli
+ - [x] add page demo
+ - [x] 增加page的统一入口
+ - [x] add demos packges
+ - [x] Merge pull request #240 from Nealyang/beta
+ - [x] 退出登陆、feedback 测试
+#### 5/31/2019
+ - [x] 添加个人中心
+#### 5/30/2019
+ - [x] 首页不刷新
+ - [x] Merge pull request #1 from forever-713/zuston-patch-1
+ - [x] Fix App name error
+#### 5/29/2019
+ - [x] 添加 github oAuth 认证,添加错误提醒
+#### 5/23/2019
+ - [x] readme.md
+ - [x] Merge pull request #219 from weikx/develop
+ - [x] Merge pull request #215 from DeckeDeng/develop
+ - [x] delete firstPage
+ - [x] de
+ - [x] Test:测试分支
+ - [x] Merge branch 'develop' of https://github.com/weikx/flutter-go into develop
+ - [x] Change word 'Free' into 'Three'
+ - [x] Chang word 'Free' into 'Three'
+#### 5/17/2019
+ - [x] Merge pull request #216 from alibaba/master
+#### 5/14/2019
+ - [x] update version
+#### 2/3/2019
+ - [x] fix(解决ios报错):
+ - [x] Merge pull request #119 from Nealyang/master
+ - [x] fix:fix code conflic
+ - [x] fix: code conflict
+ - [x] Merge branch 'develop' into master
+ - [x] fix:view code
+ - [x] Merge pull request #118 from alibaba/dev/yisheng
+#### 5/9/2019
+ - [x] test version
+#### 5/7/2019
+ - [x] merge origin
+ - [x] add update test
+ - [x] Merge branch 'develop' of github.com:alibaba/flutter-go
+ - [x] cookie 校验
+ - [x] modify home.dart bottom tab
+ - [x] session 验证
+ - [x] merge develop
+ - [x] 登陆
+ - [x] Merge pull request #205 from alibaba/dev/sanl
+ - [x] modify bottom tab
+ - [x] delete ios file
+ - [x] add apk
+ - [x] Login 登陆界面
+#### 5/6/2019
+ - [x] add login
+#### 5/1/2019
+ - [x] Modfiy: 改造业内资讯页面
+#### 4/30/2019
+ - [x] Add:二期开发-重构首页布局
+ - [x] gradle 4.10.2 包添加AndroidX配置
+#### 2/19/2019
+ - [x] packagename
+ - [x] Merge pull request #148 from alibaba/dev/yisheng
+ - [x] refactor:按照代码规范调整import 文件
+ - [x] update: 规范
+ - [x] Merge pull request #147 from Nealyang/master
+ - [x] fix:修复TabBar demo
+ - [x] Merge pull request #146 from Nealyang/master
+ - [x] refactor: 根据规范重构代码
+ - [x] Merge pull request #145 from alibaba/dev/yisheng
+ - [x] refactor:按照代码规范调整markdow解析
+ - [x] refactor(规范化代码):
+ - [x] Merge pull request #143 from Nealyang/master
+ - [x] refactor:按规范修改代码、注释等
+ - [x] Merge pull request #142 from Nealyang/master
+ - [x] commit
+ - [x] Merge pull request #141 from Nealyang/master
+ - [x] Merge pull request #140 from Nealyang/master
+ - [x] Merge pull request #135 from hanxu317317/develop
+ - [x] Merge branch 'develop' into develop
+ - [x] Merge pull request #139 from Nealyang/master
+ - [x] Merge branch 'develop' of github.com:alibaba/flutter-common-widgets-app
+ - [x] refactor:根据规范,重构代码
+ - [x] modify code comments
+ - [x] Merge pull request #138 from alibaba/dev/yisheng
+ - [x] refactor:按照代码规范调整注释文件
+#### 4/29/2019
+ - [x] test app store
+ - [x] Merge branch 'master' into dev/sanl
+ - [x] 修改bug
+#### 4/26/2019
+ - [x] Debug: GoogleService-Info.plist 位置问题 导致错误
+ - [x] change LICENSE date
+ - [x] 变更许可
+ - [x] Merge pull request #189 from alibaba/develop
+ - [x] change License
+#### 4/22/2019
+ - [x] release apk
+ - [x] Merge pull request #192 from alibaba/dev/yisheng
+ - [x] 格式化
+ - [x] Merge pull request #191 from alibaba/dev/yisheng
+ - [x] Delete:删除 .gradle 文件夹
+ - [x] Merge pull request #188 from alibaba/dev/yisheng
+#### 4/17/2019
+ - [x] gridView 网格效果 图片流
+ - [x] 添加渐变效果/网络图片覆盖图层渲染/图片填充
+#### 1/31/2019
+ - [x] Merge pull request #112 from alibaba/dev/yisheng
+ - [x] Debug:canvas 路由问题
+ - [x] Merge pull request #111 from alibaba/dev/yisheng
+ - [x] feat: Canvas 细化各种方法
+ - [x] add file
+ - [x] fix:code
+ - [x] feat(加入启动图, 时间2秒):
+#### 4/12/2019
+ - [x] update: 修改错字
+ - [x] Merge pull request #180 from alibaba/develop
+ - [x] add: doc roadmap
+#### 4/1/2019
+ - [x] remove recruit
+ - [x] move recruit
+#### 3/31/2019
+ - [x] 增加模板
+ - [x] Create pull_request_template.md
+ - [x] Delete .github
+ - [x] Create .github
+ - [x] Merge pull request #173 from alibaba/master
+#### 2/2/2019
+ - [x] fix: 部分代码添加 mounted
+ - [x] Merge pull request #117 from alibaba/dev/yisheng
+ - [x] fix:修复Canvas组件收藏的bug
+#### 2/20/2019
+ - [x] 同步文件
+ - [x] Merge pull request #152 from hanxu317317/develop
+ - [x] 更新跳转页方式
+ - [x] modify logo
+ - [x] Merge pull request #149 from hanxu317317/develop
+ - [x] fix(解决返回首页报错的问题):
+#### 2/11/2019
+ - [x] fix: 部分代码 analysis 解决
#### 2019-2-5
- - [x] 处理因为flutter版本导致的项目运行不起来
- - [x] 更新readme, 加入开发日志, 与相关说明
- - [x] 加入 首页欢迎效果图
- - [x] refactor(整理richText的说明):
- - [x] 解决一些页面的code演示打不开的问题
- - [x] add:开发规范
- - [x] add:版本更新历史链接
- - [x] Update README.md
- - [x] add:添加版本号
- - [x] feat:添加代码开发规范
- - [x] refactor(update: version & fiexed warns):
- - [x] fix(solve conflict):
- - [x] modify:toast and andrid apk label
- - [x] Add:自动 pr 工具抓取器,抓取两周前至今的,提交数据,并去重
- - [x] fix:fluttetToast backHome
- - [x] fix:modified the style of toast && remote files
- - [x] chore(删除tools/log.json):
- - [x] 重构文件结构
- - [x] 关于手册图标更换
- - [x] 增加demo: CupertinoNavigationBar CupertinoPageRoute CupertinoPageScaffold CupertinoPicker,CupertinoPopupSurface CupertinoTimerPickerDemo
+- [x] 处理因为flutter版本导致的项目运行不起来
+- [x] 更新readme, 加入开发日志, 与相关说明
+- [x] 加入 首页欢迎效果图
+- [x] refactor(整理richText的说明):
+- [x] 解决一些页面的code演示打不开的问题
+- [x] add:开发规范
+- [x] add:版本更新历史链接
+- [x] Update README.md
+- [x] add:添加版本号
+- [x] feat:添加代码开发规范
+- [x] refactor(update: version & fiexed warns):
+- [x] fix(solve conflict):
+- [x] modify:toast and andrid apk label
+- [x] Add:自动 pr 工具抓取器,抓取两周前至今的,提交数据,并去重
+- [x] fix:fluttetToast backHome
+- [x] fix:modified the style of toast && remote files
+- [x] chore(删除tools/log.json):
+- [x] 重构文件结构
+- [x] 关于手册图标更换
+- [x] 增加demo: CupertinoNavigationBar CupertinoPageRoute CupertinoPageScaffold CupertinoPicker,CupertinoPopupSurface CupertinoTimerPickerDemo
#### 2019-1-24
- - [x] 功能:更新小部件的图标
- - [x] 功能:添加CupertinoTimerPickerDemo
- - [x] 调试:消除警告
- - [x] 修复:关于手册图标更换
- - [x] 添加:文案描述
- - [x] 添加:CupertinoPicker,CupertinoPopupSurface
+- [x] 功能:更新小部件的图标
+- [x] 功能:添加CupertinoTimerPickerDemo
+- [x] 调试:消除警告
+- [x] 修复:关于手册图标更换
+- [x] 添加:文案描述
+- [x] 添加:CupertinoPicker,CupertinoPopupSurface
#### 2019-1-23
- - [x] 修复: 导航栏home返回报错
- - [x] 修复:收集错误
- - [x] 添加:CupertinoNavigationBar CupertinoPageRoute CupertinoPageScaffold
+- [x] 修复: 导航栏home返回报错
+- [x] 修复:收集错误
+- [x] 添加:CupertinoNavigationBar CupertinoPageRoute CupertinoPageScaffold
#### 2019-1-22
- - [x] 功能:在Allsimon拉请求中添加英文简介
+- [x] 功能:在Allsimon拉请求中添加英文简介
#### 2019-1-21
- - [x] 功能:Cupertino的子项
+- [x] 功能:Cupertino的子项
#### 2019-1-20
- - [x] 功能:CupertinoSwitch演示
- - [x] 功能:为搜索列表加入图标
- - [x] 功能:CupertinoSliverRefreshControl演示
- - [x] 功能:CupertinoSliverNavigationBar演示
+- [x] 功能:CupertinoSwitch演示
+- [x] 功能:为搜索列表加入图标
+- [x] 功能:CupertinoSliverRefreshControl演示
+- [x] 功能:CupertinoSliverNavigationBar演示
#### 2019-1-18
- - [x] 更新:SharedPreferences保存数据和android设备布局溢出
- - [x] 功能:添加CupertinoScrollbar演示
- - [x] 功能:第四页暂时用欢迎页替代。后期再开发
+- [x] 更新:SharedPreferences保存数据和android设备布局溢出
+- [x] 功能:添加CupertinoScrollbar演示
+- [x] 功能:第四页暂时用欢迎页替代。后期再开发
#### 2019-1-17
- - [x] 添加:+许可证
+- [x] 添加:+许可证
#### 2019-1-16
- - [x] 转换:将README翻译为En语言环境
- - [x] 功能:CupertinoScrollbar演示
+- [x] 转换:将README翻译为En语言环境
+- [x] 功能:CupertinoScrollbar演示
#### 2019-1-14
- - [x] 添加:增加手册页面
- - [x] 功能:文字演示
- - [x] 重构:修改过的图标
- - [x] 重构:文档,文章,组件收藏,新增webView
- - [x] 重构:修改过的演示
- - [x] 重构:代码视图
- - [x] 更新:版本 和readme.md
- - [x] 修改:添加代码视图
- - [x] 功能:添加搜索历史记录板
- - [x] 修改:列出加标头错误
+- [x] 添加:增加手册页面
+- [x] 功能:文字演示
+- [x] 重构:修改过的图标
+- [x] 重构:文档,文章,组件收藏,新增webView
+- [x] 重构:修改过的演示
+- [x] 重构:代码视图
+- [x] 更新:版本 和readme.md
+- [x] 修改:添加代码视图
+- [x] 功能:添加搜索历史记录板
+- [x] 修改:列出加标头错误
#### 2019-1-15
- - [x] 功能:welcomepage
+- [x] 功能:welcomepage
#### 2019-1-13
- - [x] 添加:一些输入描述
- - [x] 功能:加入GridPaper&SliverGrid
- - [x] 重构:修改db
- - [x] 重构:删除数据库 TabBarView
- - [x] 添加:网格视图
- - [x] 修改:checkbosListTile 错误
- - [x] 修改:自动提示文案
- - [x] 功能:增加免责声明,声明组件,自动弹出,左上角入口
- - [x] 重构:整理数据库初始逻辑,判断数据库完整性,判断是否存在已知的cat,widget,collection 三张表。
- - [x] 修复:DialogDemo,无法关闭的问题
+- [x] 添加:一些输入描述
+- [x] 功能:加入GridPaper&SliverGrid
+- [x] 重构:修改db
+- [x] 重构:删除数据库 TabBarView
+- [x] 添加:网格视图
+- [x] 修改:checkbosListTile 错误
+- [x] 修改:自动提示文案
+- [x] 功能:增加免责声明,声明组件,自动弹出,左上角入口
+- [x] 重构:整理数据库初始逻辑,判断数据库完整性,判断是否存在已知的cat,widget,collection 三张表。
+- [x] 修复:DialogDemo,无法关闭的问题
#### 2019-1-12
- - [x] 修复:icon没有,但内容有的,组件,给补充了icon
- - [x] 修改:1.整理文件 2.修正分析
- - [x] 更新:flutter_rookie_book => flutter_go
- - [x] 更新:更新SearchInput文件名=> search_input
- - [x] 修改:文件名称的大小写规范
- - [x] 修改:修正bottomNavigationBar iconButton警告
+- [x] 修复:icon没有,但内容有的,组件,给补充了icon
+- [x] 修改:1.整理文件 2.修正分析
+- [x] 更新:flutter_rookie_book => flutter_go
+- [x] 更新:更新SearchInput文件名=> search_input
+- [x] 修改:文件名称的大小写规范
+- [x] 修改:修正bottomNavigationBar iconButton警告
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..905b4fab
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,76 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at zhu.yan@alibaba-inc.com. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..fc13245c
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1 @@
+[Flutter Go 共建](https://github.com/alibaba/flutter-go/blob/master/docs/contribute.md)
diff --git a/FlutterGo.apk b/FlutterGo.apk
deleted file mode 100644
index 01ce3048..00000000
Binary files a/FlutterGo.apk and /dev/null differ
diff --git a/README-en.md b/README-en.md
index 4283a860..9eeeec99 100644
--- a/README-en.md
+++ b/README-en.md
@@ -1,28 +1,105 @@
-## Flutter Go
+# Flutter Go
+[中文简体](https://github.com/alibaba/flutter-go/blob/master/README.md) | Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.md)

-> Help developers get started quickly Flutter **Flutter Go 1.0 Android has been released**
+> Help developers get started quickly Flutter
+## News
+### 🔥 `Flutter Go 2.0` released
+> Flutter Go 2.0 according to [The Flutter-Go Roadmap for 2019](https://github.com/alibaba/flutter-go#the-flutter-go-roadmap%E8%B7%AF%E7%BA%BF%E5%9B%BE-for-2019) beginning of the year, the new feature is:
-## Download URL
+
mark:✔ is this version
-Android download URL:
+- [x] [ `Flutter Go` website ](https://flutter-go.pub/website/) (news,publish,learn)
+- [x] [ `Flutter Go web` ](https://github.com/alibaba/flutter-go/tree/web/flutter-go-web-0.0.1) (web version to learn)
+ - [online preview ](https://flutter-go.pub/flutter_go_web/)
+ - [resource ](https://github.com/alibaba/flutter-go/tree/web/flutter-go-web-0.0.1)
+<<<<<<< HEAD
<<<<<<< HEAD
=======
>>>>>>> develop
+=======
+- [x] [ `Flutter Go Widget` `pull request` rules ( the third )](https://github.com/alibaba/flutter-go/blob/master/docs/contribute.md)
+>>>>>>> dxj/master
-Iphone download URL:
-No
+- [x] user center (yourself `widget`)
+ - login (with `GitHub`)
+ - search (search about `Flutter`)
+ - favorite component (save online)
+ - issues (APP online `ISSUES`)
+ - favorite (APP favorite)
+- [x] [ `go-cli` tool ](https://github.com/alibaba/flutter-go/blob/master/docs/widget.md)
+ - `Flutter Go` `pull request` tools
+ - [ build `Flutter Go Widget` standard template with terminal ](https://github.com/alibaba/flutter-go/blob/beta/docs/widget.md)
+ - `markdown` template (when merge master breach)
+- [x] ` Flutter Go ` `APP` auto upgrade
+- [ ] template sync ( pc, native )
+- [ ] `Flutter Go` store
+
+## Third part build
+
+Because the content of ** flutter ** is updated faster, we can't enrich the content of the project faster, If you are willing to contribute to the development and learning of flutter, please see the [build instructions](https://github.com/alibaba/flutter-go/blob/master/docs/contribute.md) before you start, we will put the builder's avatar and nick to the websit.
+
+## Logs
+
+[resource](https://github.com/alibaba/flutter-go/blob/develop/CHANGE-LOG.md)
+
+## Development specification
+> we are based on the official [dart language specification](https://www.dartlang.org)。
+
+[<< Flutter Go development specification >>](https://github.com/alibaba/flutter-go/blob/develop/Flutter_Go%20%E4%BB%A3%E7%A0%81%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md)
+
+## The Flutter-Go Roadmap for 2019
+> Considering Flutter's future changes and strategy variability, roadmap does not rule out some adjustments, but overall it will not change much.
+
+
+
+## How to use
+
+- checkout version
+```dart
+ flutter --version
+```
+- run doctor
+```dart
+ flutter doctor
+```
+- start app
+```dart
+ flutter packages get
+ flutter run
+```
+
+- other issues
+ - https://flutterchina.club/setup-macos/
+ - https://flutter.dev/docs/get-started/install/macos
+
+## Release
+
+### Android:
+
+- [Download](https://github.com/alibaba/flutter-go/blob/master/android/app/release/app-release.apk)
+
+### Ios:
+
+- AppStore search "Fluttergo"
## Development Environment
This Project need latest package, please update regularly.
-- dart(version: 2.0.0)
-- flutter(version: v1.0.0)
+```dart
+flutter --version
+dart --version
+pub --version
+
+// Flutter (Channel beta, v1.7.8)
+// Dart VM version: 2.4.0
+// Pub 2.4.0
+```
### Background
@@ -89,4 +166,4 @@ The advantages of Flutter mainly include:
-Powered by Alibaba Auction Front-end Team
+Powered by Alibaba Auction Front-end Team
\ No newline at end of file
diff --git a/README.md b/README.md
index 3b5cc4fa..75aeae66 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,44 @@
+# Flutter Go
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

-> 帮助开发者快速上手 Flutter **Flutter Go 1.0 Android版已正式发布**
+> 一个帮助开发者快速上手的 `APP`
+
+## 最新动态
+### 🔥 `Flutter Go 2.0` 发布
+> Flutter Go 2.0 秉承年初发布的 [The Flutter-Go Roadmap(路线图) for 2019](https://github.com/alibaba/flutter-go#the-flutter-go-roadmap%E8%B7%AF%E7%BA%BF%E5%9B%BE-for-2019) 已经做了新版本的迭代,新版本如下新功能:
+
+注:✔是本次发布内容
+
+- [x] [ `Flutter Go` 官方网站 ](https://flutter-go.pub/website/) (官方消息,发布,学习)
+- [x] [ `Flutter Go web` 版本](https://github.com/alibaba/flutter-go/tree/web/flutter-go-web-0.0.1) (web 版本学习帮助)
+ - [线上预览版 ](https://flutter-go.pub/flutter_go_web/)
+ - [项目地址 ](https://github.com/alibaba/flutter-go/tree/web/flutter-go-web-0.0.1)
+
+- [x] [ `Flutter Go Widget` 的 `pull request` 提交规范(第三方共建)](https://github.com/alibaba/flutter-go/blob/master/docs/contribute.md)
+
+- [x] 用户中心 (专属个人的`widget`案例)
+ - 用户登录(通过`GitHub`账户)
+ - 全网搜索 (全网搜索 `Flutter` 资讯)
+ - 收藏个人组件(保存到远端)
+ - 反馈建议 (APP 在线 `ISSUES`)
+ - 分享链接 (APP分享)
+- [x] [ `go-cli` 工具 ](https://github.com/alibaba/flutter-go/blob/master/docs/widget.md)
+ - `Flutter Go` 的 `pull request` 工具
+ - [命令行 生成 `Flutter Go Widget` 标准公共模版](https://github.com/alibaba/flutter-go/blob/beta/docs/widget.md)
+ - `markdown` 模版动态化生成(合并到master分支后)
+- [x] ` Flutter Go ` 官方 `APP` 版本自动升级
+- [ ] 多端模版同步( pc端,native端同步 )
+- [ ] `Flutter Go` store
+
+
+
+## 三方共建说明
+
+由于 **flutter** 内容更新较快. 我们无法更快的丰富项目的内容. 如果您愿意为国内flutter的发展与学习贡献自己的力量, 请参考我们的 [共建说明](https://github.com/alibaba/flutter-go/blob/master/docs/contribute.md), 我们会将共建者的头像姓名贡献至我们的官网.
+
+
## 版本更新历史
> 按时间顺序,展示重要的提交更新内容。
@@ -16,13 +51,41 @@ Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.
[<< Flutter Go 开发规范第一版 >>](https://github.com/alibaba/flutter-go/blob/develop/Flutter_Go%20%E4%BB%A3%E7%A0%81%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md)
<<<<<<< HEAD
+<<<<<<< HEAD
+=======
+## The Flutter-Go Roadmap(路线图) for 2019
+> 考虑到 Flutter 未来的变化和策略的可变性, roadmap 不排除有一定调整,但总体不会变化太大。
+
+
+
+## 运行方式
+
+- 查看一下版本号是否正确
+```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
+>>>>>>> dxj/master
## Release安装包下载地址
### android正式版,下载地址:
- 华为市场已上线,华为应用市场搜索 "Fluttergo"或者直接[点击下载](https://appstore.huawei.com/search/fluttergo)
-
+- [直接 apk 文件下载](https://github.com/alibaba/flutter-go/blob/master/android/app/release/app-release.apk)
+
### iphone正式版,下载地址:
@@ -55,8 +118,17 @@ iphone下载地址: AppStore上面进行搜索fluttego
## 基础环境
本项目环境持续更新. 请定期更新各依赖包.
-- dart(version: 2.0.0)
-- flutter(version: v1.0.0)
+```dart
+// 运行如下命令
+flutter --version
+dart --version
+pub --version
+
+// 正确环境如下
+// Flutter (Channel beta, v1.7.8)
+// Dart VM version: 2.4.0
+// Pub 2.4.0
+```
### 背景
diff --git a/android/app/build.gradle b/android/app/build.gradle
index b723070c..4d293326 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -59,8 +59,23 @@ 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']
@@ -94,6 +109,8 @@ 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'
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index c50aa871..30748444 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -7,21 +7,22 @@
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
-
-
-
-
+
+
+
+
+ android:icon="@mipmap/ic_launcher_logo"
+ android:usesCleartextTraffic="true">
@@ -14,9 +18,9 @@
-
+
-
+
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index d94b59b8..c6bb52b8 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -22,6 +22,8 @@
????
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
+ LSApplicationCategoryType
+
LSRequiresIPhoneOS
NSCameraUsageDescription
diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
new file mode 100644
index 00000000..903def2a
--- /dev/null
+++ b/ios/Runner/Runner.entitlements
@@ -0,0 +1,8 @@
+
+
+
+
+ aps-environment
+ development
+
+
diff --git a/lib/api/api.dart b/lib/api/api.dart
index 4ed411f6..748e3422 100644
--- a/lib/api/api.dart
+++ b/lib/api/api.dart
@@ -1,6 +1,6 @@
class 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 BASE_URL = 'http://flutter-go.alibaba.net/';
+ static const String BASE_URL = 'https://flutter-go.pub/api/';
static const String DO_LOGIN = BASE_URL+'doLogin';//登陆
@@ -8,5 +8,29 @@ class Api{
static const String LOGOUT = BASE_URL+'logout';//退出登陆
+ static const String GET_USER_INFO = BASE_URL+'getUserInfo';//获取用户信息
+
+
static const String VERSION = BASE_URL+'getAppVersion';//检查版本
-}
\ No newline at end of file
+
+ 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';//搜索组件
+}
+
diff --git a/lib/blocs/bak/search_api.dart b/lib/blocs/bak/search_api.dart
deleted file mode 100644
index 0548d34e..00000000
--- a/lib/blocs/bak/search_api.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 3:20 PM
- * email: zhu.yan@alibaba-inc.com
- * tartget: FlatButton 的示例
- */
-import 'dart:async';
-import 'package:dio/dio.dart';
-import 'dart:convert';
-import './search_result.dart';
-import 'package:html/parser.dart' show parse;
-
-var dio = new Dio();
-class Api {
- Future> search(name) async {
- print('=========>>>');
- var response = await dio.get("https://www.so.com/s?ie=utf-8&q=$name");
-// var document = parse(response.data);
-// var app = document.querySelectorAll('.res-title a');
- List res = [];
-// app.forEach((f) {
-// res.add(
-// SearchResult(
-// title: f.text,
-// source: f.attributes["data-url"] ?? f.attributes["href"],
-// ),
-// );
-// });
- return res;
- }
-}
-
-Api api = Api();
\ No newline at end of file
diff --git a/lib/blocs/bak/search_bloc.dart b/lib/blocs/bak/search_bloc.dart
deleted file mode 100644
index 08d526c8..00000000
--- a/lib/blocs/bak/search_bloc.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 7:17 PM
- * email: zhu.yan@alibaba-inc.com
- * tartget:
- */
-import 'dart:async';
-import 'package:bloc/bloc.dart';
-
-import './search_event.dart';
-import './search_state.dart';
-import './search_api.dart';
-
-
-/// 这里导入api类与上面的SearchEvent与SearchState文件
-
-class SearchBloc extends Bloc {
- @override
- SearchState get initialState => SearchUninitialized();
-
- @override
- Stream mapEventToState(SearchEvent event,) async* {
- if (event is SearchFetch) {
- try {
- yield SearchLoading();
- final res = await api.search(event.query);
- yield SearchLoaded(res: res);
- } catch (_) {
- yield SearchError();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/lib/blocs/bak/search_event.dart b/lib/blocs/bak/search_event.dart
deleted file mode 100644
index 0ecc0b44..00000000
--- a/lib/blocs/bak/search_event.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 7:18 PM
- * email: zhu.yan@alibaba-inc.com
- * tartget:
- */
-abstract class SearchEvent {}
-
-class SearchFetch extends SearchEvent {
- final String query;
-
- SearchFetch({this.query});
-
- @override
- String toString() => 'SearchFetch:获取搜索结果事件';
-}
\ No newline at end of file
diff --git a/lib/blocs/bak/search_result.dart b/lib/blocs/bak/search_result.dart
deleted file mode 100644
index 8001e49a..00000000
--- a/lib/blocs/bak/search_result.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 7:11 PM
- * email: zhu.yan@alibaba-inc.com
- * tartget:
- */
-class SearchResult {
- String title;
- String source;
-
- SearchResult({this.title, this.source});
-}
\ No newline at end of file
diff --git a/lib/blocs/bak/search_state.dart b/lib/blocs/bak/search_state.dart
deleted file mode 100644
index 85d85791..00000000
--- a/lib/blocs/bak/search_state.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 7:13 PM
- * email: zhu.yan@alibaba-inc.com
- * tartget:
- */
-import './search_result.dart';
-
-abstract class SearchState {}
-
-class SearchError extends SearchState {
- @override
- String toString() => 'SearchError:获取失败';
-}
-
-class SearchUninitialized extends SearchState {
- @override
- String toString() => 'SearchUninitialized:未初始化';
-}
-
-class SearchLoading extends SearchState {
- @override
- String toString() => 'SearchLoading :正在加载';
-}
-
-class SearchLoaded extends SearchState {
- final List res;
-
- SearchLoaded({
- this.res,
- });
-
- @override
- String toString() => 'SearchLoaded:加载完毕';
-}
\ No newline at end of file
diff --git a/lib/blocs/bak/search_widget.dart b/lib/blocs/bak/search_widget.dart
deleted file mode 100644
index 1e29848a..00000000
--- a/lib/blocs/bak/search_widget.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 7:19 PM
- * email: zhu.yan@alibaba-inc.com
- * tartget:
- */
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-//import 'package:suiyi/blocs/search/bloc.dart';
-import './search_event.dart';
-import './search_state.dart';
-import './search_bloc.dart';
-
-
-class SearchWidget extends StatefulWidget {
- final SearchDelegate delegate;
- final String query;
- SearchWidget({this.delegate, this.query});
- @override
- _SearchWidgetState createState() => _SearchWidgetState();
-}
-
-class _SearchWidgetState extends State {
- final SearchBloc _search = SearchBloc();
- String old;
- @override
- void dispose() {
- _search.dispose();
- super.dispose();
- }
-
- @override
- Widget build(BuildContext context) {
- print('1:${old}');
- print('2:${widget.query}');
- if (old != widget.query) {
- _search.dispatch(SearchFetch(query: widget.query));
- old = widget.query;
- }
- return BlocBuilder(
- bloc: _search,
- builder: (BuildContext context, SearchState state) {
- print('-------${state}');
- if (state is SearchUninitialized || state is SearchLoading) {
- return Center(
- child: CircularProgressIndicator(),
- );
- } else if (state is SearchError) {
- return Center(
- child: Text('获取失败'),
- );
- } else if (state is SearchLoaded) {
- return ListView.builder(
- itemBuilder: (BuildContext context, int index) {
- return ListTile(
- dense: true,
- leading: Icon(
- Icons.bookmark_border,
- size: 32,
- ),
- title: Text(
- state.res[index].title,
- overflow: TextOverflow.ellipsis,
- ),
- subtitle: Text(state.res[index].source),
- onTap: () {
- // 在这里对选中的结果进行解析,因为我目前是用golang实现的,所以就没贴代码了。
- print(state.res[index].source);
- },
- );
- },
- itemCount: state.res.length,
- );
- }
- },
- );
- }
-}
\ No newline at end of file
diff --git a/lib/blocs/industry_api.dart b/lib/blocs/industry_api.dart
index fc8b2967..7b271ca0 100644
--- a/lib/blocs/industry_api.dart
+++ b/lib/blocs/industry_api.dart
@@ -1,16 +1,14 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 3:20 PM
- * email: zhu.yan@alibaba-inc.com
- * tartget: FlatButton 的示例
- */
+//
+// Created with Android Studio.
+// User: 一晟
+// Date: 2019/4/28
+// Time: 3:20 PM
+// email: zhu.yan@alibaba-inc.com
+// tartget: FlatButton 的示例
+//
import 'dart:async';
import 'package:dio/dio.dart';
-import 'dart:convert';
import 'package:html/parser.dart' show parse;
-import './industry_model.dart';
import './search_result.dart';
var dio = new Dio();
diff --git a/lib/blocs/industry_bloc.dart b/lib/blocs/industry_bloc.dart
index 3bcd464c..1757f3b4 100644
--- a/lib/blocs/industry_bloc.dart
+++ b/lib/blocs/industry_bloc.dart
@@ -23,7 +23,7 @@ class SuggestionBloc extends Bloc {
try {
yield SuggestionLoading();
final res = await api.suggestion(event.query);
- print('res====>${res}');
+ // print('res====>${res}');
yield SuggestionLoaded(res: res);
} catch (_) {
yield SuggestionError();
diff --git a/lib/blocs/industry_event.dart b/lib/blocs/industry_event.dart
index 641720b2..b54e7940 100644
--- a/lib/blocs/industry_event.dart
+++ b/lib/blocs/industry_event.dart
@@ -1,10 +1,10 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 3:35 PM
- * email: zhu.yan@alibaba-inc.com
- */
+///
+/// Created with Android Studio.
+/// User: 一晟
+/// Date: 2019/4/28
+/// Time: 3:35 PM
+/// email: zhu.yan@alibaba-inc.com
+///
abstract class SuggestionEvent {}
class SuggestionFetch extends SuggestionEvent {
diff --git a/lib/blocs/industry_main.dart b/lib/blocs/industry_main.dart
index 22dfbc0a..fa49fac5 100644
--- a/lib/blocs/industry_main.dart
+++ b/lib/blocs/industry_main.dart
@@ -1,14 +1,14 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 3:52 PM
- * email: zhu.yan@alibaba-inc.com
- */
+///
+/// Created with Android Studio.
+/// User: 一晟
+/// Date: 2019/4/28
+/// Time: 3:52 PM
+/// email: zhu.yan@alibaba-inc.com
+///
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import './industry_bloc.dart';
-import './industry_event.dart';
+/// import './industry_event.dart';
import './industry_state.dart';
final SuggestionBloc suggestion = SuggestionBloc();
@@ -22,47 +22,46 @@ class IndustryPage extends StatefulWidget {
}
class _IndustryState extends State {
+ Widget renderItem(state) {
+ if (state is SuggestionUninitialized) {
+ return Center(
+ child: Text('暂无内容'),
+ );
+ } else if (state is SuggestionLoading) {
+ return Center(
+ child: CircularProgressIndicator(),
+ );
+ } else if (state is SuggestionError) {
+ return Center(
+ child: Text('出现错误'),
+ );
+ } else if (state is SuggestionLoaded) {
+ if (state.res.length == 0) {
+ return Center(
+ child: Text('没有适合的结果,更换查询条件试试'),
+ );
+ }else {
+ if (widget.itemTitle is Function) {
+ return widget.itemTitle(state);
+ }
+ }
+ }
+ return Center(
+ child: Text('没有适合的结果,更换查询条件试试')
+ );
+ }
+
@override
Widget build(BuildContext context) {
return Material(
child: Column(
children: [
-// TextField(
-// autofocus: true,
-// textAlign: TextAlign.center,
-// onSubmitted: (text) {
-// print('onSubmitted:${text}');
-// suggestion.dispatch(SuggestionFetch(query: text));
-// },
-// ),
Expanded(
child: BlocBuilder(
bloc: suggestion,
- builder: (BuildContext context, SuggestionState state) {
- print('BlocBuilder----${state}');
- if (state is SuggestionUninitialized) {
- return Center(
- child: Text('暂无内容'),
- );
- } else if (state is SuggestionLoading) {
- return Center(
- child: CircularProgressIndicator(),
- );
- } else if (state is SuggestionError) {
- return Center(
- child: Text('出现错误'),
- );
- } else if (state is SuggestionLoaded) {
- if (state.res.length == 0) {
- return Center(
- child: Text('没有适合的结果,更换查询条件试试'),
- );
- }else {
- if (widget.itemTitle is Function) {
- return widget.itemTitle(state);
- }
- }
- }
+ builder: (BuildContext context, SuggestionState state){
+ /// print('BlocBuilder----${state}');
+ return renderItem(state);
},
),
),
diff --git a/lib/blocs/industry_model.dart b/lib/blocs/industry_model.dart
index ea6cb081..550d29c7 100644
--- a/lib/blocs/industry_model.dart
+++ b/lib/blocs/industry_model.dart
@@ -1,10 +1,10 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 3:19 PM
- * email: zhu.yan@alibaba-inc.com
- */
+///
+/// Created with Android Studio.
+/// User: 一晟
+/// Date: 2019/4/28
+/// Time: 3:19 PM
+/// email: zhu.yan@alibaba-inc.com
+///
class Suggestion {
String query;
List suggestions;
diff --git a/lib/blocs/industry_state.dart b/lib/blocs/industry_state.dart
index b129830c..8083aa80 100644
--- a/lib/blocs/industry_state.dart
+++ b/lib/blocs/industry_state.dart
@@ -1,10 +1,10 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 3:37 PM
- * email: zhu.yan@alibaba-inc.com
- */
+///
+/// Created with Android Studio.
+/// User: 一晟
+/// Date: 2019/4/28
+/// Time: 3:37 PM
+/// email: zhu.yan@alibaba-inc.com
+///
abstract class SuggestionState {}
class SuggestionError extends SuggestionState {
diff --git a/lib/blocs/search_result.dart b/lib/blocs/search_result.dart
index 8001e49a..bf64d1b1 100644
--- a/lib/blocs/search_result.dart
+++ b/lib/blocs/search_result.dart
@@ -1,11 +1,11 @@
-/**
- * Created with Android Studio.
- * User: 一晟
- * Date: 2019/4/28
- * Time: 7:11 PM
- * email: zhu.yan@alibaba-inc.com
- * tartget:
- */
+///
+/// Created with Android Studio.
+/// User: 一晟
+/// Date: 2019/4/28
+/// Time: 7:11 PM
+/// email: zhu.yan@alibaba-inc.com
+/// tartget:
+///
class SearchResult {
String title;
String source;
diff --git a/lib/components/cate_card.dart b/lib/components/cate_card.dart
index 4d43c5d0..aab9fa48 100644
--- a/lib/components/cate_card.dart
+++ b/lib/components/cate_card.dart
@@ -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 Cat category;
+ final CategoryComponent category;
CateCard({@required this.category});
@override
_CateCardState createState() => _CateCardState();
@@ -13,28 +13,15 @@ class CateCard extends StatefulWidget {
class _CateCardState extends State {
// 一级菜单目录下的二级Cat集合
- List _firstChildList = new List();
- CatControlModel catControl = new CatControlModel();
+ List _firstChildList;
@override
void initState() {
super.initState();
- getFirstChildCategoriesByParentId();
+ _firstChildList = widget.category.children;
}
- // 获取一层目录下的二级内容
- getFirstChildCategoriesByParentId() async {
- int parentId = widget.category.id;
- // 构建查询条件
- Cat childCateCondition = new Cat(parentId: parentId);
- List list = await catControl.getList(childCateCondition);
- if (list.isNotEmpty&&list.length>=1 && this.mounted) {
- setState(() {
- _firstChildList = list;
- });
- }
- }
@override
Widget build(BuildContext context) {
@@ -43,7 +30,6 @@ class _CateCardState extends State {
//首字母转为大写
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),
@@ -119,9 +105,8 @@ class _CateCardState extends State {
),
),
child: WidgetItemContainer(
- categories: this._firstChildList,
- columnCount: 3,
- isWidgetPoint:false
+ commonItems: this._firstChildList,
+ columnCount: 3
),
);
}
diff --git a/lib/components/category.dart b/lib/components/category.dart
index 7c6c0715..eee1035e 100644
--- a/lib/components/category.dart
+++ b/lib/components/category.dart
@@ -3,16 +3,17 @@ import 'dart:async';
import 'package:flutter/material.dart';
import '../routers/application.dart';
-import '../model/cat.dart';
+/// import '../model/cat.dart';
import '../model/widget.dart';
import '../widgets/index.dart';
import '../components/widget_item_container.dart';
-enum CateOrWigdet { Cat, WidgetDemo }
+
class CategoryHome extends StatefulWidget {
- CategoryHome(this.name);
- final String name;
+ CategoryHome(this.token);
+ final String token;
+
@override
_CategoryHome createState() => new _CategoryHome();
@@ -21,12 +22,11 @@ class CategoryHome extends StatefulWidget {
class _CategoryHome extends State {
String title = '';
// 显示列表 cat or widget;
- List categories = [];
- List widgetPoints = [];
- List catHistory = new List();
+ List items = [];
+ List widgetPoints = [];
+ List catHistory = new List();
+
- CatControlModel catControl = new CatControlModel();
- WidgetControlModel widgetControl = new WidgetControlModel();
// 所有的可用demos;
List widgetDemosList = new WidgetDemoList().getDemos();
@@ -34,80 +34,60 @@ class _CategoryHome extends State {
void initState() {
super.initState();
// 初始化加入顶级的name
- this.getCatByName(widget.name).then((Cat cat) {
- catHistory.add(cat);
- searchCatOrWigdet();
+ print("这是新界面的id:>>> ${widget.token}");
+
+ CommonItem targetGroup = Application.widgetTree.find(widget.token) ?? [];
+ print("targetGroup::: $targetGroup");
+
+ catHistory.add(
+ targetGroup
+ );
+ this.setState(() {
+ items = targetGroup.children;
});
+ searchCatOrWidget();
}
- Future getCatByName(String name) async {
- return await catControl.getCatByName(name);
- }
+
Future back() {
- if (catHistory.length == 1) {
- return Future.value(true);
- }
- catHistory.removeLast();
- searchCatOrWigdet();
- return Future.value(false);
+// if (catHistory.length == 1) {
+// return Future.value(true);
+// }
+// catHistory.removeLast();
+// searchCatOrWidget();
+ return Future.value(true);
}
- void go(Cat cat) {
+ void go(CommonItem cat) {
catHistory.add(cat);
- searchCatOrWigdet();
+ searchCatOrWidget();
}
- void searchCatOrWigdet() async {
- // 假设进入这个界面的parent一定存在
- Cat parentCat = catHistory.last;
+ void searchCatOrWidget() async {
+ /// CommonItem widgetTree = Application.widgetTree;
+ // 假设进入这个界面的parent一定存在
+ CommonItem targetGroup = catHistory.last;
- // 继续搜索显示下一级depth: depth + 1, parentId: parentCat.id
- List _categories =
- await catControl.getList(new Cat(parentId: parentCat.id));
- List _widgetPoints = new List();
- if (_categories.isEmpty) {
- _widgetPoints =
- await widgetControl.getList(new WidgetPoint(catId: parentCat.id));
- }
-
this.setState(() {
- categories = _categories;
- title = parentCat.name;
- widgetPoints = _widgetPoints;
+ title = targetGroup.name;
});
}
- void onCatgoryTap(Cat cat) {
+ void onCatgoryTap(CommonItem 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,
- categories: categories,
- isWidgetPoint:false
+ commonItems: items
);
- 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(
@@ -122,14 +102,18 @@ class _CategoryHome extends State {
@override
Widget build(BuildContext context) {
+
+
return Scaffold(
appBar: AppBar(
- title: Text(title),
+ title: Text("$title"),
),
body: WillPopScope(
+
onWillPop: () {
return back();
},
+
child: ListView(
children: [
_buildContent(),
diff --git a/lib/components/disclaimer_msg.dart b/lib/components/disclaimer_msg.dart
index 78ebb0a5..d7c4bf7f 100644
--- a/lib/components/disclaimer_msg.dart
+++ b/lib/components/disclaimer_msg.dart
@@ -9,7 +9,6 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
-
const disclaimerText1 =
'\r\r\r\r\r\r本APP属于个人的非赢利性开源项目,以供开源社区使用,凡本APP转载的所有的文章 、图片、音频、视频文件等资料的版权归版权所有人所有,本APP采用的非本站原创文章及图片等内容无法一一和版权者联系,如果本网所选内容的文章作者及编辑认为其作品不宜上网供大家浏览,或不应无偿使用请及时用电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。';
const disclaimerText2 =
@@ -23,6 +22,7 @@ class DisclaimerMsg extends StatefulWidget {
DisclaimerMsgState createState() => DisclaimerMsgState();
}
+
class DisclaimerMsgState extends State {
Future _prefs = SharedPreferences.getInstance();
Future _unKnow;
@@ -33,11 +33,14 @@ class DisclaimerMsgState extends State {
void refs(bool value) async {
final SharedPreferences prefs = await _prefs;
final bool unKnow = value;
+ _valBool = value;
+ _readed = value;
if (mounted) {
setState(() {
- _unKnow = prefs.setBool("disclaimer::Boolean", unKnow).then((bool success) {
- return unKnow;
- });
+ _unKnow =
+ prefs.setBool("disclaimer::Boolean", unKnow).then((bool success) {
+ return unKnow;
+ });
});
}
}
@@ -60,110 +63,14 @@ class DisclaimerMsgState extends State {
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
- return AlertDialog(
- //title: Text('免责声明'),
- content: SingleChildScrollView(
- child: ListBody(
- children: [
- Container(
- padding: EdgeInsets.fromLTRB(5.0, 5.0, 10.0, 10.0),
- //width: 100,
- height: 35,
- child: Text('免责声明',
- style: TextStyle(
- fontSize: 18, fontWeight: FontWeight.w700)),
- decoration: BoxDecoration(
- //color: Colors.blue,
- image: DecorationImage(
- fit: BoxFit.fitWidth,
- image: AssetImage('assets/images/paimaiLogo.png')),
- borderRadius: BorderRadius.all(
- Radius.circular(10.0),
- ),
- //alignment: Alignment.bottomRight,
- )),
- SizedBox(height: 20),
- Text(disclaimerText1),
- Text(disclaimerText2),
- ],
- ),
- ),
- shape: RoundedRectangleBorder(
- borderRadius: new BorderRadius.circular(20.0)), // 圆角
-
- actions: [
- new Container(
- width: 250,
- child: _create(),
- )
- ],
- );
+ return DisclaimerMsgDialog(_valBool, _readed, (b){
+ refs(b);
+ });
},
);
}
- Row _create() {
- //已读
- if (_readed) {
- return Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
- FlatButton(
- padding: EdgeInsets.symmetric(horizontal: 20.0),
- child: Text('已阅读知晓',
- style: TextStyle(fontSize: 16, color: Colors.white)),
- //可点击
- color: Theme.of(context).primaryColor,
- onPressed: () {
- Navigator.of(context).pop();
- },
- ),
- SizedBox(
- width: 10.0,
- )
- ],
- );
- }
- //第一次读取
- return Row(mainAxisAlignment: MainAxisAlignment.spaceAround,
- //crossAxisAlignment:CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Checkbox(
- activeColor: Theme.of(context).primaryColor,
- tristate: false,
- value: _valBool,
- onChanged: (bool bol) {
- if(mounted) {
- setState(() {
- _valBool = bol;
- });
- }
- Navigator.of(context).pop(); // here I pop to avoid multiple Dialogs
- showAlertDialog(context); //here i call the same function
- }),
- Text('不再自动提示', style: TextStyle(fontSize: 14)),
- ],
- ),
- FlatButton(
- child: Text('知道了',
- style: TextStyle(fontSize: 16, color: Colors.white)),
- //可点击
- color: _valBool
- ? Theme.of(context).primaryColor
- : Theme.of(context).primaryColor.withAlpha(800),
- onPressed: () {
- // if (_valBool) {
- refs(_valBool);
- Navigator.of(context).pop();
- // }
- },
- ),
- ]);
- }
Widget build(BuildContext context) {
return GestureDetector(
@@ -178,7 +85,7 @@ class DisclaimerMsgState extends State {
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius:
- BorderRadius.horizontal(right: Radius.circular(10)),
+ BorderRadius.horizontal(right: Radius.circular(10)),
color: Colors.black45,
),
child: Text(
@@ -194,3 +101,150 @@ class DisclaimerMsgState extends State {
));
}
}
+
+
+class DisclaimerMsgDialog extends StatefulWidget {
+
+ final bool valBool;
+ final bool readed;
+ final ValueChanged onValueChanged;
+
+
+ DisclaimerMsgDialog(this.valBool, this.readed, this.onValueChanged);
+
+ @override
+ _DisclaimerMsgDialogState createState() => _DisclaimerMsgDialogState();
+}
+
+class _DisclaimerMsgDialogState extends State {
+
+ bool readBool;
+
+
+ @override
+ void initState() {
+ super.initState();
+ readBool = widget.valBool;
+ }
+
+
+
+ Row _create() {
+ //已读
+ if (widget.readed) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ FlatButton(
+ padding: EdgeInsets.symmetric(horizontal: 20.0),
+ child: Text('已阅读知晓',
+ style: TextStyle(fontSize: 16, color: Colors.white)),
+ //可点击
+ color: Theme
+ .of(context)
+ .primaryColor,
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ ),
+ SizedBox(
+ width: 10.0,
+ )
+ ],
+ );
+ }
+
+ /// 选中状态更新,并返回数据
+ checkChanged(){
+ if (mounted) {
+ setState(() {
+ readBool = !readBool;
+ });
+ }
+ }
+
+ //第一次读取
+ return Row(mainAxisAlignment: MainAxisAlignment.spaceAround,
+ //crossAxisAlignment:CrossAxisAlignment.start,
+ children: [
+ GestureDetector(
+ onTap: (){
+ checkChanged();
+ },
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Checkbox(
+ activeColor: Theme
+ .of(context)
+ .primaryColor,
+ tristate: false,
+ value: readBool,
+ onChanged: (bool bol) {
+ checkChanged();
+ }),
+ Text('不再自动提示', style: TextStyle(fontSize: 14)),
+ ],
+ ),
+ ),
+ FlatButton(
+ child: Text('知道了',
+ style: TextStyle(fontSize: 16, color: Colors.white)),
+ //可点击
+ color: readBool
+ ? Theme
+ .of(context)
+ .primaryColor
+ : Theme
+ .of(context)
+ .primaryColor
+ .withAlpha(800),
+ onPressed: () {
+ widget.onValueChanged(readBool);
+ Navigator.of(context).pop();
+ },
+ ),
+ ]);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return AlertDialog(
+ //title: Text('免责声明'),
+ content: SingleChildScrollView(
+ child: ListBody(
+ children: [
+ Container(
+ padding: EdgeInsets.fromLTRB(5.0, 5.0, 10.0, 10.0),
+ //width: 100,
+ height: 35,
+ child: Text('免责声明',
+ style:
+ TextStyle(fontSize: 18, fontWeight: FontWeight.w700)),
+ decoration: BoxDecoration(
+ //color: Colors.blue,
+ image: DecorationImage(
+ fit: BoxFit.fitWidth,
+ image: AssetImage('assets/images/paimaiLogo.png')),
+ borderRadius: BorderRadius.all(
+ Radius.circular(10.0),
+ ),
+ //alignment: Alignment.bottomRight,
+ )),
+ SizedBox(height: 20),
+ Text(disclaimerText1),
+ Text(disclaimerText2),
+ ],
+ ),
+ ),
+ shape: RoundedRectangleBorder(
+ borderRadius: new BorderRadius.circular(20.0)), // 圆角
+
+ actions: [
+ new Container(
+ width: 250,
+ child: _create(),
+ )
+ ],
+ );
+ }}
diff --git a/lib/components/flutter_markdown/LICENSE b/lib/components/flutter_markdown/LICENSE
new file mode 100644
index 00000000..e7892520
--- /dev/null
+++ b/lib/components/flutter_markdown/LICENSE
@@ -0,0 +1,27 @@
+// 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.
diff --git a/lib/components/flutter_markdown/README.md b/lib/components/flutter_markdown/README.md
new file mode 100644
index 00000000..35c4a267
--- /dev/null
+++ b/lib/components/flutter_markdown/README.md
@@ -0,0 +1,39 @@
+# 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`.
diff --git a/lib/components/flutter_markdown/lib/flutter_markdown.dart b/lib/components/flutter_markdown/lib/flutter_markdown.dart
new file mode 100644
index 00000000..8d7ed6ea
--- /dev/null
+++ b/lib/components/flutter_markdown/lib/flutter_markdown.dart
@@ -0,0 +1,10 @@
+// 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';
diff --git a/lib/components/flutter_markdown/lib/src/builder.dart b/lib/components/flutter_markdown/lib/src/builder.dart
new file mode 100644
index 00000000..089e83c3
--- /dev/null
+++ b/lib/components/flutter_markdown/lib/src/builder.dart
@@ -0,0 +1,376 @@
+// 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 attrs);
+
+final Set _kBlockTags = new Set.from([
+ 'p',
+ 'h1',
+ 'h2',
+ 'h3',
+ 'h4',
+ 'h5',
+ 'h6',
+ 'li',
+ 'blockquote',
+ 'pre',
+ 'ol',
+ 'ul',
+ 'hr',
+]);
+
+const List _kListTags = const ['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 children = [];
+
+ 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 children = [];
+}
+
+/// 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 _listIndents = [];
+ final List<_BlockElement> _blocks = <_BlockElement>[];
+ final List<_InlineElement> _inlines = <_InlineElement>[];
+ final List _linkHandlers = [];
+
+
+ /// Returns widgets that display the given Markdown nodes.
+ ///
+ /// The returned widgets are typically used as children in a [ListView].
+ List build(List 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: [
+ 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 attrs) {
+ Widget targetGoDemos;
+
+ if (demoParser != null) {
+ targetGoDemos = demoParser(attrs);
+ }
+
+ return targetGoDemos ?? new Text('demo not exits');
+ }
+
+ Widget _buildImage(String src) {
+ final List parts = src.split('#');
+ if (parts.isEmpty)
+ return const SizedBox();
+
+ final String path = parts.first;
+ double width;
+ double height;
+ if (parts.length == 2) {
+ final List 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 mergedInlines = _mergeInlineChildren(inline);
+ final Wrap wrap = new Wrap(children: mergedInlines);
+ _addBlockChild(wrap);
+ _inlines.clear();
+ }
+ }
+
+ /// Merges adjacent [TextSpan] children of the given [_InlineElement]
+ List _mergeInlineChildren(_InlineElement inline) {
+ List mergedTexts = [];
+ for (Widget child in inline.children) {
+ if (mergedTexts.isNotEmpty && mergedTexts.last is RichText && child is RichText) {
+ RichText previous = mergedTexts.removeLast();
+ List 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;
+ }
+}
diff --git a/lib/components/flutter_markdown/lib/src/style_sheet.dart b/lib/components/flutter_markdown/lib/src/style_sheet.dart
new file mode 100644
index 00000000..6c44b773
--- /dev/null
+++ b/lib/components/flutter_markdown/lib/src/style_sheet.dart
@@ -0,0 +1,307 @@
+// 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 = {
+ '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 get styles => _styles;
+ Map _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,
+ ]);
+ }
+}
diff --git a/lib/components/flutter_markdown/lib/src/widget.dart b/lib/components/flutter_markdown/lib/src/widget.dart
new file mode 100644
index 00000000..c9d5cbaf
--- /dev/null
+++ b/lib/components/flutter_markdown/lib/src/widget.dart
@@ -0,0 +1,247 @@
+// 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 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.
+/// *
+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 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 implements MarkdownBuilderDelegate {
+ List _children;
+ final List _recognizers = [];
+
+ @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 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 localRecognizers = new List.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.
+/// *
+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 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.
+/// *
+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 children) {
+ return new ListView(padding: padding, children: children);
+ }
+}
diff --git a/lib/components/full_screen_code_dialog.dart b/lib/components/full_screen_code_dialog.dart
index 76147749..5a40d9cf 100644
--- a/lib/components/full_screen_code_dialog.dart
+++ b/lib/components/full_screen_code_dialog.dart
@@ -7,11 +7,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_go/utils/example_code_parser.dart';
import 'package:flutter_go/utils/syntax_highlighter.dart';
+import 'package:flutter_go/utils/net_utils.dart';
class FullScreenCodeDialog extends StatefulWidget {
- const FullScreenCodeDialog({this.filePath});
+ const FullScreenCodeDialog({this.filePath, this.remoteFilePath});
final String filePath;
+ final String remoteFilePath;
_FullScreenCodeDialogState createState() => _FullScreenCodeDialogState();
}
@@ -21,17 +23,31 @@ class _FullScreenCodeDialogState extends State {
@override
void didChangeDependencies() {
print('widget.filePath=======${widget.filePath}');
- getExampleCode(context,'${widget.filePath}', DefaultAssetBundle.of(context))
- .then((String code) {
- if (mounted) {
- setState(() {
- _exampleCode = code ?? 'Example code not found';
- });
- }
- });
+ if (widget.filePath != null) {
+ getExampleCode(context,'${widget.filePath}', DefaultAssetBundle.of(context))
+ .then((String code) {
+ if (mounted) {
+ setState(() {
+ _exampleCode = code ?? 'Example code not found';
+ });
+ }
+ });
+ }
+ if (widget.remoteFilePath != null) {
+ getRemotePathCode(widget.remoteFilePath);
+ }
+
super.didChangeDependencies();
}
+ getRemotePathCode(path) async {
+ String response = await NetUtils.get(path);
+ if (mounted) {
+ setState(() {
+ _exampleCode = response ?? 'Example code not found';
+ });
+ }
+ }
@override
Widget build(BuildContext context) {
final SyntaxHighlighterStyle style =
diff --git a/lib/components/list_refresh.dart b/lib/components/list_refresh.dart
index b4a13244..c5d3b0d8 100644
--- a/lib/components/list_refresh.dart
+++ b/lib/components/list_refresh.dart
@@ -174,6 +174,7 @@ class _ListRefreshState extends State {
return widget.renderItem(index, items[index]);
}
}
+ return null;
},
controller: _scrollController,
),
diff --git a/lib/components/loading.dart b/lib/components/loading.dart
new file mode 100644
index 00000000..659b2ff8
--- /dev/null
+++ b/lib/components/loading.dart
@@ -0,0 +1,94 @@
+//
+// 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 requestCallBack;
+
+ NetLoadingDialog(
+ {Key key,
+ this.loadingText = "loading...",
+ this.outsideDismiss = true,
+ this.dismissCallback,
+ this.loading,
+ this.requestCallBack})
+ : super(key: key);
+
+ @override
+ State createState() => _LoadingDialog();
+}
+
+class _LoadingDialog extends State {
+ _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: [
+ new CircularProgressIndicator(),
+ new Padding(
+ padding: const EdgeInsets.only(
+ top: 20.0,
+ ),
+ child: new Text(
+ widget.loadingText,
+ style: new TextStyle(fontSize: 12.0),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/components/markdown.dart b/lib/components/markdown.dart
index 02cf6af7..af055381 100644
--- a/lib/components/markdown.dart
+++ b/lib/components/markdown.dart
@@ -1,4 +1,4 @@
-import 'package:flutter_markdown/flutter_markdown.dart' as md;
+import '../components/flutter_markdown/lib/flutter_markdown.dart' as md;
import 'package:flutter/material.dart';
import 'package:flutter_go/utils/high_light_code.dart';
diff --git a/lib/components/search_input.dart b/lib/components/search_input.dart
index b0abdf03..9852c83a 100644
--- a/lib/components/search_input.dart
+++ b/lib/components/search_input.dart
@@ -15,13 +15,9 @@ typedef void OnSubmit(String value);
///搜索结果内容显示面板
class MaterialSearchResult extends StatelessWidget {
- const MaterialSearchResult({
- Key key,
- this.value,
- this.text,
- this.icon,
- this.onTap
- }) : super(key: key);
+ const MaterialSearchResult(
+ {Key key, this.value, this.text, this.icon, this.onTap})
+ : super(key: key);
final String value;
final VoidCallback onTap;
@@ -30,7 +26,6 @@ class MaterialSearchResult extends StatelessWidget {
@override
Widget build(BuildContext context) {
-
return new InkWell(
onTap: this.onTap,
child: new Container(
@@ -38,8 +33,14 @@ class MaterialSearchResult extends StatelessWidget {
padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 10.0),
child: new Row(
children: [
- new Container(width: 30.0, margin: EdgeInsets.only(right: 10), child: new Icon(icon)) ?? null,
- new Expanded(child: new Text(value, style: Theme.of(context).textTheme.subhead)),
+ new Container(
+ width: 30.0,
+ margin: EdgeInsets.only(right: 10),
+ child: new Icon(icon)) ??
+ null,
+ new Expanded(
+ child: new Text(value,
+ style: Theme.of(context).textTheme.subhead)),
new Text(text, style: Theme.of(context).textTheme.subhead)
],
),
@@ -124,6 +125,7 @@ class _MaterialSearchState extends State {
}
Timer _resultsTimer;
+
Future _getResultsDebounced() async {
if (_results.length == 0) {
setState(() {
@@ -164,6 +166,7 @@ class _MaterialSearchState extends State {
super.dispose();
_resultsTimer?.cancel();
}
+
Widget buildBody(List results) {
if (_criteria.isEmpty) {
return History();
@@ -171,16 +174,11 @@ class _MaterialSearchState extends State {
return new Center(
child: new Padding(
padding: const EdgeInsets.only(top: 50.0),
- child: new CircularProgressIndicator()
- )
- );
+ child: new CircularProgressIndicator()));
}
if (results.isNotEmpty) {
- var content = new SingleChildScrollView(
- child: new Column(
- children: results
- )
- );
+ var content =
+ new SingleChildScrollView(child: new Column(children: results));
return content;
}
return Center(child: Text("暂无数据"));
@@ -241,7 +239,7 @@ class _MaterialSearchState extends State {
],
),
body: buildBody(results),
- );
+ );
}
}
@@ -405,34 +403,35 @@ class SearchInput extends StatelessWidget {
}
// wigdet干掉.=> componets
-
class History extends StatefulWidget {
const History() : super();
@override
- _History createState() => _History();
+ _History createState() => _History();
}
// AppBar 默认的实例,有状态
class _History extends State {
SearchHistoryList searchHistoryList = new SearchHistoryList();
+ bool refreshFlag;
@override
void initState() {
super.initState();
+ this.refreshFlag = true;
}
@override
void dispose() {
super.dispose();
}
+
buildChips(BuildContext context) {
List list = [];
List historyList = searchHistoryList.getList();
print("historyList> $historyList");
Color bgColor = Theme.of(context).primaryColor;
historyList.forEach((SearchHistory value) {
-
Widget icon = CircleAvatar(
backgroundColor: bgColor,
child: Text(
@@ -443,21 +442,30 @@ class _History extends State {
if (WidgetName2Icon.icons[value.name] != null) {
icon = Icon(WidgetName2Icon.icons[value.name], size: 25);
}
+ String targetRouter = value.targetRouter;
- list.add(
- InkWell(
- onTap: () {
- Application.router.navigateTo(context, "${value.targetRouter}", transition: TransitionType.inFromRight);
- },
- child: Chip(
- avatar: icon,
- label: Text("${value.name}"),
- ),
- )
- );
+ list.add(InkWell(
+ onTap: () {
+ Application.router.navigateTo(
+ context, "${targetRouter.toLowerCase()}",
+ transition: TransitionType.inFromRight);
+ },
+ child: Chip(
+ avatar: icon,
+ label: Text("${value.name}"),
+ ),
+ ));
});
return list;
}
+
+ _clearHistory() {
+ searchHistoryList.clear();
+ this.setState(() {
+ this.refreshFlag = !this.refreshFlag;
+ });
+ }
+
@override
Widget build(BuildContext context) {
List childList = buildChips(context);
@@ -469,25 +477,38 @@ class _History extends State {
return Column(
children: [
Container(
- alignment: Alignment.centerLeft,
- padding: EdgeInsets.fromLTRB(12.0, 12, 12, 0),
- child: InkWell(
- onLongPress: () {
- searchHistoryList.clear();
- },
- child: Text('历史搜索'),
- ),
- ),
+ alignment: Alignment.centerLeft,
+ padding: EdgeInsets.fromLTRB(12.0, 12, 12, 0),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ InkWell(
+ onLongPress: () {
+ searchHistoryList.clear();
+ },
+ child: Text('历史搜索'),
+ ),
+ GestureDetector(
+ onTap: _clearHistory,
+ child: Container(
+ child: new Icon(Icons.delete,
+ size: 24.0, color: Theme.of(context).accentColor),
+ width: 30,
+ height: 30,
+ ),
+ )
+ ],
+ )),
Container(
padding: EdgeInsets.only(left: 10),
alignment: Alignment.topLeft,
child: Wrap(
- spacing: 6.0, // gap between adjacent chips
- runSpacing: 0.0, // gap between lines
- children: childList
- ),
+ spacing: 6.0, // gap between adjacent chips
+ runSpacing: 0.0, // gap between lines
+ children: childList),
)
],
);
}
-}
\ No newline at end of file
+}
diff --git a/lib/components/single_theme_color.dart b/lib/components/single_theme_color.dart
new file mode 100644
index 00000000..8a9088a0
--- /dev/null
+++ b/lib/components/single_theme_color.dart
@@ -0,0 +1,47 @@
+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: [
+ 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,
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/components/widget_demo.dart b/lib/components/widget_demo.dart
index bbce9f51..1e2d5744 100644
--- a/lib/components/widget_demo.dart
+++ b/lib/components/widget_demo.dart
@@ -4,11 +4,12 @@
import 'dart:core';
import 'package:flutter/material.dart';
+import 'package:flutter_go/utils/data_utils.dart';
import '../routers/application.dart';
import '../routers/routers.dart';
import '../components/markdown.dart';
-import '../model/collection.dart';
+/// import '../model/collection.dart';
import '../widgets/index.dart';
import '../event/event_bus.dart';
import '../event/event_model.dart';
@@ -24,8 +25,8 @@ class WidgetDemo extends StatefulWidget {
{Key key,
@required this.title,
@required this.contentList,
- @required this.codeUrl,
- @required this.docUrl,
+ this.codeUrl,
+ this.docUrl,
this.bottomNaviBar})
: super(key: key);
@@ -34,10 +35,10 @@ class WidgetDemo extends StatefulWidget {
class _WidgetDemoState extends State {
bool _hasCollected = false;
- CollectionControlModel _collectionControl = new CollectionControlModel();
+ /// CollectionControlModel _collectionControl = new CollectionControlModel();
var _collectionIcons;
List widgetDemosList = new WidgetDemoList().getDemos();
- String _router = '';
+ String widgetType = 'old';
final GlobalKey _scaffoldKey = GlobalKey();
List _buildContent() {
@@ -64,56 +65,67 @@ class _WidgetDemoState extends State {
@override
void initState() {
super.initState();
- _collectionControl.getRouterByName(widget.title).then((list) {
- widgetDemosList.forEach((item) {
- if (item.name == widget.title) {
- _router = item.routerName;
+ // 这里不能直接 使用 ` ModalRoute.of(context)` 会产生报错
+ Future.delayed(Duration.zero, () {
+ String currentPath = ModalRoute.of(context).settings.name;
+ if (currentPath.indexOf('/standard-page') == 0) {
+ widgetType = 'standard';
+ }
+ Map params = {
+ 'type': widgetType,
+ "url": currentPath,
+ "name": widget.title
+ };
+ DataUtils.checkCollected(params).then((result) {
+ if (this.mounted) {
+ setState(() {
+ _hasCollected = result ?? null;
+ });
}
});
- if (this.mounted) {
- setState(() {
- _hasCollected = list.length > 0;
- });
- }
});
}
// 点击收藏按钮
_getCollection() {
+ String currentRouterPath = ModalRoute.of(context).settings.name;
+ Map params = {
+ "type": widgetType,
+ "url": currentRouterPath,
+ "name": widget.title
+ };
if (_hasCollected) {
// 删除操作
- _collectionControl.deleteByName(widget.title).then((result) {
- if (result > 0 && this.mounted) {
- setState(() {
- _hasCollected = false;
- });
+ DataUtils.removeCollected(params, context).then((result) {
+ if (result) {
_scaffoldKey.currentState
.showSnackBar(SnackBar(content: Text('已取消收藏')));
if (ApplicationEvent.event != null) {
ApplicationEvent.event
- .fire(CollectionEvent(widget.title, _router, true));
+ .fire(CollectionEvent(widget.title, currentRouterPath, true));
+ }
+ if (this.mounted) {
+ setState(() {
+ _hasCollected = false;
+ });
}
- return;
}
- print('删除错误');
});
} else {
// 插入操作
- _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, _router, false));
+ DataUtils.addCollected(params, context).then((result) {
+ if (result) {
+ if (this.mounted) {
+ setState(() {
+ _hasCollected = true;
+ });
}
-
_scaffoldKey.currentState
.showSnackBar(SnackBar(content: Text('收藏成功')));
+ if (ApplicationEvent.event != null) {
+ ApplicationEvent.event
+ .fire(CollectionEvent(widget.title, currentRouterPath, false));
+ }
}
});
}
@@ -129,7 +141,38 @@ class _WidgetDemoState extends State {
'${Routes.codeView}?filePath=${Uri.encodeComponent(widget.codeUrl)}');
}
}
-
+ List> buildPopupMenu() {
+ List> comps = [];
+ if (widget.docUrl != null) {
+ comps.add(
+ PopupMenuItem(
+ value: 'doc',
+ child: ListTile(
+ leading: Icon(
+ Icons.library_books,
+ size: 22.0,
+ ),
+ title: Text('查看文档'),
+ ),
+ )
+ );
+ }
+ if (widget.codeUrl != null) {
+ comps.add(
+ PopupMenuItem(
+ value: 'code',
+ child: ListTile(
+ leading: Icon(
+ Icons.code,
+ size: 22.0,
+ ),
+ title: Text('查看Demo'),
+ ),
+ )
+ );
+ }
+ return comps;
+ }
@override
Widget build(BuildContext context) {
if (_hasCollected) {
@@ -137,50 +180,34 @@ class _WidgetDemoState extends State {
} else {
_collectionIcons = Icons.favorite_border;
}
+ List> menus = buildPopupMenu();
+ List actions = [
+ new IconButton(
+ tooltip: 'goBack home',
+ onPressed: () {
+ Navigator.popUntil(context, ModalRoute.withName(Routes.root));
+ },
+ icon: Icon(Icons.home),
+ ),
+ new IconButton(
+ tooltip: 'collection',
+ onPressed: _getCollection,
+ icon: Icon(_collectionIcons),
+ ),
+ ];
+ if (menus.length > 0) {
+ actions.add(
+ PopupMenuButton(
+ onSelected: _selectValue,
+ itemBuilder: (BuildContext context) => menus,
+ )
+ );
+ }
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text(widget.title),
- 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),
- ),
- PopupMenuButton(
- onSelected: _selectValue,
- itemBuilder: (BuildContext context) => >[
- const PopupMenuItem(
- value: 'doc',
- child: ListTile(
- leading: Icon(
- Icons.library_books,
- size: 22.0,
- ),
- title: Text('查看文档'),
- ),
- ),
- const PopupMenuDivider(),
- const PopupMenuItem(
- value: 'code',
- child: ListTile(
- leading: Icon(
- Icons.code,
- size: 22.0,
- ),
- title: Text('查看Demo'),
- ),
- ),
- ],
- ),
- ],
+ actions: actions,
),
body: Container(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
diff --git a/lib/components/widget_item_container.dart b/lib/components/widget_item_container.dart
index a1461857..d7438790 100644
--- a/lib/components/widget_item_container.dart
+++ b/lib/components/widget_item_container.dart
@@ -3,56 +3,91 @@ 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 categories;
- final bool isWidgetPoint;
+ final List commonItems;
+// final bool isWidgetPoint;
// 所有的可用demos;
final List widgetDemosList = new WidgetDemoList().getDemos();
WidgetItemContainer(
{Key key,
- @required this.categories,
+ @required this.commonItems,
@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;
+ targetRouter = targetRouter.toLowerCase();
+ }
+ });
+ 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 _buildColumns(context) {
List _listWidget = [];
List _listRows = [];
int addI;
- for (int i = 0, length = categories.length; i < length; i += columnCount) {
+ for (int i = 0, length = commonItems.length; i < length; i += columnCount) {
_listRows = [];
for (int innerI = 0; innerI < columnCount; innerI++) {
addI = innerI + i;
if (addI < length) {
- dynamic item = categories[addI];
+ CommonItem item = commonItems[addI];
+
+
_listRows.add(
Expanded(
flex: 1,
child: WidgetItem(
title: item.name,
onTap: () {
- 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);
+ String type = item.type;
+
+ if (type == "category") {
+ return tapToGroup(item as CategoryComponent, context);
}
+ 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: isWidgetPoint ? 'middle' : 'small',
+ /// textSize: true ? 'middle' : 'small',
+ textSize: 'middle'
),
),
);
@@ -81,3 +116,4 @@ class WidgetItemContainer extends StatelessWidget {
);
}
}
+
diff --git a/lib/event/event_bus.dart b/lib/event/event_bus.dart
index ce2123df..d51e9b10 100644
--- a/lib/event/event_bus.dart
+++ b/lib/event/event_bus.dart
@@ -2,4 +2,4 @@ import 'package:event_bus/event_bus.dart';
class ApplicationEvent{
static EventBus event;
-}
\ No newline at end of file
+}
diff --git a/lib/event/event_model.dart b/lib/event/event_model.dart
index f72f0cb6..ca753ec9 100644
--- a/lib/event/event_model.dart
+++ b/lib/event/event_model.dart
@@ -4,4 +4,16 @@ 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);
}
\ No newline at end of file
diff --git a/lib/main.dart b/lib/main.dart
index 89fd9d3d..ec88b683 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,12 +1,8 @@
-import 'dart:async';
-import 'dart:core';
-
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter/rendering.dart';
-import 'package:url_launcher/url_launcher.dart';
import 'routers/routers.dart';
-import 'routers/application.dart';
+import 'routers/application.dart' show Application;
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutter_go/utils/provider.dart';
import 'package:flutter_go/utils/shared_preferences.dart';
@@ -16,19 +12,24 @@ 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';
+import 'package:flutter_go/utils/net_utils.dart';
-const int ThemeColor = 0xFFC91B3A;
SpUtil sp;
var db;
class MyApp extends StatefulWidget {
MyApp() {
final router = new Router();
-
Routes.configureRoutes(router);
-
+ // 这里设置项目环境
Application.router = router;
}
@@ -39,70 +40,144 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State {
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;
+ }
+
+ /// 服务端控制是否显示业界动态
+ Future _reqsMainPageIsOpen() async {
+ const reqs = 'https://flutter-go.pub/api/isInfoOpen';
+ var response;
+ try{
+ response = await NetUtils.get(reqs, {});
+ print('response-$response');
+ if(response['status'] == 200 && response['success'] ==true && response['data'] is Map && response['data']['isOpen'] == true) {
+ Application.pageIsOpen = true;
+ print('是否需要展开【业界动态】${Application.pageIsOpen}');
+ }
+ }catch(e){
+ print('response-$e');
+ }
+ return response;
+ }
@override
- Future initState() {
+ void initState() {
super.initState();
- var platformAandroid =
- (Theme.of(context).platform == TargetPlatform.android);
- DataUtils.checkVersion({'name': 'FlutterGo'}).then((bool) {
- print("返回值back ${bool}");
- if (platformAandroid && bool) {
- setState(() {});
- _UpdateURL();
- }
- }).catchError((onError) {
- print('获取失败:$onError');
+ _reqsMainPageIsOpen();
+ _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) {
- setState(() {
- _hasLogin = hasLogin;
- _isLoading = false;
- });
+ 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 = true;
+ _hasLogin = false;
_isLoading = false;
});
print('身份信息验证失败:$onError');
});
- }
- _UpdateURL() async {
- const currUrl =
- 'https://github.com/alibaba/flutter-go/raw/master/FlutterGo.apk';
- if (await canLaunch(currUrl)) {
- await launch(currUrl);
- } else {
- throw 'Could not launch $currUrl';
- }
+ ApplicationEvent.event.on().listen((event) {
+ print('接收到的 event $event');
+ });
}
showWelcomePage() {
-// if (_isLoading) {
-// return Container(
-// color: const Color(ThemeColor),
-// child: Center(
-// child: SpinKitPouringHourglass(color: Colors.white),
-// ),
-// );
-// } else {
-// // 判断是否已经登录
-// if (_hasLogin) {
- return AppPage();
-// } else {
-// return LoginPage();
-// }
-// }
+ if (_isLoading) {
+ return Container(
+ color: Color(this.themeColor),
+ child: Center(
+ child: SpinKitPouringHourglass(color: Colors.white),
+ ),
+ );
+ } else {
+ // 判断是否已经登录
+ if (_hasLogin) {
+ return AppPage(_userInfo);
+ } else {
+ return LoginPage();
+ }
+ }
}
@override
Widget build(BuildContext context) {
+// WidgetTree.getCommonItemByPath([15, 17], Application.widgetTree);
return new MaterialApp(
- title: 'title',
+ title: 'titles',
theme: new ThemeData(
- primaryColor: Color(ThemeColor),
+ primaryColor: Color(this.themeColor),
backgroundColor: Color(0xFFEFEFEF),
accentColor: Color(0xFF888888),
textTheme: TextTheme(
@@ -110,14 +185,18 @@ class _MyAppState extends State {
body1: TextStyle(color: Color(0xFF888888), fontSize: 16.0),
),
iconTheme: IconThemeData(
- color: Color(ThemeColor),
+ color: Color(this.themeColor),
size: 35.0,
),
),
+<<<<<<< HEAD
home: new Scaffold(
body: showWelcomePage()
),
+=======
+ home: new Scaffold(body: showWelcomePage()),
+>>>>>>> dxj/master
debugShowCheckedModeBanner: false,
onGenerateRoute: Application.router.generator,
navigatorObservers: [Analytics.observer],
@@ -125,11 +204,25 @@ class _MyAppState extends State {
}
}
+void _startupJpush() async {
+ print("初始化jpush");
+ await FlutterJPush.startup();
+ print("初始化jpush成功");
+}
+
void main() async {
+ WidgetsFlutterBinding.ensureInitialized();
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());
}
+
diff --git a/lib/model/cat.dart b/lib/model/cat.dart
index e9ecae7b..5ac493f4 100644
--- a/lib/model/cat.dart
+++ b/lib/model/cat.dart
@@ -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 mainList() async{
- List listJson = await sql.getByCondition(conditions: {'parentId': 0});
- List cats = listJson.map((json) {
- return new Cat.fromJSON(json);
- }).toList();
- return cats;
- }
-
- // 获取Cat不同深度与parent的列表
- Future> 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 cats = listJson.map((json) {
- return new Cat.fromJSON(json);
- }).toList();
- return cats;
- }
-
- // 通过name获取Cat对象信息
- Future 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 mainList() async{
+// List listJson = await sql.getByCondition(conditions: {'parentId': 0});
+// List cats = listJson.map((json) {
+// return new Cat.fromJSON(json);
+// }).toList();
+// return cats;
+// }
+//
+// // 获取Cat不同深度与parent的列表
+// Future> 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 cats = listJson.map((json) {
+// return new Cat.fromJSON(json);
+// }).toList();
+// return cats;
+// }
+//
+// // 通过name获取Cat对象信息
+// Future getCatByName(String name) async {
+// List json = await sql.getByCondition(conditions: {'name': name});
+// if (json.isEmpty) {
+// return null;
+// }
+// return new Cat.fromJSON(json.first);
+// }
+//
+//}
diff --git a/lib/model/collection.dart b/lib/model/collection.dart
index 388fb3d8..49233bbe 100644
--- a/lib/model/collection.dart
+++ b/lib/model/collection.dart
@@ -49,15 +49,21 @@ class CollectionControlModel {
List list = await sql.getByCondition();
List resultList = [];
list.forEach((item){
- print(item);
+ print('collection item =>> $item');
resultList.add(Collection.fromJSON(item));
});
return resultList;
}
- // 通过收藏名获取router
- Future getRouterByName(String name) async {
- List list = await sql.getByCondition(conditions: {'name': name});
+ /// 通过收藏名获取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});
return list;
}
@@ -65,4 +71,8 @@ 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');
+ }
}
diff --git a/lib/model/responseData.dart b/lib/model/responseData.dart
new file mode 100644
index 00000000..1b5327e5
--- /dev/null
+++ b/lib/model/responseData.dart
@@ -0,0 +1,25 @@
+class ResponseData{
+ int status;
+ bool success;
+ String message;
+
+ ResponseData(this.status, this.success,this.message);
+
+ ResponseData.fromJson(Map json)
+ : status = json['status'],
+ success = json['success'],
+ message=json['message'];
+
+ Map toJson() =>
+ {
+ 'status': status,
+ 'success': success,
+ 'messsage': message
+ };
+
+ @override
+ String toString() {
+ return 'status: $status ,success: $success,message: ${message.toString()}';
+ }
+
+}
\ No newline at end of file
diff --git a/lib/model/search_history.dart b/lib/model/search_history.dart
index da2e4cdd..ecaef036 100644
--- a/lib/model/search_history.dart
+++ b/lib/model/search_history.dart
@@ -73,7 +73,7 @@ class SearchHistoryList {
}
add(SearchHistory item) {
- print("_searchHistoryList> ${_searchHistoryList.length}");
+ print("add item to serach history ${item.targetRouter}");
for (SearchHistory value in _searchHistoryList) {
if (value.name == item.name) {
return;
diff --git a/lib/model/user_info.dart b/lib/model/user_info.dart
index b47b08a3..5007e512 100644
--- a/lib/model/user_info.dart
+++ b/lib/model/user_info.dart
@@ -1,24 +1,32 @@
-class UserInfo {
+class UserInformation {
String username;
int id;
String avatarPic;
String themeColor;
- String urlName;
- UserInfo({
+ UserInformation({
this.avatarPic,
this.id,
this.themeColor,
- this.urlName,
this.username,
});
- factory UserInfo.fromJson(Map json) {
- return UserInfo(
+ factory UserInformation.fromJson(Map 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(
avatarPic: json['avatar_pic'],
- id: int.parse(json['id']),
- username: json['name'],
- themeColor: json['theme_color'],
- urlName: json['url_name']);
+ id: userId,
+ username: name,
+ themeColor: json['theme_color']);
}
}
diff --git a/lib/model/widget.dart b/lib/model/widget.dart
index bcc6ae7f..c0f37d0d 100644
--- a/lib/model/widget.dart
+++ b/lib/model/widget.dart
@@ -2,9 +2,16 @@
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;
@@ -142,3 +149,226 @@ class WidgetControlModel {
return widgets;
}
}
+// 抽象类
+abstract class CommonItem {
+ int id;
+ String name;
+ int parentId;
+ String type;
+ List 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 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 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;
+ }
+}
\ No newline at end of file
diff --git a/lib/page_demo_package/.demo.json b/lib/page_demo_package/.demo.json
new file mode 100644
index 00000000..ff076189
--- /dev/null
+++ b/lib/page_demo_package/.demo.json
@@ -0,0 +1 @@
+[{"name":"PullToRefresh","screenShot":"","author":"chenfeihu","email":"763551832@qq.com","desc":"刷新组件","id":"5553db80_52ae_4241_9c8a_5c9e1f92b096"},{"name":"RangeSlider","screenShot":"","author":"RangeSlider","email":"hanxu317@qq.com","desc":"RangeSlider widget demo","id":"e5f958bc_52ae_4241_9c8a_5c9e1f92b096"},{"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"}]
\ No newline at end of file
diff --git a/lib/page_demo_package/PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/.demo.json b/lib/page_demo_package/PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/.demo.json
new file mode 100644
index 00000000..1fe09bd0
--- /dev/null
+++ b/lib/page_demo_package/PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/.demo.json
@@ -0,0 +1,9 @@
+{
+ "name": "PullToRefresh",
+ "screenShot": "",
+ "author":"chenfeihu",
+ "email": "763551832@qq.com",
+ "desc": "刷新组件",
+ "id": "5553db80_52ae_4241_9c8a_5c9e1f92b096"
+}
+
\ No newline at end of file
diff --git a/lib/page_demo_package/PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/page_demo_package/PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..f3f84726
--- /dev/null
+++ b/lib/page_demo_package/PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,15 @@
+//
+// Created with flutter go cli
+// User: chenfeihu
+// Time: 2019-09-24 12:11:14.085126
+// email: 763551832@qq.com
+// desc: 刷新组件
+//
+
+import 'src/index.dart';
+
+var demoWidgets = [
+ new Demo()
+];
+
+
\ No newline at end of file
diff --git a/lib/page_demo_package/PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/src/index.dart b/lib/page_demo_package/PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/src/index.dart
new file mode 100644
index 00000000..1558967c
--- /dev/null
+++ b/lib/page_demo_package/PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/src/index.dart
@@ -0,0 +1,241 @@
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+import 'package:pull_to_refresh/pull_to_refresh.dart';
+
+
+class Demo extends StatefulWidget {
+ @override
+ _State createState() => _State();
+}
+
+class _State extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.all(5.0),
+ width: double.infinity,
+ height: 600.0,
+ child: Pulltorefresh(),
+ );
+ }
+}
+
+class Pulltorefresh extends StatefulWidget {
+ @override
+ _PulltorefreshState createState() => _PulltorefreshState();
+}
+
+class _PulltorefreshState extends State {
+ List datas=ListData.getList();
+ RefreshController _controller=RefreshController(initialRefresh: false);
+
+ void _onRefresh() async{
+ await Future.delayed(Duration(milliseconds: 1000));
+ _controller.refreshCompleted();
+ }
+
+ void _onLoading() async{
+ await Future.delayed(Duration(milliseconds: 1500));
+ ItemModel model=ItemModel(getRandomColor(), Icons.airplanemode_active, "军事新闻", "俄军大秀战略",
+ "酝酿已久的俄罗斯“中部-2019”战略演习于16日正式启动", 5000);
+
+ this.datas.add(Item(getRandomColor(), model.icon, model.mainTitle, model.subTitle, model.des, model.readCount));
+ this.datas.add(Item(getRandomColor(), model.icon, model.mainTitle, model.subTitle, model.des, model.readCount));
+ this.datas.add(Item(getRandomColor(), model.icon, model.mainTitle, model.subTitle, model.des, model.readCount));
+ this.datas.add(Item(getRandomColor(), model.icon, model.mainTitle, model.subTitle, model.des, model.readCount));
+ this.datas.add(Item(getRandomColor(), model.icon, model.mainTitle, model.subTitle, model.des, model.readCount));
+ this.datas.add(Item(getRandomColor(), model.icon, model.mainTitle, model.subTitle, model.des, model.readCount));
+ this.datas.add(Item(getRandomColor(), model.icon, model.mainTitle, model.subTitle, model.des, model.readCount));
+ this.datas.add(Item(getRandomColor(), model.icon, model.mainTitle, model.subTitle, model.des, model.readCount));
+ if(mounted)
+ setState(() {
+
+ });
+ _controller.loadComplete();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+
+ Widget _itemBuilder(BuildContext context, int position) {
+
+ return Card(child: this.datas[position]);
+
+ }
+ return Scaffold(
+ appBar: AppBar(
+ title: Text("Pulltorefresh"),
+ ),
+ body: SmartRefresher(
+ enablePullDown: true,
+ enablePullUp: true,
+ header: WaterDropHeader(),
+ footer: ClassicFooter(
+ loadStyle: LoadStyle.ShowAlways,
+ completeDuration: Duration(microseconds: 50),
+ ),
+ onRefresh: _onRefresh,
+ onLoading: _onLoading,
+ controller: _controller,
+ child: ListView.builder(itemBuilder: _itemBuilder,itemCount: this.datas.length),
+
+
+ ),
+
+
+ );
+ }
+
+
+ Color getRandomColor(){
+ List colors=[Colors.deepOrange,Colors.amber,Colors.cyan,Colors.green,Colors.red,Colors.yellow];
+ int randomValue=Random().nextInt(colors.length);
+ if(randomValue==colors.length){
+ randomValue=colors.length-1;
+ }
+ return colors[randomValue];
+
+ }
+
+}
+
+
+
+class Item extends StatelessWidget {
+ Color color;
+ IconData icon;
+ String mainTitle;
+ String subTitle;
+ String des;
+ int readCount;
+
+ Item(this.color, this.icon, this.mainTitle, this.subTitle, this.des,
+ this.readCount);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0),
+ height: 90.0,
+ child: Row(
+ children: [
+ Container(
+ width: 90.0,
+ color: color,
+ alignment: Alignment.center,
+ child: Icon(icon, color: Colors.white),
+ ),
+ SizedBox(width: 10),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Expanded(
+ child: Text(mainTitle,
+ style: TextStyle(
+ fontWeight: FontWeight.bold, fontSize: 18.0))),
+ Expanded(child: Text(subTitle, style: TextStyle(fontSize: 14.0))),
+ Expanded(
+ child: Text(
+ des,
+ style: TextStyle(fontSize: 13.0),
+ overflow: TextOverflow.ellipsis,
+ )),
+ Expanded(
+ child: Text("阅读量:${readCount.toString()}",
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 14.0,
+ color: Colors.redAccent))),
+ ],
+ ))
+ ],
+ ),
+ );
+ }
+}
+
+class ItemModel{
+ Color _color;
+ IconData _icon;
+ String _mainTitle;
+ String _subTitle;
+ String _des;
+ int _readCount;
+
+ ItemModel(this._color, this._icon, this._mainTitle, this._subTitle, this._des,
+ this._readCount);
+
+ int get readCount => _readCount;
+
+ set readCount(int value) {
+ _readCount = value;
+ }
+
+ String get des => _des;
+
+ set des(String value) {
+ _des = value;
+ }
+
+ String get subTitle => _subTitle;
+
+ set subTitle(String value) {
+ _subTitle = value;
+ }
+
+ String get mainTitle => _mainTitle;
+
+ set mainTitle(String value) {
+ _mainTitle = value;
+ }
+
+ IconData get icon => _icon;
+
+ set icon(IconData value) {
+ _icon = value;
+ }
+
+ Color get color => _color;
+
+ set color(Color value) {
+ _color = value;
+ }
+
+
+}
+
+class ListData{
+ static List getList(){
+ List models=[];
+ ItemModel model1= ItemModel(Colors.red, Icons.airplanemode_active, "军事新闻", "俄军大秀战略",
+ "酝酿已久的俄罗斯“中部-2019”战略演习于16日正式启动", 2999);
+ ItemModel model2= ItemModel(Colors.red, Icons.airplanemode_active, "军事新闻", "俄“中部”演习",
+ "俄罗斯卫星网报道称,俄罗斯国防部长绍伊古表示,“中央-2019”战略演习是", 4588);
+ ItemModel model3= ItemModel(Colors.red, Icons.airplanemode_active, "军事新闻", "中国2.7万吨坞登舰",
+ "据印度新德里电视台16日报道,印度海军发现7艘中国军舰在印度洋", 7777);
+ ItemModel model4= ItemModel(Colors.red, Icons.airplanemode_active, "军事新闻", "针对中国?",
+ "美国空军着力打造军用5G网络,5G+VR,飞行员无需上天就能操控战机;美军濒海", 8888);
+ ItemModel model5= ItemModel(Colors.red, Icons.airplanemode_active, "军事新闻", "“凯旋”防空导弹系统",
+ "俄罗斯卫星通讯社报道,俄罗斯北方舰队(Russian Northern Fleet)新闻处", 9999);
+ ItemModel model6= ItemModel(Colors.red, Icons.airplanemode_active, "军事新闻", "火箭军还有骑兵连",
+ "迅速对禁区“敌特分子”活动区域进行侦察定位,战斗小分队", 104754);
+ ItemModel model7= ItemModel(Colors.red, Icons.airplanemode_active, "军事新闻", "侦察兵跨越冰川",
+ "在海拔5000多米的雪域高原,第77集团军某合成旅的侦察兵们正在进行野外驻训", 47545);
+ ItemModel model8= ItemModel(Colors.red, Icons.airplanemode_active, "军事新闻", "香港被护商船",
+ "新京报快讯 据北海舰队官微消息:“感谢海军!”“祖国万岁!”,当地时", 124574);
+
+ models.add(Item(model1.color, model1.icon, model1.mainTitle, model1.subTitle, model1.des, model1.readCount));
+ models.add(Item(model2.color, model2.icon, model2.mainTitle, model2.subTitle, model2.des, model2.readCount));
+ models.add(Item(model3.color, model3.icon, model3.mainTitle, model3.subTitle, model3.des, model3.readCount));
+ models.add(Item(model4.color, model4.icon, model4.mainTitle, model4.subTitle, model4.des, model4.readCount));
+ models.add(Item(model5.color, model5.icon, model5.mainTitle, model5.subTitle, model5.des, model5.readCount));
+ models.add(Item(model6.color, model6.icon, model6.mainTitle, model6.subTitle, model6.des, model6.readCount));
+ models.add(Item(model7.color, model7.icon, model7.mainTitle, model7.subTitle, model7.des, model7.readCount));
+ models.add(Item(model8.color, model8.icon, model8.mainTitle, model8.subTitle, model8.des, model8.readCount));
+ return models;
+ }
+}
+
+
diff --git a/lib/page_demo_package/RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/.demo.json b/lib/page_demo_package/RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/.demo.json
new file mode 100644
index 00000000..10444611
--- /dev/null
+++ b/lib/page_demo_package/RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/.demo.json
@@ -0,0 +1,8 @@
+{
+ "name": "RangeSlider",
+ "screenShot": "",
+ "author":"RangeSlider",
+ "email": "hanxu317@qq.com",
+ "desc": "RangeSlider widget demo",
+ "id": "e5f958bc_52ae_4241_9c8a_5c9e1f92b096"
+}
diff --git a/lib/page_demo_package/RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/page_demo_package/RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..53760649
--- /dev/null
+++ b/lib/page_demo_package/RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,15 @@
+//
+// Created with flutter go cli
+// User: RangeSlider
+// Time: 2019-09-12 15:11:05.512158
+// email: hanxu317@qq.com
+// desc: RangeSlider widget demo
+//
+
+import 'src/index.dart';
+
+var demoWidgets = [
+ new Demo()
+];
+
+
\ No newline at end of file
diff --git a/lib/page_demo_package/RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/src/index.dart b/lib/page_demo_package/RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/src/index.dart
new file mode 100644
index 00000000..bc34bf8f
--- /dev/null
+++ b/lib/page_demo_package/RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/src/index.dart
@@ -0,0 +1,30 @@
+import 'package:flutter/material.dart';
+
+class Demo extends StatefulWidget {
+ @override
+ _State createState() => _State();
+}
+
+class _State extends State {
+ RangeValues valuess = RangeValues(20.0, 50.0);
+ @override
+ Widget build(BuildContext context) {
+ return RangeSlider(
+ values: valuess,
+ //实际进度的位置
+ inactiveColor: Colors.black12,
+ //进度中不活动部分的颜色
+ labels: RangeLabels('12', '23'),
+ min: 0.0,
+ max: 100.0,
+ divisions: 1000,
+ activeColor: Colors.blue,
+ //进度中活动部分的颜色
+ onChanged: (rangeValues) {
+ setState(() {
+ valuess = rangeValues;
+ });
+ },
+ );
+ }
+}
diff --git a/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/.demo.json b/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/.demo.json
new file mode 100644
index 00000000..de6b8e00
--- /dev/null
+++ b/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/.demo.json
@@ -0,0 +1,9 @@
+{
+ "name": "demoName",
+ "screenShot": "",
+ "author":"yourName",
+ "email": "yourEmail",
+ "desc": "这是一个测试的标准demo",
+ "id": "1a29aa8e_32ae_4241_9c8a_5c9e1f92b096"
+}
+
\ No newline at end of file
diff --git a/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..68193686
--- /dev/null
+++ b/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,15 @@
+//
+// 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()
+];
+
+
\ No newline at end of file
diff --git a/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/src/index.dart b/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/src/index.dart
new file mode 100644
index 00000000..e2992379
--- /dev/null
+++ b/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/src/index.dart
@@ -0,0 +1,16 @@
+import 'package:flutter/material.dart';
+
+class Demo extends StatefulWidget {
+ @override
+ _State createState() => _State();
+}
+
+class _State extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ child: RaisedButton(onPressed: () {}, child: Text('我是md中引入的demo'))
+ );
+ }
+}
+
\ No newline at end of file
diff --git a/lib/page_demo_package/index.dart b/lib/page_demo_package/index.dart
new file mode 100644
index 00000000..c3ed991d
--- /dev/null
+++ b/lib/page_demo_package/index.dart
@@ -0,0 +1,10 @@
+import 'PullToRefresh_chenfeihu_5553db80_52ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardDemo_PullToRefresh_5553db80_52ae_4241_9c8a_5c9e1f92b096;
+import 'RangeSlider_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardDemo_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096;
+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 = {
+ '5553db80_52ae_4241_9c8a_5c9e1f92b096': StandardDemo_PullToRefresh_5553db80_52ae_4241_9c8a_5c9e1f92b096.demoWidgets,
+ 'e5f958bc_52ae_4241_9c8a_5c9e1f92b096': StandardDemo_RangeSlider_e5f958bc_52ae_4241_9c8a_5c9e1f92b096.demoWidgets,
+ '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
+};
\ No newline at end of file
diff --git a/lib/page_demo_package/info.json b/lib/page_demo_package/info.json
new file mode 100644
index 00000000..669b078a
--- /dev/null
+++ b/lib/page_demo_package/info.json
@@ -0,0 +1,17 @@
+{
+ "70c429df-c27d-4843-8e28-1e6885c9276b": {
+ "name": "button-red",
+ "screenShot": "",
+ "author": "sanfan",
+ "email": "sanfan.hx@alibaba-inc.com",
+ "desc": "desc",
+ }
+}
+
+
+
+
+
+
+
+
diff --git a/lib/page_demo_package/local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/.demo.json b/lib/page_demo_package/local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/.demo.json
new file mode 100644
index 00000000..e6e8114d
--- /dev/null
+++ b/lib/page_demo_package/local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/.demo.json
@@ -0,0 +1,9 @@
+{
+ "name": "local",
+ "screenShot": "",
+ "author":"ab",
+ "email": "email",
+ "desc": "ags",
+ "id": "2c1d57d0_42ae_4241_9c8a_5c9e1f92b096"
+}
+
\ No newline at end of file
diff --git a/lib/page_demo_package/local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/page_demo_package/local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..4e315373
--- /dev/null
+++ b/lib/page_demo_package/local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,15 @@
+//
+// 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()
+];
+
+
\ No newline at end of file
diff --git a/lib/page_demo_package/local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/src/index.dart b/lib/page_demo_package/local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/src/index.dart
new file mode 100644
index 00000000..d0d3921e
--- /dev/null
+++ b/lib/page_demo_package/local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/src/index.dart
@@ -0,0 +1,16 @@
+import 'package:flutter/material.dart';
+
+class Demo extends StatefulWidget {
+ @override
+ _State createState() => _State();
+}
+
+class _State extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ child: Text("this is flutter go init demo"),
+ );
+ }
+}
+
\ No newline at end of file
diff --git a/lib/page_demo_package/readme.md b/lib/page_demo_package/readme.md
new file mode 100644
index 00000000..be5a40f1
--- /dev/null
+++ b/lib/page_demo_package/readme.md
@@ -0,0 +1,20 @@
+# 目录说明
+
+本目录文件结构与文件命名, 使用cli进行更新
+
+
+# demos 目录文件结构
+
+```
+demos
+├── ${demoName}-${author}-${32位demoID}
+│ ├── index.dart
+│ └── src
+│ ├── .demo.json
+│ └── ${demoName}.dart
+├── ...${demoName}-${author}-${32位demoID}
+├── index.dart
+├── info.json
+└── readme.md
+```
+
\ No newline at end of file
diff --git a/lib/resources/widget_name_to_icon.dart b/lib/resources/widget_name_to_icon.dart
index 644d145d..82f2593f 100644
--- a/lib/resources/widget_name_to_icon.dart
+++ b/lib/resources/widget_name_to_icon.dart
@@ -1,9 +1,11 @@
import 'package:flutter/material.dart';
class WidgetName2Icon {
static Map icons = {
+ "Developer": Icons.developer_mode,
+ "Standard": Icons.pages ,
"Element":Icons.explicit,
"Components":Icons.extension,
- "Themes":Icons.filter_b_and_w,
+ "Theme":Icons.filter_b_and_w,
"Form":Icons.table_chart,
"Frame":Icons.aspect_ratio,
"Media":Icons.subscriptions,
diff --git a/lib/routers/application.dart b/lib/routers/application.dart
index 8a03d9c7..0724ad89 100644
--- a/lib/routers/application.dart
+++ b/lib/routers/application.dart
@@ -1,12 +1,21 @@
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 sharePeferences;
+ static SpUtil sharePeference;
+ static CategoryComponent widgetTree;
+ static bool pageIsOpen = false;
static Map github = {
'widgetsURL':'https://github.com/alibaba/flutter-go/blob/develop/lib/widgets/',
@@ -14,4 +23,15 @@ class Application {
//'master':'https://github.com/alibaba-paimai-frontend/flutter-common-widgets-app/tree/master/lib/widgets/'
};
+ /// 所有获取配置的唯一入口
+ Map get config {
+ if (Application.env == ENV.PRODUCTION) {
+ return {};
+ }
+ if (Application.env == ENV.DEV) {
+ return {};
+ }
+ return {};
+ }
+
}
diff --git a/lib/routers/router_handler.dart b/lib/routers/router_handler.dart
index e9f7698e..cd655b92 100644
--- a/lib/routers/router_handler.dart
+++ b/lib/routers/router_handler.dart
@@ -8,38 +8,66 @@ 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> params) {
- return new AppPage();
+ return new AppPage(UserInformation(id: 0));
},
);
+var collectionFullHandler = new Handler(
+ handlerFunc: (BuildContext context,Map> params){
+ bool hasLogined = params['hasLogin']?.first == 'true';
+ return CollectionFullPage(hasLogined: hasLogined);
+ }
+);
+
+var collectionHandler = new Handler(
+ handlerFunc: (BuildContext context,Map> params){
+ bool hasLogined = params['hasLogin']?.first == 'true';
+ return CollectionPage(hasLogined: hasLogined);
+ }
+);
+
var categoryHandler = new Handler(
handlerFunc: (BuildContext context, Map> params) {
- String name = params["type"]?.first;
+ String ids = params["ids"]?.first;
- return new CategoryHome(name);
+ return new CategoryHome(ids);
},
);
var widgetNotFoundHandler = new Handler(
handlerFunc: (BuildContext context, Map> params) {
- return new WidgetNotFound();
-});
+ return new WidgetNotFound();
+ });
var loginPageHandler = new Handler(
handlerFunc: (BuildContext context, Map> params) {
- return LoginPage();
-});
+ return LoginPage();
+ });
var fullScreenCodeDialog = new Handler(
handlerFunc: (BuildContext context, Map> params) {
- String path = params['filePath']?.first;
- return new FullScreenCodeDialog(
- filePath: path,
- );
-});
+ String path = params['filePath']?.first;
+ return new FullScreenCodeDialog(
+ filePath: path,
+ );
+ });
+
+
+var githubCodeDialog = new Handler(
+ handlerFunc: (BuildContext context, Map> params) {
+ String path = params['remotePath']?.first;
+ return new FullScreenCodeDialog(
+ remoteFilePath: path,
+ );
+ });
var webViewPageHand = new Handler(
handlerFunc: (BuildContext context, Map> params) {
@@ -47,3 +75,17 @@ var webViewPageHand = new Handler(
String url = params['url']?.first;
return new WebViewPage(url, title);
});
+
+
+var standardPageHandler = new Handler(
+ handlerFunc: (BuildContext context, Map> params) {
+ String id = params['id']?.first;
+ return StandardView(id: id);
+ }
+);
+
+
+var issuesMessageHandler = new Handler(
+ handlerFunc: (BuildContext context, Map> params) {
+ return IssuesMessagePage();
+ });
diff --git a/lib/routers/routers.dart b/lib/routers/routers.dart
index 116fc33d..e21ddbae 100644
--- a/lib/routers/routers.dart
+++ b/lib/routers/routers.dart
@@ -3,39 +3,53 @@ 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();
- router.notFoundHandler = new Handler(
- handlerFunc: (BuildContext context, Map> params) {
- });
+// router.notFoundHandler = new Handler(
+// handlerFunc: (BuildContext context, Map> params) {
+// }
+// );
router.define(home, handler: homeHandler);
-
- router.define('/category/:type', handler: categoryHandler);
+ router.define(collectionPage,handler:collectionHandler);
+ router.define(collectionFullPage,handler:collectionFullHandler);
+ router.define('/category/:ids', handler: categoryHandler);
router.define('/category/error/404', handler: widgetNotFoundHandler);
router.define(loginPage, handler: loginPageHandler);
router.define(codeView,handler:fullScreenCodeDialog);
+ router.define(githubCodeView,handler:githubCodeDialog);
router.define(webViewPage,handler:webViewPageHand);
- widgetDemosList.forEach((demo) {
- Handler handler = new Handler(
- handlerFunc: (BuildContext context, Map> params) {
- print('组件路由params=$params widgetsItem=${demo.routerName}');
- analytics.logEvent(
- name: 'component', parameters: {'name': demo.routerName });
- return demo.buildRouter(context);
- });
- router.define('${demo.routerName}', handler: handler);
+ router.define(issuesMessage, handler: issuesMessageHandler);
+ router.define(standardPage,handler:standardPageHandler);
+ widgetDemosList.forEach((demo) {
+ Handler handler = new Handler(
+ handlerFunc: (BuildContext context, Map> params) {
+ print('组件路由params=$params widgetsItem=${demo.routerName}');
+ analytics.logEvent(
+ name: 'component', parameters: {'name': demo.routerName });
+ return demo.buildRouter(context);
+ });
+ String path = demo.routerName;
+ router.define('${path.toLowerCase()}', handler: handler);
});
+// router.define(webViewPage,handler:webViewPageHand);
+// standardPages.forEach((String id, String md) => {
+//
+// });
}
}
diff --git a/lib/standard_pages/.pages.json b/lib/standard_pages/.pages.json
new file mode 100644
index 00000000..fa8e84db
--- /dev/null
+++ b/lib/standard_pages/.pages.json
@@ -0,0 +1 @@
+[{"name":"PullToRefresh","screenShot":"","author":"chenfeihu","title":"PullToRefresh","email":"763551832@qq.com","desc":"Refresh conponent","id":"cd9b8b80_52ae_4241_9c8a_5c9e1f92b096"},{"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"},{"name":"RangeSlider","screenShot":"","author":"hanxu","title":"RangeSlider","email":"hanxu317@qq.com","desc":"RangeSlider widget","id":"cbffbf7c_52ae_4241_9c8a_5c9e1f92b096"}]
\ No newline at end of file
diff --git a/lib/standard_pages/PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/.page.json b/lib/standard_pages/PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/.page.json
new file mode 100644
index 00000000..b007469b
--- /dev/null
+++ b/lib/standard_pages/PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/.page.json
@@ -0,0 +1,10 @@
+{
+ "name": "PullToRefresh",
+ "screenShot": "",
+ "author":"chenfeihu",
+ "title":"PullToRefresh",
+ "email": "763551832@qq.com",
+ "desc": "Refresh conponent",
+ "id": "cd9b8b80_52ae_4241_9c8a_5c9e1f92b096"
+}
+
\ No newline at end of file
diff --git a/lib/standard_pages/PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/standard_pages/PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..f675dbc6
--- /dev/null
+++ b/lib/standard_pages/PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,87 @@
+String getMd() {
+ return """
+# PullToRefresh
+
+> 下拉刷新 上拉加载
+
+PullToRefresh 是一个刷新列表组件,借助于pull_to_refresh库实现,感觉这是目前最好的一款三方刷新库,它的可定制性比较好,刷新样式多样化,已经满足大部分的开发需求。
+
+### **基本用法**
+
+* 添加依赖 pull_to_refresh: ^1.5.6
+* ListView包裹一层SmartRefresher
+
+
+
+### **SmartRefresher常用属性说明**
+
+* **enablePullDown** 允许下拉刷新
+* **enablePullUp** 允许上拉加载
+* **header** 下拉刷新头部样式
+* **footer** 上拉加载底部样式
+* **onRefresh** 下拉刷新的回调
+* **onLoading** 上拉加载的回调
+* **controller** 刷新控件的控制器,用来处理回调状态等
+
+
+### **国际化显示**
+
+ ```
+ 需要添加语言本地化SDK,不然刷新库头部与底部显示加载提示内容为英文
+
+ 添加依赖 flutter_localizations:
+ sdk: flutter
+
+ main.dart中MateriaApp里面添加以下内容
+
+ localizationsDelegates: [
+ // 这行是关键
+ RefreshLocalizations.delegate,
+ GlobalWidgetsLocalizations.delegate,
+ GlobalMaterialLocalizations.delegate
+ ],
+ supportedLocales: [
+ const Locale('en'),
+ const Locale('zh'),
+ ],
+ localeResolutionCallback:
+ (Locale locale, Iterable supportedLocales) {
+ //print("change language");
+ return locale;
+ },
+
+ ```
+
+
+### **全局配置**
+ 全局配置RefreshConfiguration,配置子树下的所有SmartRefresher表现,一般存放于MaterialApp的根部
+
+ ```
+ RefreshConfiguration(
+ headerBuilder: () => WaterDropHeader(), // 配置默认头部指示器,假如你每个页面的头部指示器都一样的话,你需要设置这个
+ footerBuilder: () => ClassicFooter(), // 配置默认底部指示器
+ headerTriggerDistance: 80.0, // 头部触发刷新的越界距离
+ springDescription:SpringDescription(stiffness: 170, damping: 16, mass: 1.9), // 自定义回弹动画,三个属性值意义请查询flutter api
+ maxOverScrollExtent :100, //头部最大可以拖动的范围,如果发生冲出视图范围区域,请设置这个属性
+ maxUnderScrollExtent:0, // 底部最大可以拖动的范围
+ enableScrollWhenRefreshCompleted: true, //这个属性不兼容PageView和TabBarView,如果你特别需要TabBarView左右滑动,你需要把它设置为true
+ enableLoadingWhenFailed : true, //在加载失败的状态下,用户仍然可以通过手势上拉来触发加载更多
+ hideFooterWhenNotFull: false, // Viewport不满一屏时,禁用上拉加载更多功能
+ enableBallisticLoad: true, // 可以通过惯性滑动触发加载更多
+ child: MaterialApp(
+ ........
+ )
+ );
+
+ ```
+
+
+### 实例展示
+
+[demo:5553db80_52ae_4241_9c8a_5c9e1f92b096]
+
+
+
+""";
+
+}
diff --git a/lib/standard_pages/PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/index.md b/lib/standard_pages/PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/index.md
new file mode 100644
index 00000000..1dca085b
--- /dev/null
+++ b/lib/standard_pages/PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/index.md
@@ -0,0 +1,82 @@
+# PullToRefresh
+
+> 下拉刷新 上拉加载
+
+PullToRefresh 是一个刷新列表组件,借助于pull_to_refresh库实现,感觉这是目前最好的一款三方刷新库,它的可定制性比较好,刷新样式多样化,已经满足大部分的开发需求。
+
+### **基本用法**
+
+* 添加依赖 pull_to_refresh: ^1.5.6
+* ListView包裹一层SmartRefresher
+
+
+
+### **SmartRefresher常用属性说明**
+
+* **enablePullDown** 允许下拉刷新
+* **enablePullUp** 允许上拉加载
+* **header** 下拉刷新头部样式
+* **footer** 上拉加载底部样式
+* **onRefresh** 下拉刷新的回调
+* **onLoading** 上拉加载的回调
+* **controller** 刷新控件的控制器,用来处理回调状态等
+
+
+### **国际化显示**
+
+ ```
+ 需要添加语言本地化SDK,不然刷新库头部与底部显示加载提示内容为英文
+
+ 添加依赖 flutter_localizations:
+ sdk: flutter
+
+ main.dart中MateriaApp里面添加以下内容
+
+ localizationsDelegates: [
+ // 这行是关键
+ RefreshLocalizations.delegate,
+ GlobalWidgetsLocalizations.delegate,
+ GlobalMaterialLocalizations.delegate
+ ],
+ supportedLocales: [
+ const Locale('en'),
+ const Locale('zh'),
+ ],
+ localeResolutionCallback:
+ (Locale locale, Iterable supportedLocales) {
+ //print("change language");
+ return locale;
+ },
+
+ ```
+
+
+### **全局配置**
+ 全局配置RefreshConfiguration,配置子树下的所有SmartRefresher表现,一般存放于MaterialApp的根部
+
+ ```
+ RefreshConfiguration(
+ headerBuilder: () => WaterDropHeader(), // 配置默认头部指示器,假如你每个页面的头部指示器都一样的话,你需要设置这个
+ footerBuilder: () => ClassicFooter(), // 配置默认底部指示器
+ headerTriggerDistance: 80.0, // 头部触发刷新的越界距离
+ springDescription:SpringDescription(stiffness: 170, damping: 16, mass: 1.9), // 自定义回弹动画,三个属性值意义请查询flutter api
+ maxOverScrollExtent :100, //头部最大可以拖动的范围,如果发生冲出视图范围区域,请设置这个属性
+ maxUnderScrollExtent:0, // 底部最大可以拖动的范围
+ enableScrollWhenRefreshCompleted: true, //这个属性不兼容PageView和TabBarView,如果你特别需要TabBarView左右滑动,你需要把它设置为true
+ enableLoadingWhenFailed : true, //在加载失败的状态下,用户仍然可以通过手势上拉来触发加载更多
+ hideFooterWhenNotFull: false, // Viewport不满一屏时,禁用上拉加载更多功能
+ enableBallisticLoad: true, // 可以通过惯性滑动触发加载更多
+ child: MaterialApp(
+ ........
+ )
+ );
+
+ ```
+
+
+### 实例展示
+
+[demo:5553db80_52ae_4241_9c8a_5c9e1f92b096]
+
+
+
\ No newline at end of file
diff --git a/lib/standard_pages/RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/.page.json b/lib/standard_pages/RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/.page.json
new file mode 100644
index 00000000..553fa67b
--- /dev/null
+++ b/lib/standard_pages/RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/.page.json
@@ -0,0 +1,10 @@
+{
+ "name": "RangeSlider",
+ "screenShot": "",
+ "author":"hanxu",
+ "title":"RangeSlider",
+ "email": "hanxu317@qq.com",
+ "desc": "RangeSlider widget",
+ "id": "cbffbf7c_52ae_4241_9c8a_5c9e1f92b096"
+}
+
\ No newline at end of file
diff --git a/lib/standard_pages/RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/standard_pages/RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..63850c68
--- /dev/null
+++ b/lib/standard_pages/RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,36 @@
+String getMd() {
+ return """
+ # RangeSlider
+
+> 用来选择范围性的数据
+
+slider 用来选择连续性的或者非连续性的数据. 默认是在一段最大值最小值间做任意值的选择. 如果你想选择间隔性的值, 例如0.0到50.0间,选择10, 15,...50.0这样的值, 给divisions设定一个非空的整数5,, 去分割区间范围.
+
+
+### **基本用法**
+
+关于slider有以下的术语:
+
+* **thumb** 滑块 用户可以水平拖拽移动的区域
+
+* **track** 滑轨 thumb 可以滑动的线条区域
+
+* **value indicator** 值指示器 当用户拖拽thumb的时候. 显示用户当前所选的属性值
+
+* **active** 选中区
+
+* **inactive** 非选中区
+
+如果**onChanged**属性为空或者**min** .. **max**给出的范围 为空(例如如果min等于max),则将禁用滑块。
+
+滑块小部件本身不保持任何状态State。相反,当滑块状态发生变化时,窗口小部件会调用 **onChanged** 回调。大多数使用滑块的小部件将侦听 **onChanged** 回调并使用新值重建滑块以更新滑块的视觉外观。要知道值何时开始更改,或何时更改,请设置可选回调**onChangeStart**或**onChangeEnd**。
+
+默认情况下,滑块将尽可能宽,垂直居中。当给定无限制约束时,它将尝试使轨道宽144像素(每边有边距)并垂直收缩。
+
+### 实例展示
+
+[demo:e5f958bc_52ae_4241_9c8a_5c9e1f92b096]""";
+
+
+}
+
\ No newline at end of file
diff --git a/lib/standard_pages/RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/index.md b/lib/standard_pages/RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/index.md
new file mode 100644
index 00000000..d6049358
--- /dev/null
+++ b/lib/standard_pages/RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/index.md
@@ -0,0 +1,30 @@
+# RangeSlider
+
+> 用来选择范围性的数据
+
+slider 用来选择连续性的或者非连续性的数据. 默认是在一段最大值最小值间做任意值的选择. 如果你想选择间隔性的值, 例如0.0到50.0间,选择10, 15,...50.0这样的值, 给divisions设定一个非空的整数5,, 去分割区间范围.
+
+
+### **基本用法**
+
+关于slider有以下的术语:
+
+* **thumb** 滑块 用户可以水平拖拽移动的区域
+
+* **track** 滑轨 thumb 可以滑动的线条区域
+
+* **value indicator** 值指示器 当用户拖拽thumb的时候. 显示用户当前所选的属性值
+
+* **active** 选中区
+
+* **inactive** 非选中区
+
+如果**onChanged**属性为空或者**min** .. **max**给出的范围 为空(例如如果min等于max),则将禁用滑块。
+
+滑块小部件本身不保持任何状态State。相反,当滑块状态发生变化时,窗口小部件会调用 **onChanged** 回调。大多数使用滑块的小部件将侦听 **onChanged** 回调并使用新值重建滑块以更新滑块的视觉外观。要知道值何时开始更改,或何时更改,请设置可选回调**onChangeStart**或**onChangeEnd**。
+
+默认情况下,滑块将尽可能宽,垂直居中。当给定无限制约束时,它将尝试使轨道宽144像素(每边有边距)并垂直收缩。
+
+### 实例展示
+
+[demo:e5f958bc_52ae_4241_9c8a_5c9e1f92b096]
\ No newline at end of file
diff --git a/lib/standard_pages/index.dart b/lib/standard_pages/index.dart
new file mode 100644
index 00000000..199d81f0
--- /dev/null
+++ b/lib/standard_pages/index.dart
@@ -0,0 +1,45 @@
+
+import 'PullToRefresh_chenfeihu_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_PullToRefresh_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096;
+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;
+import 'RangeSlider_hanxu_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_RangeSlider_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096;
+class StandardPages {
+ Map standardPages;
+ Map getPages() {
+ return {
+ "0": "0" ,
+ "cd9b8b80_52ae_4241_9c8a_5c9e1f92b096" : StandardPage_PullToRefresh_cd9b8b80_52ae_4241_9c8a_5c9e1f92b096.getMd()
+,
+ "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()
+,
+ "cbffbf7c_52ae_4241_9c8a_5c9e1f92b096" : StandardPage_RangeSlider_cbffbf7c_52ae_4241_9c8a_5c9e1f92b096.getMd()
+ };
+ }
+ List> getLocalList() {
+ return [
+ {},
+ { "id": "cd9b8b80_52ae_4241_9c8a_5c9e1f92b096", "name": "PullToRefresh", "email": "763551832@qq.com", "author": "chenfeihu"}
+,
+ { "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"}
+,
+ { "id": "cbffbf7c_52ae_4241_9c8a_5c9e1f92b096", "name": "RangeSlider", "email": "hanxu317@qq.com", "author": "hanxu"}
+ ];
+ }
+
+}
+
+
\ No newline at end of file
diff --git a/lib/standard_pages/local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/.page.json b/lib/standard_pages/local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/.page.json
new file mode 100644
index 00000000..d6a9e3d0
--- /dev/null
+++ b/lib/standard_pages/local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/.page.json
@@ -0,0 +1,10 @@
+{
+ "name": "local",
+ "screenShot": "",
+ "author":"hnaxu",
+ "title":"本地",
+ "email": "hanxu@qq.com",
+ "desc": "desc",
+ "id": "5d7178d0_42ae_4241_9c8a_5c9e1f92b096"
+}
+
\ No newline at end of file
diff --git a/lib/standard_pages/local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/standard_pages/local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..6e506d10
--- /dev/null
+++ b/lib/standard_pages/local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,52 @@
+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]
+```""";
+
+}
diff --git a/lib/standard_pages/local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/index.md b/lib/standard_pages/local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/index.md
new file mode 100644
index 00000000..28d32949
--- /dev/null
+++ b/lib/standard_pages/local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/index.md
@@ -0,0 +1,47 @@
+# 标准的详情页 this is test
+您可以在这个界面中, 编写大多数的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]
+```
diff --git a/lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/.page.json b/lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/.page.json
new file mode 100644
index 00000000..fa8a3a6a
--- /dev/null
+++ b/lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/.page.json
@@ -0,0 +1,10 @@
+{
+ "name": "standard_for_slider",
+ "screenShot": "",
+ "author":"sanfan",
+ "title":"slider组件",
+ "email": "hanxu@qq.com",
+ "desc": "slider, new Slider",
+ "id": "8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096"
+}
+
\ No newline at end of file
diff --git a/lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..bd222ee8
--- /dev/null
+++ b/lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,61 @@
+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]""";
+
+
+}
+
\ No newline at end of file
diff --git a/lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.md b/lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.md
new file mode 100644
index 00000000..0cf3597e
--- /dev/null
+++ b/lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.md
@@ -0,0 +1,55 @@
+# 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]
\ No newline at end of file
diff --git a/lib/standard_pages/standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/.page.json b/lib/standard_pages/standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/.page.json
new file mode 100644
index 00000000..1e6d54b7
--- /dev/null
+++ b/lib/standard_pages/standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/.page.json
@@ -0,0 +1,10 @@
+{
+ "name": "standard",
+ "screenShot": "",
+ "author":"sanfan",
+ "title":"介绍页",
+ "email": "hanxu317@qq.com",
+ "desc": "desc",
+ "id": "ee4feb8e_32ae_4241_9c8a_5c9e1f92b096"
+}
+
\ No newline at end of file
diff --git a/lib/standard_pages/standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/standard_pages/standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..be0e2607
--- /dev/null
+++ b/lib/standard_pages/standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,56 @@
+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]
+```""";
+
+
+}
+
\ No newline at end of file
diff --git a/lib/standard_pages/standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/index.md b/lib/standard_pages/standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/index.md
new file mode 100644
index 00000000..bf94471b
--- /dev/null
+++ b/lib/standard_pages/standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/index.md
@@ -0,0 +1,50 @@
+# 标准的详情页 this is title
+
+您可以在这个界面中, 编写大多数的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]
+```
diff --git a/lib/standard_pages/test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/.page.json b/lib/standard_pages/test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/.page.json
new file mode 100644
index 00000000..297b026e
--- /dev/null
+++ b/lib/standard_pages/test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/.page.json
@@ -0,0 +1,10 @@
+{
+ "name": "test",
+ "screenShot": "",
+ "author":"abc",
+ "title":"ya",
+ "email": "adsf.com",
+ "desc": "desc",
+ "id": "84f38e00_42ae_4241_9c8a_5c9e1f92b096"
+}
+
\ No newline at end of file
diff --git a/lib/standard_pages/test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/index.dart b/lib/standard_pages/test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/index.dart
new file mode 100644
index 00000000..6e506d10
--- /dev/null
+++ b/lib/standard_pages/test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/index.dart
@@ -0,0 +1,52 @@
+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]
+```""";
+
+}
diff --git a/lib/standard_pages/test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/index.md b/lib/standard_pages/test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/index.md
new file mode 100644
index 00000000..61a5f516
--- /dev/null
+++ b/lib/standard_pages/test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/index.md
@@ -0,0 +1,48 @@
+# 标准的详情页
+
+您可以在这个界面中, 编写大多数的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]
+```
\ No newline at end of file
diff --git a/lib/utils/data_utils.dart b/lib/utils/data_utils.dart
index 149c6e22..921f95ff 100644
--- a/lib/utils/data_utils.dart
+++ b/lib/utils/data_utils.dart
@@ -1,26 +1,83 @@
import 'dart:async' show Future;
+import 'package:fluro/fluro.dart';
+import 'package:flutter_go/model/collection.dart';
import 'package:flutter_go/model/version.dart';
+import 'package:flutter_go/model/widget.dart';
import 'package:package_info/package_info.dart';
-import 'package:url_launcher/url_launcher.dart';
+/// import 'package:flutter_go/model/responseData.dart';
import './net_utils.dart';
import '../model/user_info.dart';
import 'package:flutter_go/api/api.dart';
+import 'package:flutter_go/routers/application.dart';
+import 'package:flutter_go/routers/routers.dart';
class DataUtils {
// 登陆获取用户信息
- static Future doLogin(Map params) async {
+ static Future doLogin(Map params) async {
var response = await NetUtils.post(Api.DO_LOGIN, params);
- UserInfo userInfo = UserInfo.fromJson(response['data']);
- return userInfo;
+ try {
+ UserInformation userInfo = UserInformation.fromJson(response['data']);
+ return userInfo;
+ } catch (err) {
+ return response['message'];
+ }
+ }
+
+ // 获取用户信息
+ static Future getUserInfo(Map params) async {
+ var response = await NetUtils.get(Api.GET_USER_INFO, params);
+ try {
+ UserInformation userInfo = UserInformation.fromJson(response['data']);
+ return userInfo;
+ } catch (err) {
+ return response['message'];
+ }
}
// 验证登陆
-
- static Future checkLogin() async {
+ static Future checkLogin() async {
var response = await NetUtils.get(Api.CHECK_LOGIN);
- print('验证登陆:$response');
+ print('response: $response');
+ try {
+ if (response['success']) {
+ print('${response['success']} ${response['data']} response[succes]');
+ UserInformation userInfo = UserInformation.fromJson(response['data']);
+ print('${response['data']} $userInfo');
+ return userInfo;
+ } else {
+ return response['success'];
+ }
+ } catch (err) {
+ return response['message'];
+ }
+ }
+
+ // 一键反馈
+ static Future feedback(Map params, context) async {
+ var response = await NetUtils.post(Api.FEEDBACK, params);
+ if (response['status'] == 401 && response['message'] == '请先登录') {
+ Application.router.navigateTo(context, '${Routes.loginPage}',
+ transition: TransitionType.nativeModal);
+ }
+ return response['success'];
+ }
+
+ //设置主题颜色
+ static Future setThemeColor(int color, context) async {
+ var response =
+ await NetUtils.post(Api.SET_THEMECOLOR, {'color': color.toString()});
+ if (response['status'] == 401 && response['message'] == '请先登录') {
+ Application.router.navigateTo(context, '${Routes.loginPage}',
+ transition: TransitionType.nativeModal);
+ }
+ return response['success'];
+ }
+
+ //获取主题颜色
+ static Future getThemeColor() async {
+ var response = await NetUtils.get(Api.GET_THEMECOLOR);
return response['success'];
}
@@ -31,9 +88,6 @@ class DataUtils {
return response['success'];
}
- /**
- * {"status":200,"data":{"version":"0.0.2","name":"FlutterGo"},"success":true}
- */
// 检查版本
static Future checkVersion(Map params) async {
var response = await NetUtils.get(Api.VERSION, params);
@@ -42,12 +96,107 @@ class DataUtils {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
var localVersion = packageInfo.version;
//相同=0、大于=1、小于=-1
-// localVersion = '0.0.2';
-// currVersion = '1.0.6';
+ // localVersion = '0.0.2';
+ // currVersion = '1.0.6';
if (currVersion.compareTo(localVersion) == 1) {
return true;
} else {
return false;
}
}
+
+ /// 获取widget列表处的树型数据
+ static Future getWidgetTreeList() async {
+ try {
+ var response = await NetUtils.get(Api.GET_WIDGET_TREE);
+ print('组件树dddd:$response');
+ if (response != null && response['success']) {
+ return response['data'];
+ } else {
+ return [];
+ }
+ } catch (error) {
+ print('获取组件树 error $error');
+ return [];
+ }
+ }
+
+ // 校验是否收藏
+ static Future checkCollected(Map params) async {
+ print('url 地址:${Api.CHECK_COLLECTED} $params');
+ try {
+ var response = await NetUtils.post(Api.CHECK_COLLECTED, params);
+ return response != null && response['hasCollected'];
+ } catch (error) {
+ print('校验收藏 error $error');
+ return false;
+ }
+ }
+
+ // 添加收藏
+ static Future addCollected(Map params, context) async {
+ var response = await NetUtils.post(Api.ADD_COLLECTION, params);
+ if (response['status'] == 401 && response['message'] == '请先登录') {
+ Application.router.navigateTo(context, '${Routes.loginPage}',
+ transition: TransitionType.nativeModal);
+ }
+ return response != null && response['success'];
+ }
+
+ // 移出收藏
+ static Future removeCollected(Map params, context) async {
+ var response = await NetUtils.post(Api.REMOVE_COLLECTION, params);
+ if (response['status'] == 401 && response['message'] == '请先登录') {
+ Application.router.navigateTo(context, '${Routes.loginPage}',
+ transition: TransitionType.nativeModal);
+ }
+ return response != null && response['success'];
+ }
+
+ // 获取全部收藏
+ static Future getAllCollections(context) async {
+ var response = await NetUtils.get(Api.GET_ALL_COLLECTION);
+ List responseList = [];
+ if (response['status'] == 401 && response['message'] == '请先登录') {
+ Application.router.navigateTo(context, '${Routes.loginPage}',
+ transition: TransitionType.nativeModal);
+ }
+ if (response != null && response['success'] == true) {
+ for (int i = 0; i < response['data'].length; i++) {
+ Map tempCo = response['data'][i];
+ responseList.add(Collection.fromJSON(
+ {"name": tempCo['name'], "router": tempCo['url']}));
+ }
+ return responseList;
+ } else {
+ return [];
+ }
+ }
+
+ // 搜索组件
+ static Future searchWidget(String name) async {
+ var response = await NetUtils.get(Api.SEARCH_WIDGET, {"name": name});
+ List list = [];
+ if (response != null && response['success'] == true) {
+ for (int i = 0; i < response['data'].length; i++) {
+ var json = response['data'][i];
+ String routerName;
+ if (json['display'] == 'old') {
+ routerName = json['path'];
+ } else {
+ routerName = json['pageId'];
+ }
+ Map tempMap = {
+ "name": json['name'],
+ "cnName": json['name'],
+ "routerName": routerName,
+ "catId": json['parentId'].runtimeType == String ? int.parse(json['parentId']) : json['parentId']
+ };
+ list.add(WidgetPoint.fromJSON(tempMap));
+ }
+ return list;
+ } else {
+ return [];
+ }
+ }
}
diff --git a/lib/utils/net_utils.dart b/lib/utils/net_utils.dart
index 2f39746c..b93c00d1 100644
--- a/lib/utils/net_utils.dart
+++ b/lib/utils/net_utils.dart
@@ -4,15 +4,14 @@ import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
-Map optHeader = {
- 'accept-language':'zh-cn',
- 'content-type':'application/json'
+Map optHeader = {
+ 'accept-language': 'zh-cn',
+ 'content-type': 'application/json'
};
-var dio = new Dio(BaseOptions(connectTimeout: 30000,headers: optHeader));
+var dio = new Dio(BaseOptions(connectTimeout: 30000, headers: optHeader));
class NetUtils {
-
static Future get(String url, [Map params]) async {
var response;
@@ -20,7 +19,7 @@ class NetUtils {
// (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
// (HttpClient client) {
// client.findProxy = (uri) {
- // return "PROXY 30.10.26.193:8888";
+ // return "PROXY 30.10.24.79:8889";
// };
// };
@@ -28,7 +27,6 @@ class NetUtils {
String documentsPath = documentsDir.path;
var dir = new Directory("$documentsPath/cookies");
await dir.create();
- // print('documentPath:${dir.path}');
dio.interceptors.add(CookieManager(PersistCookieJar(dir: dir.path)));
if (params != null) {
response = await dio.get(url, queryParameters: params);
@@ -39,6 +37,18 @@ class NetUtils {
}
static Future post(String url, Map params) async {
+ // // 设置代理 便于本地 charles 抓包
+ // (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
+ // (HttpClient client) {
+ // client.findProxy = (uri) {
+ // return "PROXY 30.10.24.79:8889";
+ // };
+ // };
+ Directory documentsDir = await getApplicationDocumentsDirectory();
+ String documentsPath = documentsDir.path;
+ var dir = new Directory("$documentsPath/cookies");
+ await dir.create();
+ dio.interceptors.add(CookieManager(PersistCookieJar(dir: dir.path)));
var response = await dio.post(url, data: params);
return response.data;
}
diff --git a/lib/utils/shared_preferences.dart b/lib/utils/shared_preferences.dart
index 81f7dc70..c7351a66 100644
--- a/lib/utils/shared_preferences.dart
+++ b/lib/utils/shared_preferences.dart
@@ -24,8 +24,9 @@ class SpUtil {
static Future getInstance() async {
if (_instance == null) {
_instance = new SpUtil._();
+ }
+ if (_spf == null) {
await _instance._init();
-
}
return _instance;
}
@@ -117,4 +118,4 @@ class SpUtil {
if (_beforeCheck()) return null;
return _spf.clear();
}
-}
\ No newline at end of file
+}
diff --git a/lib/views/collection_page/collection_full_page.dart b/lib/views/collection_page/collection_full_page.dart
new file mode 100644
index 00000000..ada616eb
--- /dev/null
+++ b/lib/views/collection_page/collection_full_page.dart
@@ -0,0 +1,161 @@
+/// @Author: 一凨
+/// @Date: 2019-06-05 14:01:03
+/// @Last Modified by: 一凨
+/// @Last Modified time: 2019-06-05 14:01:03
+import 'package:flutter/material.dart';
+import 'package:event_bus/event_bus.dart';
+import 'package:fluro/fluro.dart';
+
+import 'package:flutter_go/model/collection.dart';
+import 'package:flutter_go/routers/application.dart';
+import 'package:flutter_go/event/event_bus.dart';
+import 'package:flutter_go/event/event_model.dart';
+import 'package:flutter_go/utils/data_utils.dart';
+
+class CollectionFullPage extends StatefulWidget {
+ final bool hasLogined;
+ CollectionFullPage({Key key, this.hasLogined}) : super(key: key);
+
+ @override
+ _CollectionFullPageState createState() => _CollectionFullPageState();
+}
+
+class _CollectionFullPageState extends State {
+ _CollectionFullPageState() {
+ final eventBus = new EventBus();
+ ApplicationEvent.event = eventBus;
+ }
+
+ /// CollectionControlModel _collectionControl = new CollectionControlModel();
+ List _collectionList = [];
+ ScrollController _scrollController = new ScrollController();
+ var _icons;
+
+ @override
+ void initState() {
+ super.initState();
+ _getList();
+ ApplicationEvent.event.on().listen((event) {
+ _getList();
+ });
+ }
+
+ void _getList() {
+ _collectionList.clear();
+ DataUtils.getAllCollections(context).then((collectionList) {
+ if (this.mounted) {
+ setState(() {
+ _collectionList = collectionList;
+ });
+ }
+ });
+ }
+
+ @override
+ void dispose() {
+ _scrollController.dispose();
+ super.dispose();
+ }
+
+ Widget _renderList(context, index) {
+
+ if (index == 0) {
+ return Container(
+ height: 40.0,
+ padding: const EdgeInsets.only(left: 10.0),
+ child: Row(
+ children: [
+ Icon(
+ Icons.warning,
+ size: 22.0,
+ ),
+ SizedBox(
+ width: 5.0,
+ ),
+ Text('常用的组件都可以收藏在这里哦'),
+ ],
+ ),
+ );
+ }
+ if (_collectionList[index - 1].router.contains('http')) {
+ if (_collectionList[index - 1].name.endsWith('Doc')) {
+ _icons = Icons.library_books;
+ } else {
+ _icons = Icons.language;
+ }
+ } else {
+ _icons = Icons.extension;
+ }
+ String targetRouter = _collectionList[index - 1].router;
+ return Container(
+ padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
+ margin: const EdgeInsets.only(bottom: 7.0),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ boxShadow: [
+ new BoxShadow(
+ color: const Color(0xFFd0d0d0),
+ blurRadius: 1.0,
+ spreadRadius: 2.0,
+ offset: Offset(3.0, 2.0),
+ ),
+ ],
+ ),
+ child: ListTile(
+ leading: Icon(
+ _icons,
+ size: 30.0,
+ color: Theme.of(context).primaryColor,
+ ),
+ title: Text(
+ _collectionList[index - 1].name,
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(fontSize: 17.0),
+ ),
+ trailing:
+ Icon(Icons.keyboard_arrow_right, color: Colors.grey, size: 30.0),
+ onTap: () {
+ Application.router.navigateTo(
+ context, targetRouter.toLowerCase(),
+ transition: TransitionType.inFromRight);
+ },
+ ),
+ );
+ }
+
+ ListView buildContent() {
+ if (_collectionList.length == 0) {
+ return ListView(
+ children: [
+ Column(
+ children: [
+ Image.asset(
+ 'assets/images/nothing.png',
+ fit: BoxFit.contain,
+ width: MediaQuery.of(context).size.width / 2,
+ ),
+ Text('暂无收藏,赶紧去收藏一个吧!'),
+ ],
+ ),
+ ],
+ );
+ }
+ return ListView.builder(
+ itemBuilder: _renderList,
+ itemCount: _collectionList.length + 1,
+ controller: _scrollController,
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('我的收藏'),
+ ),
+ body: Container(
+ child: buildContent(),
+ ),
+ );
+ }
+}
diff --git a/lib/views/collection_page/collection_page.dart b/lib/views/collection_page/collection_page.dart
index 6b4c609b..75d6e309 100644
--- a/lib/views/collection_page/collection_page.dart
+++ b/lib/views/collection_page/collection_page.dart
@@ -1,5 +1,5 @@
-/// @Author: 一凨
-/// @Date: 2019-01-08 17:12:58
+/// @Author: 一凨
+/// @Date: 2019-01-08 17:12:58
/// @Last Modified by: 一凨
/// @Last Modified time: 2019-01-14 20:13:28
@@ -11,9 +11,13 @@ import 'package:flutter_go/routers/application.dart';
import 'package:flutter_go/routers/routers.dart';
import 'package:flutter_go/event/event_bus.dart';
import 'package:flutter_go/event/event_model.dart';
-
+/// import 'package:flutter_go/utils/data_utils.dart';
class CollectionPage extends StatefulWidget {
+ final bool hasLogined;
+
+ CollectionPage({Key key, this.hasLogined}) : super(key: key);
+
_CollectionPageState createState() => _CollectionPageState();
}
@@ -22,7 +26,7 @@ class _CollectionPageState extends State {
final eventBus = new EventBus();
ApplicationEvent.event = eventBus;
}
- CollectionControlModel _collectionControl = new CollectionControlModel();
+ /// CollectionControlModel _collectionControl = new CollectionControlModel();
List _collectionList = [];
ScrollController _scrollController = new ScrollController();
var _icons;
@@ -44,16 +48,13 @@ class _CollectionPageState extends State {
void _getList() {
_collectionList.clear();
- _collectionControl.getAllCollection().then((resultList) {
- resultList.forEach((item) {
- _collectionList.add(item);
- });
- if (this.mounted) {
- setState(() {
- _collectionList = _collectionList;
- });
- }
- });
+ // DataUtils.getAllCollections(context).then((collectionList) {
+ // if (this.mounted) {
+ // setState(() {
+ // _collectionList = collectionList;
+ // });
+ // }
+ // });
}
Widget _renderList(context, index) {
@@ -105,7 +106,8 @@ class _CollectionPageState extends State {
color: Theme.of(context).primaryColor,
),
title: Text(
- Uri.decodeComponent(_collectionList[index - 1].name),
+ _collectionList[index - 1].name,
+// Uri.decodeComponent(_collectionList[index - 1].name),
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 17.0),
),
diff --git a/lib/views/first_page/drawer_page.dart b/lib/views/first_page/drawer_page.dart
new file mode 100644
index 00000000..f0fc1be0
--- /dev/null
+++ b/lib/views/first_page/drawer_page.dart
@@ -0,0 +1,247 @@
+import 'dart:async';
+
+import 'package:fluro/fluro.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter_go/components/single_theme_color.dart';
+import 'package:flutter_go/model/user_info.dart';
+import 'package:share/share.dart';
+import 'package:flutter_go/utils/data_utils.dart';
+import 'package:flutter_go/routers/application.dart';
+import 'package:flutter_go/routers/routers.dart';
+import './search_page.dart';
+import 'package:flutter_go/event/event_bus.dart';
+import 'package:flutter_go/event/event_model.dart';
+import 'package:event_bus/event_bus.dart';
+
+const List> defalutThemeColor = [
+ {'cnName': 'Flutter篮', 'value': 0xFF3391EA},
+ {'cnName': '拍卖红', 'value': 0xFFC91B3A},
+ {'cnName': '阿里橙', 'value': 0xFFF7852A},
+];
+
+class DrawerPage extends StatefulWidget {
+ final UserInformation userInfo;
+ DrawerPage({Key key, this.userInfo}) : super(key: key);
+
+ @override
+ _DrawerPageState createState() => _DrawerPageState();
+}
+
+class _DrawerPageState extends State {
+ final TextStyle textStyle =
+ TextStyle(fontSize: 16, fontWeight: FontWeight.w300);
+ bool hasLogin;
+
+ _DrawerPageState() {
+ final eventBus = new EventBus();
+ ApplicationEvent.event = eventBus;
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ ApplicationEvent.event.on().listen((event) {
+ print('接收到的 event ${event.settingThemeColor}');
+ });
+ hasLogin = this.widget.userInfo.id != 0;
+ }
+
+ Future logoutDialog(BuildContext context) {
+ return showDialog(
+ context: context,
+ builder: (BuildContext context) {
+ return AlertDialog(
+ title: Text('确认退出登陆?'),
+ // content: Text('退出登陆后将没法进行'),
+ actions: [
+ FlatButton(
+ onPressed: () {
+ // 退出登陆
+ DataUtils.logout().then((result) {
+ if (result) {
+ Application.router.navigateTo(
+ context, '${Routes.loginPage}',
+ transition: TransitionType.native, clearStack: true);
+ }
+ });
+ },
+ child: Text(
+ '确认',
+ style: TextStyle(color: Colors.red),
+ ),
+ ),
+ FlatButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('取消'),
+ )
+ ],
+ );
+ });
+ }
+
+ void showLogoutDialog(BuildContext context) {
+ if (hasLogin) {
+ logoutDialog(context);
+ } else {
+ Application.router.navigateTo(context, '${Routes.loginPage}',
+ transition: TransitionType.native, clearStack: true);
+ }
+ }
+
+ void pushPage(BuildContext context, Widget page, {String pageName}) {
+ if (context == null || page == null) return;
+ Navigator.push(context, CupertinoPageRoute(builder: (ctx) => page));
+ }
+
+ Future buildSimpleDialog(BuildContext context) {
+ return showDialog(
+ context: context,
+ builder: (BuildContext context) {
+ return Dialog(
+ child: Container(
+ padding: const EdgeInsets.symmetric(vertical: 20.0),
+ height: 300.0,
+ color: Colors.white,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ mainAxisSize: MainAxisSize.max,
+ children: buildThemeColorChildren(),
+ )),
+ );
+ });
+ }
+
+ List buildThemeColorChildren() {
+ List tempWidget = [];
+ for (var i = 0; i < defalutThemeColor.length; i++) {
+ tempWidget.add(SingleThemeColor(
+ themeColor: defalutThemeColor[i]['value'],
+ coloeName: defalutThemeColor[i]['cnName'],
+ ));
+ }
+ return tempWidget;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return ListView(
+ padding: EdgeInsets.zero,
+ children: [
+ UserAccountsDrawerHeader(
+ accountName: Text(''),
+ accountEmail: Container(
+ padding: const EdgeInsets.only(bottom: 20.0),
+ child: Text(
+ hasLogin ? widget.userInfo.username : ' ',
+ style: TextStyle(fontSize: 28),
+ ),
+ ),
+ decoration: BoxDecoration(
+ image: new DecorationImage(
+ fit: BoxFit.cover,
+ image: new NetworkImage(hasLogin
+ ? widget.userInfo.avatarPic
+ : 'https://hbimg.huabanimg.com/9bfa0fad3b1284d652d370fa0a8155e1222c62c0bf9d-YjG0Vt_fw658'),
+ ),
+ ),
+ ),
+ // new Divider(),
+ ListTile(
+ leading: Icon(
+ Icons.search,
+ size: 27.0,
+ ),
+ title: Text(
+ '全网搜',
+ style: textStyle,
+ ),
+ onTap: () {
+ pushPage(context, SearchPage(), pageName: "SearchPage");
+ },
+ ),
+ ListTile(
+ leading: Icon(
+ Icons.favorite,
+ size: 27.0,
+ ),
+ title: Text(
+ '我的收藏',
+ style: textStyle,
+ ),
+ onTap: () {
+ Application.router.navigateTo(context,
+ '${Routes.collectionFullPage}?hasLogin=${hasLogin.toString()}',
+ transition: TransitionType.fadeIn);
+ },
+ ),
+ // new Divider(),
+ // ListTile(
+ // leading: Icon(
+ // Icons.settings,
+ // size: 27.0,
+ // ),
+ // title: Text(
+ // '主题色',
+ // style: textStyle,
+ // ),
+ // onTap: () {
+ // buildSimpleDialog(context);
+ // },
+ // ),
+ new Divider(),
+
+ ListTile(
+ leading: Icon(
+ Icons.email,
+ size: 27.0,
+ ),
+ title: Text(
+ '反馈/建议',
+ style: textStyle,
+ ),
+ onTap: () {
+ if (hasLogin) {
+ //issue 未登陆状态 返回登陆页面
+ Application.router.navigateTo(context, '${Routes.issuesMessage}');
+ } else {
+ //No description provided.
+ Application.router.navigateTo(context, '${Routes.loginPage}');
+
+ }
+ },
+ ),
+ ListTile(
+ leading: Icon(
+ Icons.share,
+ size: 27.0,
+ ),
+ title: Text(
+ '分享 App',
+ style: textStyle,
+ ),
+ onTap: () {
+ Share.share('https://flutter-go.pub/website/');
+ },
+ ),
+ new Divider(),
+ ListTile(
+ leading: Icon(
+ hasLogin ? Icons.exit_to_app : Icons.supervised_user_circle,
+ size: 27.0,
+ ),
+ title: Text(
+ hasLogin ? '退出登陆' : '点击登录',
+ style: textStyle,
+ ),
+ onTap: () {
+ showLogoutDialog(context);
+ // logoutDialog(context);
+ },
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/views/first_page/first_page.dart b/lib/views/first_page/first_page.dart
index bc052da6..13e87884 100644
--- a/lib/views/first_page/first_page.dart
+++ b/lib/views/first_page/first_page.dart
@@ -51,7 +51,9 @@ class FirstPageState extends State
}
Future getIndexListData([Map