Revert "add widget SliderNew"

This commit is contained in:
hanxu317317
2019-08-13 15:16:21 +08:00
committed by GitHub
parent adf5dba183
commit 3e7daebe79
160 changed files with 832 additions and 10771 deletions

View File

@ -1,26 +0,0 @@
---
name: "\U0001F41B Bug Report"
about: Something isn't working as expected
---
## Bug Report
**仅限中文与英文**, 其他语言的提交将直接被关闭
请先确认查找了已有的 issue [GitHub issues](https://github.com/apache/incubator-shardingsphere-example/issues).
为了更好的收录您反馈或者提交的相关pr. 请您关注您提交的问题, 我们可能需要更多的详细信息, 我们会在issue下先您收集相关信息,
如果长时间未得到您的回复, 如果我们无法在某些环境上重现该问题, 并且您**超过7天未回复**, 我们可能会关 **闭掉issue**, 谢谢
### 您当前的flutter doctor信息
### 预期的表现
### 实际的表现
### 预期的分析 (给出您能想到, 任何您能想到的)
### 重现的方式, 例如从 A界面 点击 b, 跳转到B页面, 界面出现溢出乱码等.
### 用于重现此问题或者可能解决以上问题的示例代码例如github 链接代码)

View File

@ -1,18 +0,0 @@
---
name: "\U0001F680 Feature Request"
about: I have a suggestion
---
## Feature Request
**仅限中文与英文**, 其他语言的提交将直接被关闭
请先确认查找了已有的 issue [GitHub issues](https://github.com/apache/incubator-shardingsphere-example/issues).
为了更好的收录您反馈或者提交的相关pr. 请您关注您提交的问题, 我们可能需要更多的详细信息, 我们会在issue下先您收集相关信息,
如果长时间未得到您的回复, 如果我们无法在某些环境上重现该问题, 并且您**超过7天未回复**, 我们可能会关 **闭掉issue**, 谢谢
### 您的功能需求是否与哪些问题有关?
### 描述您想要的功能.

View File

@ -1,62 +0,0 @@
---
name: "📄 Page About"
about: something about page
---
## Page About
**仅限中文与英文**, 其他语言的提交将直接被关闭
请先确认查找了已有的 issue [GitHub issues](https://github.com/apache/incubator-shardingsphere-example/issues).
为了更好的收录您反馈或者提交的相关pr. 请您关注您提交的问题, 我们可能需要更多的详细信息, 我们会在issue下先您收集相关信息,
如果长时间未得到您的回复, 如果我们无法在某些环境上重现该问题, 并且您**超过7天未回复**, 我们可能会关 **闭掉issue**, 谢谢
## 界面增加或者更新的内容概括
## 界面数据
例如:
```
{
"name": "standard_for_slider",
"screenShot": "",
"author":"sanfan",
"title":"slider组件",
"email": "hanxu@qq.com",
"desc": "slider, new Slider",
"id": "8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096"
}
```
## Page 关联的 DEMO 信息
例如:
```
{
"name": "intor page",
"screenShot": "",
"author":"sanfan",
"title":"介绍页",
"email": "hanxu317@qq.com",
"desc": "desc",
"id": "ee4feb8e_32ae_4241_9c8a_5c9e1f92b096"
},
{
"name": "intor pag2e",
"screenShot": "",
"author":"sanfan",
"title":"介绍页",
"email": "hanxu317@qq.com",
"desc": "desc",
"id": "ee4feb8e_32ae_4241_9c8a_5c9e1f92b097"
}
```
## 引入第三方包的文件与版本号(如果有引入, 请标明)

View File

@ -1,14 +0,0 @@
---
name: "\U0001F914 Question"
about: Usage question that isn't answered in docs or discussion
---
## Question
**仅限中文与英文**, 其他语言的提交将直接被关闭
请先确认查找了已有的 issue [GitHub issues](https://github.com/apache/incubator-shardingsphere-example/issues).
为了更好的收录您反馈或者提交的相关pr. 请您关注您提交的问题, 我们可能需要更多的详细信息, 我们会在issue下先您收集相关信息,
如果长时间未得到您的回复, 如果我们无法在某些环境上重现该问题, 并且您**超过7天未回复**, 我们可能会关 **闭掉issue**, 谢谢

0
.github/issue_template.md vendored Normal file
View File

1
.gitignore vendored
View File

@ -18,7 +18,6 @@
.metadata
# IntelliJ related
*.iml
*.ipr

View File

@ -85,4 +85,4 @@ The advantages of Flutter mainly include:
</tbody>
</table>
Powered by Alibaba Auction Front-end Team<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width= 20 height=20>
Powered by [Alibaba Auction Front-end Team](https://github.com/alibaba-paimai-frontend)<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width= 20 height=20>

View File

@ -1,8 +1,6 @@
Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.md) | [中文简体](https://github.com/alibaba/flutter-go/blob/master/README.md)
## Flutter Go
# test
![https://img.alicdn.com/tfs/TB1OJkeHNYaK1RjSZFnXXa80pXa-229-229.png](https://img.alicdn.com/tfs/TB1OJkeHNYaK1RjSZFnXXa80pXa-229-229.png)
> 帮助开发者快速上手 Flutter **Flutter Go 1.0 Android版已正式发布**
@ -22,37 +20,17 @@ Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.
<img src="https://img.alicdn.com/tfs/TB19UahQQzoK1RjSZFlXXai4VXa-1500-1106.png" width="600px">
## 运行方式
- 查看一下版本号是否正确
```dart
flutter --version
```
- 运行以下命令查看是否需要安装其它依赖项来完成安装
```dart
flutter doctor
```
- 运行启动您的应用
```dart
flutter packages get
flutter run
```
- 如果有其他问题,请参考
- https://flutterchina.club/setup-macos/
- https://flutter.dev/docs/get-started/install/macos
## Release安装包下载地址
### android正式版,下载地址:
android下载地址:
- 华为市场已上线,华为应用市场搜索 "Fluttergo"或者直接[点击下载](https://appstore.huawei.com/search/fluttergo)
<img src="https://img.alicdn.com/tfs/TB1LbEYarys3KVjSZFnXXXFzpXa-378-380.jpg" width=200>
<img src="https://img.alicdn.com/tfs/TB1ylxGTMHqK1RjSZFgXXa7JXXa-436-432.png" width="200px">
### iphone正式版,下载地址:
iphone下载地址: AppStore上面进行搜索fluttego
- AppStore 搜索 "Fluttergo" 或者直接[点击下载](https://itunes.apple.com/cn/app/flutter-go/id1462026296?mt=8)
<img src="https://img.alicdn.com/tfs/TB1PygPaBWD3KVjSZFsXXcqkpXa-380-376.jpg" width=200>
<img src="https://img.alicdn.com/tfs/TB1trMgV7PoK1RjSZKbXXX1IXXa-620-1343.png" width=200> <img src="https://img.alicdn.com/tfs/TB1w_MbV7voK1RjSZFDXXXY3pXa-620-1343.png" width=200>
## 基础环境
@ -145,5 +123,6 @@ flutter优点主要包括
- 大家的互相信任,尊重与支持,才是开源社区前进的动力和来源.
Powered by 阿里拍卖前端团队<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width=20 height=20>
Powered by [阿里拍卖前端团队](https://github.com/alibaba-paimai-frontend)<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width=20 height=20>
+++++++

View File

@ -51,23 +51,8 @@ android {
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [
JPUSH_PKGNAME : "com.alibaba.fluttergo",
JPUSH_APPKEY : "62eb07d227d1f11dd7fa6239", //JPush上注册的包名对应的appkey.
JPUSH_CHANNEL : "developer-default",
]
// ndk {
// //选择要添加的对应cpu类型的.so库。
// abiFilters 'armeabi', 'armeabi-v7a','x86', 'x86_64', 'mips'//, 'arm64-v8a'
// // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
// }
}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
@ -101,8 +86,6 @@ dependencies {
///implementation 'com.google.firebase:firebase-perf:16.2.3'
// 登陆
////implementation 'com.google.firebase:firebase-auth:16.0.3'
}
//firebase
apply plugin: 'com.google.gms.google-services'

Binary file not shown.

View File

@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0.6","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"0.0.5","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

View File

@ -7,22 +7,20 @@
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODE_WORLD_READABLE" />
<uses-permission android:name="android.permission.MODE_WORLD_WRITEABLE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODE_WORLD_READABLE"/>
<uses-permission android:name="android.permission.MODE_WORLD_WRITEABLE"/>
<application
android:name="io.flutter.app.FlutterApplication"
android:label="FlutterGo"
android:icon="@mipmap/ic_launcher_logo"
android:usesCleartextTraffic="true">
android:label="fluttergo"
android:icon="@mipmap/ic_launcher_logo">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
@ -32,36 +30,9 @@
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<provider
android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
android:authorities="${applicationId}.flutter_downloader.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:enabled="false"
android:exported="false" />
<provider
android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer"
android:authorities="${applicationId}.flutter-downloader-init"
android:exported="false">
<meta-data
android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS"
android:value="5" />
</provider>
</application>
</manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

@ -1,38 +0,0 @@
# Flutter Go 共建
# 共建说明
由于 **Flutter 版本迭代速度较快**,产生的内容较多, 而我们**人力有限**无法更加全面快速的支持Flutter Go的日常维护迭代, 如果您对flutter go的共建感兴趣, 欢迎您来参与本项目的共建.
**凡是参与共建的成员. 我们会将您的头像与github个人地址收纳进我们的官方网站中.**
# 共建方式
1. 共建组件
- 本次更新, 开放了 **Widget 内容收录** 的功能, 您需要通过 [goCli](https://github.com/alibaba/flutter-go/blob/master/docs/go-cli.md) 工具编写markdown代码。
- 然后通过 **Pull Request** 的形式将您的文章内容, api描述, 组件使用方法等加入进我们的Widget界面。
- 为了更好记录您的改动目的, 内容信息, 交流过程, 每一条PR都需要对应一条 **Issue**, 即提交你发现的BUG或者想加入的功能, 或者想要加入的WidgetPage(共建组件), 选择你issue在类型。
![](https://img.alicdn.com/tfs/TB1r3LEbKL2gK0jSZFmXXc7iXXa-858-317.png)
2. 提交文章和修改bug
- 您也可以将例如**日常bug.** **未来feature**等的功能性PR, 申请提交到我们的的主仓库。
# 参与共建
我们采用 **Pull Request(简称PR)** 的方式, 进行三方共建.
关于如何提PR请先阅读以下文档
- [如何向仓库提交 Pull Request](https://github.com/alibaba/flutter-go/blob/master/docs/push-pr.md)
- [dart 代码规范](https://github.com/alibaba/flutter-go/blob/master/Flutter_Go%20%E4%BB%A3%E7%A0%81%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md)
- [如何使用go-cli 创建 Widget Page](https://github.com/alibaba/flutter-go/blob/master/docs/go-cli.md)
# 贡献指南
此项目遵循[贡献者行为准则](https://github.com/spring-projects/spring-framework/blob/master/CODE_OF_CONDUCT.adoc)。参与此项目即表示您同意遵守其条款.

View File

@ -1,84 +0,0 @@
# GoCli 说明
## 安装
获取最新flutterGo代码分之后. 在项目下会有 **go-cli** 的文件夹.
首先进入该文件夹并安装go-cli所需要的依赖
```
cd go-cli
pub get
```
然后使用pub global命令将文件包注册到全局
```
pub global activate --source path /{your project absolute path}/flutter-go/go-cli
```
使用pub global list命令查看全局包列表 如果看到有 **goCli 1.0.0**则证明安装成功
```
goCli 1.0.0 at path "/{youpath}/flutter-go/go-cli"
```
## 固定命令
### goCli createPage
初始化并创建一个Widget详情页, 通常来说. 当我们需要在Widget Tab下. 新加入一个界面内容, 执行该条命令, 会根据您的输入, 自动在本项目中创建对应的文件夹, 并记录相关配置信息, 在创建的目录中, 您可以通过编写markdown代码, 进行文章内容的编写.
### goCli createDemo
初始化并创建一个可实例化的Widget Demo(实例块), 按照在命令行中的提示, 输入我们的相关信息, 我们会创建一个 关于demo 的文件夹. 并会得到一个唯一的 **ID**. 我们可以通过这条ID,在我们的markdown代码中, 进行直接调用.
例如:
```
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```
### goCli build
将本地的界面与实例资源进行打包开成统一的独立的入口. 在拉取flutter-go的项目代码后. 需要执行当前命令. 否则会报错.
### goCli watch
动态便宜Widget Page, 动态进行markdown => dart 代码的转换. 通常在我们编辑Widget page的index.md的时候进行文件监听. 动态生成, 进行本地热更新.
## 注意
- 在修改**page\_demo\_package**或者standard\_pages目录下的文件操作时. 请先执行 **goCLi watch**
- **name**, **author** 字段必须使用英文开头, 不允许使用特殊符号. 正常的示范 name ='name_test' author = 'abcdefg';
- 以下文件目录, 显示**不可人为修改的文件**, 凡是被**合进master主分支的代码**不允许进行任何修改.
```
// demo 文件结构
demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/
├── .demo.json (不可人为修改)
├── index.dart (不可人为修改)
└── src
└── index.dart (可修改)
// widget page 文件结构
standard_pages/
├── index.dart (不可人为修改)
└── standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096
├── .page.json (不可人为修改)
├── index.dart (不可人为修改)
└── index.md (可修改)
```

BIN
docs/jiegou.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

@ -1,35 +0,0 @@
# 如何为一个项目提PR
## PR 的含义
PR的全称是 **pull request**, 可以理解成. 让开源项目拉取合并他方的请求.
## pull request
1. 将 开源flutter go项目 fork到我们自己的仓库.
![如何fock项目](https://img.alicdn.com/tfs/TB1XbnDbQH0gK0jSZPiXXavapXa-1425-672.gif)
2. 将Fork的仓库 clone 到本地,进行本地修改.
3. 将改动push到自己的仓库中
```
git add {some change file}
git commit ...
git push origin {your branch}
```
4. 登陆github, 从**自己的仓库**向**开源项目仓库** 发起 **pull request** (合并申请);
过程参考:
![如何提pr](https://img.alicdn.com/tfs/TB1zV_BbKL2gK0jSZPhXXahvXXa-1425-672.gif)
5. 开源项目维护者会review您的 **pull request**,展开讨论或者修改, 一旦通过审核,开源项目维护者合并该分支到正式仓库然后并关闭合并申请。

View File

@ -1,62 +0,0 @@
# 如何在Widget新增界面
阅读文档前, 请先阅读 go-cli 文档
在Widget列表页, 我们设有一个组, 名叫 **Developer**, 这个分组的作用是用来展示第三方作者提交的内容. 正常情况下会显示以下内容
<img src="https://img.alicdn.com/tfs/TB1RCfZc1H2gK0jSZJnXXaT1FXa-798-1582.png" width='300px' />
## 新建 Page
在项目的根目录下使用 **goCLi createPage** 固定命令, 按照命令行提示信息. 输入新建界面的相关信息
```
goCli createPage
```
参考:
![](https://img.alicdn.com/tfs/TB1ms2Wc1H2gK0jSZFEXXcqMpXa-1393-228.gif)
按照以上操作会得到以下信息输出:
```
{
界面位于 : lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096
Id : 8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096
文件夹名称 : standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096
}
```
### 字段注意事项
**name** 必须**英文开头**, 统一用小写的英文字母,数字和下划线的组合,不得包含汉字空格和特殊字符, 需要与文章内容相关
**author** 可以为中文英文以及任意组合, 但是不得有歧义, 暴力, 辱骂等词汇, 否则可能会被拒绝合并
**desc** 相关的简要描述, 需要对添加的组件或者界面进行简要描述, 方便后期搜索引擎采集
**email** 创建者的邮箱
## 查看创建的 Page
为了能正确的加载出新的界面, 建议重新启动当前项目. 在**Widget -> Developer -> 本地代码**中,您可以找到您新建的界面
<image src='https://img.alicdn.com/tfs/TB1eNLYc7Y2gK0jSZFgXXc5OFXa-744-722.png' width='300px' />
## 编辑界面
为了能动态的将**markdown**转化成**可识别**的内容, 需要在您项目中调用 **goCli watch**, 然后可以编辑以下位置的md文件, 更改当前文件内容, 即可动态更新我们详情页的内容.
```
lib/standard_pages/standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.md
```
参考:
![](https://img.alicdn.com/tfs/TB1cHLZc.T1gK0jSZFhXXaAtVXa-1393-760.gif)
## 引用Flutter 实例
如何在markdown中引用flutter widget实例请参考: [WidgetDemo](https://github.com/alibaba/flutter-go/blob/beta/go-cli/utils/tpl.md)

View File

@ -1,110 +0,0 @@
# GoCli 使用方式
## 安装
获取最新flutterGo代码分之后. 在源文件下会有 **go-cli** 的文件.
首先进入该文件夹并安装go-cli所需要的依赖
```
cd go-cli
pub get
```
然后使用pub global命令将文件包注册到全局
```
pub global activate --source path /{your flutter go absolute path}/fluttergo/go-cli
```
使用pub global list命令查看全局包列表 如果看到有 **goCli 1.0.0**则证明安装成功
```
goCli 1.0.0 at path "/{youpath}/flutter-go/go-cli"
```
## 使用方式
现在支持以下几种命令
- createDemo 新增flutter go demo.
- createPage 新增flutter go page.
- watch 动态生成文档与demo相关
- build 生成文档与demo相关
### createDemo
动态生成widget demo, 可以创建demo.以便详情页中使用
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
[✓] 请输入新增加的demo名称? demoName
[✓] 请输入您的姓名(使用英文) yourName
[✓] 请输入您的github的email地址 yourEmail
[✓] 请输入您demo的描述 这是一个测试的标准demo
在完成以上操作后, 可以得到这样的输出:
```
------------------
您新增的组件信息如下
==================
{
name : demoName
author : yourName
email : yourEmail
desc : 这是一个测试的标准demo
}
==================
[✓] Is this the config you want ? (Y/n) y
{
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
}
```
您可以在任意详情页中, 通过以下方式调用
```
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```
### createPage
使用方式同上. 通过该命令可以创建标准的详情页.您可以通过修改index.md进行动态的更新您所创建的详情页.
目录结构为
```
standard_pages/
├── index.dart (不可人为修改)
└── standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096
├── .page.json (不可人为修改)
├── index.dart (不可人为修改)
└── index.md (可修改)
```
### watch
监听并编译standard_pages与page_demo_package下的的文件改动. 动态处理demo目录与文件markdown转化等.
## 注意
- 在修改page_demo_package或者standard_pages目录下的文件操作时. 建议在flutterGo目录执行goCLi watch 开启文件动态编译
- name, author 字段必须使用英文开头, 不允许使用特殊符号. 正常的示范 name ='name_test' author = 'abcdefg';
- 暂时阶段demo与page,一经过创建不允许修改名称作者等信息. 凡是被收录进主分支的不允许被删除

View File

@ -1,17 +0,0 @@
import 'package:args/args.dart'; // 使用其中两个类ArgParser和ArgResults
import 'package:args/command_runner.dart';
import '../src/cli_command_runder.dart';
ArgResults argResults; // 声明ArgResults类型的顶级变量保存解析的参数结果
// 同时argResults也是ArgResults的实例
void main(List<String> args) async {
// createDemo();
try {
await run(args);
} on UsageException catch (e) {
print(' ');
print(e.usage);
}
}

View File

@ -1,3 +0,0 @@
{
"name": "sanfan"
}

View File

@ -1,24 +0,0 @@
name: goCli
description: bin_go
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# Read more about versioning at semver.org.
version: 1.0.0
executables:
goCli:
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
args: '^1.5.1'
dart_inquirer: '^1.0.0'
watcher: ^0.9.7+10
mustache: ^1.1.1
dev_dependencies:

View File

@ -1,95 +0,0 @@
import 'dart:io';
import 'dart:convert';
import '../../utils/util.dart';
import '../config.dart';
import '../exception/demo.dart';
Future<List> buildDemoListJson() async {
List<FileSystemEntity> childList = await readeDirChildren(TARGET_DEMO_DIC, false);
List<String> demoPathList = [];
List<Map<String, dynamic>> detailList = []; // 存放所有demo的详情的列表
for(FileSystemEntity entity in childList) {
//文件、目录和链接都继承自FileSystemEntity
//FileSystemEntity.type静态函数返回值为FileSystemEntityType
//FileSystemEntityType有三个常量
//Directory、FILE、LINK、NOT_FOUND
//FileSystemEntity.isFile .isLink .isDerectory可用于判断类型
Uri url = entity.uri;
if (await FileSystemEntity.isDirectory(entity.path)) {
try {
await checkDemo(entity.path);
demoPathList.add(entity.path);
} on InvalidDemo catch (e) {
print("不存在 $e");
}
}
}
for (String dicPath in demoPathList) {
String target = '$dicPath/.demo.json';
String jsonString = await readeFile(target);
try {
Map<String, dynamic> item = json.decode(jsonString);
detailList.add(item);
} catch (err) {
print("err $err");
throw new Exception('$dicPath');
}
}
print("本次编译: 获取${detailList.length}条demo数据");
String demoTplString = renderDemosDart(detailList);
// 生成 page_demo_package/index.dart
writeContent2Path(TARGET_DEMO_DIC, 'index.dart', demoTplString.replaceAll(new RegExp('-'), '_'));
// 生成 page_demo_package/.demo.dart
writeContent2Path(TARGET_DEMO_DIC, '.demo.json', json.encode(detailList));
return Future(() => childList);
// return ;
}
String renderDemosDart(List<Map<String, dynamic>> data) {
// 自定义前缀 避免出现数字非法字符等
String pre = "StandardDemo";
String head = '';
String foot = 'var demoObjects = { \r\n';
for (int i = 0; i < data.length; i++) {
Map<String, dynamic> item = data[i];
String demoImportName = '${item['name']}_${item['id']}';
head += "import '${item['name']}_${item['author']}_${item['id']}/index.dart' as StandardDemo_$demoImportName;\r\n";
foot += " '${item['id']}': ${pre}_${demoImportName}.demoWidgets";
if (i != data.length - 1) {
foot += ',\r\n';
}
}
foot += "\r\n};";
return head + foot;
}
Future<bool> checkDemo(String path) async {
List files = [
'index.dart',
'.demo.json',
'src/'
];
bool success = true;
for (String name in files) {
bool isDic = name.indexOf('/') != -1;
bool isExist ;
String detailPath = '$path/$name';
if (isDic) {
isExist = await Directory(detailPath).exists();
} else {
isExist = await File(detailPath).exists();
}
if (!isExist) {
throw new InvalidDemo('$path$name not exit');
}
}
return Future(() => true);
}

View File

@ -1,186 +0,0 @@
import 'dart:io';
import 'dart:convert';
import 'package:mustache/mustache.dart';
import 'package:path/path.dart' as p;
import '../../utils/util.dart';
import '../config.dart';
import '../exception/demo.dart';
String prettyJson(Map json) {
String res = "{";
json.forEach((k, v) {
res += (
"\t'$k': '$v'");
});
res +='}';
return res;
}
Future<List> buildPageListJson() async {
List<FileSystemEntity> childList = await readeDirChildren(TARGET_PAGE_DIC, false);
List<String> pagePathList = [];
List<Map<String, dynamic>> detailList = []; // 存放所有demo的详情的列表
int errCount = 0;
int pageCount = 0;
for(FileSystemEntity entity in childList) {
//文件、目录和链接都继承自FileSystemEntity
//FileSystemEntity.type静态函数返回值为FileSystemEntityType
//FileSystemEntityType有三个常量
//Directory、FILE、LINK、NOT_FOUND
//FileSystemEntity.isFile .isLink .isDerectory可用于判断类型
if (await FileSystemEntity.isDirectory(entity.path)) {
pageCount++;
try {
await checkPage(entity.path);
pagePathList.add(entity.path);
} on InvalidDemo catch (e) {
errCount++;
print("不存在 $e");
}
}
}
for (String dicPath in pagePathList) {
String target = '$dicPath/.page.json';
String jsonString = await readeFile(target);
try {
Map<String, dynamic> item = json.decode(jsonString);
detailList.add(item);
} catch (err) {
print("err $err");
throw new Exception('$dicPath');
}
}
print("本次编译: 总${pageCount}个界面, 成功${detailList.length}条, 失败${errCount}");
String demoTplString = renderPagesDart(detailList);
//
// // 生成 page_demo_package/index.dart
writeContent2Path(TARGET_PAGE_DIC, 'index.dart', demoTplString.replaceAll(new RegExp('-'), '_'));
// // 生成 page_demo_package/.demo.dart
writeContent2Path(TARGET_PAGE_DIC, '.pages.json', json.encode(detailList));
return Future(() => childList);
// return ;
}
String renderPagesDart(List<Map<String, dynamic>> data) {
print('data>>> $data');
var source = '''
{{# pages }}
import '{{ name }}_{{ author }}_{{ id }}/index.dart' as StandardPage_{{ name }}_{{ id }};
{{/ pages }}
class StandardPages {
Map<String, String> standardPages;
Map<String, String> getPages() {
return {
"0": "0" {{# pages }},
"{{ id }}" : StandardPage_{{ name }}_{{ id }}.getMd()
{{/ pages }}
};
}
List<Map<String, String>> getLocalList() {
return [
{}{{# pages }},
{ "id": "{{ id }}", "name": "{{ name }}", "email": "{{ email }}", "author": "{{ author }}"}
{{/ pages }}
];
}
}
''';
var template = new Template(source, name: 'template-filename.html');
// 自定义前缀 避免出现数字非法字符等
Map<String, List> formatData = {
"pages": data
};
String output = template.renderString(formatData);
return output;
}
Future<bool> checkPage(String path) async {
List files = [
'index.dart',
'index.md',
'.page.json'
];
for (String name in files) {
bool isDic = name.indexOf('/') != -1;
bool isExist ;
String detailPath = '$path/$name';
if (isDic) {
isExist = await Directory(detailPath).exists();
} else {
isExist = await File(detailPath).exists();
}
if (!isExist) {
throw new InvalidDemo('$path$name not exit');
}
}
return Future(() => true);
}
Future<void> transformMd2Dart(String path) async{
print("pathLL: $path");
String mdContent = await readeFile(p.absolute(path,'index.md'));
String result = """
String getMd() {
return \"\"\"
${mdContent}\"\"\";
}
""";
writeContent2Path(p.absolute(path), 'index.dart', result);
return '';
}
//main() {
// buildPageListJson();
//}
////
//// Created with Android Studio.
//// User: 三帆
//// Date: 25/05/2019
//// Time: 21:23
//// email: sanfan.hx@alibaba-inc.com
//// target: 该文件用在打包后的代码中.日常开发的时候, 获取markdown不走该目录
////
//import 'package:flutter/material.dart';
//import 'page1_hanxu_172ba42f_0520_401e_b568_ba7f7f6835e4/index.dart' as page1_hanxu_172ba42f_0520_401e_b568_ba7f7f6835e4;
//
//
//class StandardPages {
// Map<String, String> standardPages;
// Map<String, String> getPages() {
// return {
// 'page1_hanxu_172ba42f_0520_401e_b568_ba7f7f6835e4': page1_hanxu_172ba42f_0520_401e_b568_ba7f7f6835e4.stringMd
// };
// }
//}
//var stringMd = """# page
//
//this is page markdown
//
//you can load demo like this
//
//```
//[demo: xxxid]
//```
//
//""";
//

View File

@ -1,35 +0,0 @@
import 'dart:async';
import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import './version.dart';
import './command/create_demo.dart';
import './command/create_page.dart';
import './command/watch_md.dart';
import './command/build.dart';
Future<int> run(List<String> args) => _CommandRunner().run(args);
class _CommandRunner extends CommandRunner<int> {
_CommandRunner() : super('goCli', 'A tool to develop flutter go projects.') {
argParser.addFlag('version',
negatable: false, help: 'Prints the version of goCi.');
addCommand(CreateDemoCommand());
addCommand(CreatePageCommand());
addCommand(WatchCommand());
addCommand(Build());
}
@override
Future<int> runCommand(ArgResults topLevelResults) async {
if (topLevelResults['version'] as bool) {
return 0;
}
// In the case of `help`, `null` is returned. Treat that as success.
return await super.runCommand(topLevelResults) ?? 0;
}
}

View File

@ -1,32 +0,0 @@
//
// Created with Android Studio.
// User: 三帆
// Date: 30/07/2019
// Time: 16:51
// email: sanfan.hx@alibaba-inc.com
// target: build
//
import 'package:args/command_runner.dart';
import '../build/build_demo_list.dart';
import '../build/build_page_list.dart';
import 'dart:async';
class Build extends Command<int> {
@override
final name = 'build';
@override
final description = '生成索引等';
@override
Future<int> run() async {
buildPageListJson();
buildDemoListJson();
return 0;
}
}

View File

@ -1,137 +0,0 @@
import 'dart:io';
import 'package:args/args.dart'; // 使用其中两个类ArgParser和ArgResults
import 'package:dart_inquirer/dart_inquirer.dart';
import 'package:console/console.dart';
import 'package:path/path.dart' as p;
import 'package:args/command_runner.dart';
import '../build/build_demo_list.dart';
import '../config.dart';
import '../../utils/util.dart';
ArgResults argResults; // 声明ArgResults类型的顶级变量保存解析的参数结果
class DemoDetail {
String name;
String author;
String email;
String desc;
String id;
DemoDetail.fromJson(Map<dynamic, dynamic> json) {
name = json['name'].trim();
author = json['author'].trim();
email = json['email'].trim();
desc = json['desc'].trim();
id = json['id'] ?? generateId();
}
}
// 同时argResults也是ArgResults的实例
void createDemo() async {
Map environmentVars = Platform.environment;
List<Question> questions = [
InputQuestion('name', '请输入新增加的demo名称?'),
InputQuestion('author', '请输入您的姓名(使用英文)'),
InputQuestion('email', '请输入您的github的email地址'),
InputQuestion('desc', '请输入您demo的描述'),
];
Map<dynamic, dynamic> answers = {};
// 获取初次信息
Prompt prompt = Prompt(questions);
DemoDetail demoDetail;
answers = await prompt.execute();
print(Seperator());
print('您新增的组件信息如下');
print(Seperator('='));
prettyPrintJson(answers);
print(Seperator('='));
questions =[ConfirmQuestion('confirm', 'Is this the config you want ?')];
prompt = Prompt(questions);
Map confirmAnswers = await prompt.execute();
if (confirmAnswers['confirm'] != true) {
return createDemo();
}
demoDetail = DemoDetail.fromJson(answers);
var demoPath = '$TARGET_DEMO_DIC/${demoDetail.name}_${demoDetail.author}_${demoDetail.id}';
// 创建root文件
await createFile(demoPath);
await createFile('$demoPath/src');
// print("demoPath>>>> ${environmentVars['PWD']}/${demoPath}");
writeContent2Path('$demoPath/src/', 'index.dart', """
import 'package:flutter/material.dart';
class Demo extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Demo> {
@override
Widget build(BuildContext context) {
return Container(
child: Text("this is flutter go init demo"),
);
}
}
""");
writeContent2Path('$demoPath/', '.demo.json', """
{
"name": "${demoDetail.name}",
"screenShot": "",
"author":"${demoDetail.author}",
"email": "${demoDetail.email}",
"desc": "${demoDetail.desc}",
"id": "${demoDetail.id}"
}
""");
writeContent2Path('$demoPath/', 'index.dart', """
//
// Created with flutter go cli
// User: ${demoDetail.author}
// Time: ${new DateTime.now()}
// email: ${demoDetail.email}
// desc: ${demoDetail.desc}
//
import 'src/index.dart';
var demoWidgets = [
new Demo()
];
""");
// format('{color.red}Invalid demo happends: $details {color.normal}');
prettyPrintJson({
'新建的demo文件位于': p.absolute((demoPath)),
'demoId为': demoDetail.id,
'markdown中调用方式': '[demo:${demoDetail.id}]'
});
buildDemoListJson();
}
class CreateDemoCommand extends Command<int> {
@override
final name = 'createDemo';
@override
final description = '新增flutter go demo.';
CreateDemoCommand() {
}
@override
Future<int> run() async {
createDemo();
return 0;
}
}

View File

@ -1,124 +0,0 @@
import 'dart:io';
import 'package:args/args.dart'; // 使用其中两个类ArgParser和ArgResults
import 'package:dart_inquirer/dart_inquirer.dart';
import 'package:args/command_runner.dart';
import '../build/build_page_list.dart';
import '../config.dart';
import '../../utils/util.dart';
var pageMarkdown = """
# page
this is page markdown
you can load demo like this
```
[demo: xxxid]
```
""";
ArgResults argResults; // 声明ArgResults类型的顶级变量保存解析的参数结果
class PageDetail {
String name;
String author;
String title;
String email;
String desc;
String id;
PageDetail.fromJson(Map<dynamic, dynamic> json) {
name = json['name'];
author = json['author'];
title = json['title'];
email = json['email'];
desc = json['desc'];
id = json['id'] ?? generateId();
}
}
// 同时argResults也是ArgResults的实例
void createPage() async {
Map environmentVars = Platform.environment;
List<Question> questions = [
InputQuestion('name', '请输入文件名称?'),
InputQuestion('title', '请输入界面名称?'),
InputQuestion('author', '请输入您的姓名(使用英文)'),
InputQuestion('email', '请输入您的email地址'),
InputQuestion('desc', '请输入您界面的简要'),
];
Map<dynamic, dynamic> answers = {};
// 获取初次信息
Prompt prompt = Prompt(questions);
PageDetail pageDetail;
answers = await prompt.execute();
print(Seperator());
print('您新增的界面信息如下');
print(Seperator('='));
prettyPrintJson(answers);
print(Seperator('='));
questions =[ConfirmQuestion('confirm', 'Is this the config you want ?')];
prompt = Prompt(questions);
Map confirmAnswers = await prompt.execute();
if (confirmAnswers['confirm'] != true) {
return createPage();
}
pageDetail = PageDetail.fromJson(answers);
var demoPath = '$TARGET_PAGE_DIC/${pageDetail.name}_${pageDetail.author}_${pageDetail.id}';
// 创建root文件
await createFile(demoPath);
pageMarkdown = await readeFile("${environmentVars['PWD']}/go-cli/utils/tpl.md");
writeContent2Path('$demoPath/', 'index.dart', """
String getMd() {
return \"\"\"
${pageMarkdown}\"\"\";
}
""");
writeContent2Path('$demoPath/', '.page.json', """
{
"name": "${pageDetail.name}",
"screenShot": "",
"author":"${pageDetail.author}",
"title":"${pageDetail.title}",
"email": "${pageDetail.email}",
"desc": "${pageDetail.desc}",
"id": "${pageDetail.id}"
}
""");
writeContent2Path('$demoPath/', 'index.md', pageMarkdown);
buildPageListJson();
prettyPrintJson({
'界面位于': demoPath,
'Id': pageDetail.id,
'文件夹名称': '${pageDetail.name}_${pageDetail.author}_${pageDetail.id}'
});
}
class CreatePageCommand extends Command<int> {
@override
final name = 'createPage';
@override
final description = '新增flutter go page.';
CreateDemoCommand() {
}
@override
Future<int> run() async {
createPage();
return 0;
}
}

View File

@ -1,102 +0,0 @@
//
// Created with Android Studio.
// User: 三帆
// Date: 08/06/2019
// Time: 16:34
// email: sanfan.hx@alibaba-inc.com
// target: 监听demo与md
//
import 'package:path/path.dart' as p;
import 'package:args/command_runner.dart';
import '../build/build_demo_list.dart';
import '../build/build_page_list.dart';
import 'package:watcher/watcher.dart';
import '../config.dart';
import 'dart:async';
void watch() {
Timer _changeTimer;
List<Map<String, String>> config = [
{
"type": "demo",
"path": '$TARGET_DEMO_DIC'
}
];
List<String> demoIgnore = [
'.demo.json',
'index.dart',
'info.json',
'readme.md',
];
var watcherDemo = DirectoryWatcher(p.absolute('$TARGET_DEMO_DIC'));
watcherDemo.events.listen((event) {
if (isIgnore(demoIgnore, TARGET_DEMO_DIC, event.path)) {
return ;
}
if (event.type == ChangeType.ADD || event.type == ChangeType.REMOVE) {
if (_changeTimer != null && _changeTimer.isActive) {
_changeTimer.cancel();
}
_changeTimer = new Timer(Duration(milliseconds: 1000), () {
buildDemoListJson();
});
}
}, onError: (error) {
print('watch 发生错误: $error');
});
List<String> pageIgnore = [
'index.dart',
'.pages.json'
];
var watcherPage = DirectoryWatcher(p.absolute('$TARGET_PAGE_DIC'));
watcherPage.events.listen((event) {
if (isIgnore(pageIgnore, TARGET_PAGE_DIC, event.path)) {
return ;
}
if (event.type == ChangeType.ADD || event.type == ChangeType.REMOVE) {
print("buildPageListJson:::");
buildPageListJson();
return ;
}
if (event.type == ChangeType.MODIFY) {
if (event.path.contains('index.md')) {
transformMd2Dart(event.path.replaceAll('/index.md', ''));
}
return ;
}
print(event);
});
}
bool isIgnore (List<String> ignorePath, parentPath, currentPath) {
for (String ignore in ignorePath) {
String path = p.absolute(parentPath, ignore);
if (currentPath.contains(path)) {
// print("修改的文件, 是忽略列表中的文件, 跳过编译!");
return true;
}
}
return false;
}
class WatchCommand extends Command<int> {
@override
final name = 'watch';
@override
final description = '动态生成文档与demo相关';
CreateDemoCommand() {
}
@override
Future<int> run() async {
watch();
return 0;
}
}

View File

@ -1,4 +0,0 @@
// 生成Demo的目录位置
const TARGET_PAGE_DIC = 'lib/standard_pages';
const TARGET_DEMO_DIC = 'lib/page_demo_package';

View File

@ -1,21 +0,0 @@
//
// Created with Android Studio.
// User: 三帆
// Date: 25/05/2019
// Time: 21:20
// email: sanfan.hx@alibaba-inc.com
// target: xxx
//
import 'package:console/console.dart';
class InvalidDemo implements Exception {
final String details;
InvalidDemo(this.details);
@override
String toString() {
return format('{color.red}Invalid demo happends: $details {color.normal}');
}
}

View File

@ -1 +0,0 @@
const packageVersion = '1.0.0';

View File

@ -1,60 +0,0 @@
# 标准的详情页
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
您可以通过goCli固定命令创建详情页所需要的 **Flutter 实例**
```
goCLi createDemo
```
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
[✓] 请输入新增加的demo名称? demoName
[✓] 请输入您的姓名(使用英文) yourName
[✓] 请输入您的github的email地址 yourEmail
[✓] 请输入您demo的描述 这是一个测试的标准demo
在完成以上操作后, 可以得到这样的输出:
```
------------------
您新增的组件信息如下
==================
{
name : demoName
author : yourName
email : yourEmail
desc : 这是一个测试的标准demo
}
==================
[✓] Is this the config you want ? (Y/n) y
{
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
}
```
您可以在任意详情页中, 通过以下方式调用
```
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```
# 注意事项
**name** 必须**英文开头**, 统一用小写的英文字母,数字和下划线的组合,不得包含汉字空格和特殊字符, 需要与文章内容相关
**author** 可以为中文英文以及任意组合, 但是不得有歧义, 暴力, 辱骂等词汇, 否则可能会被拒绝合并
**desc** 相关的简要描述, 需要对添加的组件或者界面进行简要描述, 方便后期搜索引擎采集
**email** 创建者的邮箱

View File

@ -1,64 +0,0 @@
import 'dart:io';
import 'dart:math';
Future<bool> createFile(String path) async {
final tempDic = new Directory(path);
var exits = await tempDic.exists();
if (exits) {
print("文件当前已存在");
return Future(() => false);
}
await tempDic.createSync(recursive: true);
return Future(() => true);
}
Future<String> readeFile(String path) async {
String content = await new File(path).readAsString();
return Future(() => content);
}
// 该文件调用的时候. 必须存在父级文件夹
Future<void> writeContent2Path(String path,String fileName, String content) async {
var file = File('$path/$fileName');
var sink = file.openWrite();
sink.write(content);
await sink.flush();
await sink.close();
return Future.value();
}
String generateId() {
int d = DateTime.now().millisecondsSinceEpoch;
var random = new Random(1);
var template = 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx';
var id = template.replaceAllMapped(new RegExp(r"[x|y]"), (c) {
var r = ((d + random.nextDouble() * 16) % 16).toInt();
d = d ~/ 16;
var t = c.group(0) == 'x' ? r : (1 & 0x3 | 0x8);
return t.toRadixString(16);
});
return id;
}
/// 该文件调用的时候. 必须存在父级文件夹
/// @param path 目录地址
/// @param recursive 是否显示子目录或者子文件
Future<List<FileSystemEntity>> readeDirChildren(String path, [bool recursive = false]) async {
try {
var dirParent = Directory(path);
Stream<FileSystemEntity> entityList = dirParent.list(recursive: false, followLinks: false);
List<FileSystemEntity> fileChildren = [];
await for(FileSystemEntity entity in entityList) {
fileChildren.add(entity);
}
return Future(() => fileChildren);
} catch (e) {
print('读取文件失败 ${e.toString()}');
return Future(() => []);
}
}
//void main() {
// readeFile('/Users/ontwo/Documents/ali/flutter/flutter-common-widgets-app/LICENSE');
//}

View File

@ -25,23 +25,18 @@
0828E4A52206936100A59437 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0828E4A42206936100A59437 /* Images.xcassets */; };
084A20882202E4FD00428FF5 /* flutter go.png in Resources */ = {isa = PBXBuildFile; fileRef = 084A20872202E4FD00428FF5 /* flutter go.png */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
17DB4C25EDB98B3648015B9E /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 813A089174EBE6F8695A172E /* libPods-Runner.a */; };
333E5DAE7FC10AC69FEC26C0 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA792F029EDD7A11295D192 /* libPods-Runner.a */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
94722E5C22511D3600F63900 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 94722E5B22511D3600F63900 /* GoogleService-Info.plist */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
FA240D7922F2857D003025F3 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0115F22F1B9DF0016E673 /* Flutter.framework */; };
FA240D7A22F2857D003025F3 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0115F22F1B9DF0016E673 /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
FA240D7B22F28581003025F3 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0116122F1B9DF0016E673 /* App.framework */; };
FA240D7C22F28581003025F3 /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0116122F1B9DF0016E673 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
FAD0116422F1B9DF0016E673 /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = FAD0115E22F1B9DF0016E673 /* Debug.xcconfig */; };
FAD0116522F1B9DF0016E673 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0115F22F1B9DF0016E673 /* Flutter.framework */; };
FAD0116622F1B9DF0016E673 /* Release.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = FAD0116022F1B9DF0016E673 /* Release.xcconfig */; };
FAD0116722F1B9DF0016E673 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD0116122F1B9DF0016E673 /* App.framework */; };
FAD0116822F1B9DF0016E673 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = FAD0116222F1B9DF0016E673 /* AppFrameworkInfo.plist */; };
FAD0116922F1B9DF0016E673 /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = FAD0116322F1B9DF0016E673 /* Generated.xcconfig */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -51,8 +46,8 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
FA240D7C22F28581003025F3 /* App.framework in Embed Frameworks */,
FA240D7A22F2857D003025F3 /* Flutter.framework in Embed Frameworks */,
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@ -77,27 +72,26 @@
0828E494220692B500A59437 /* iPhone XR Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone XR Landscape.png"; sourceTree = "<group>"; };
0828E4A42206936100A59437 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
084A20872202E4FD00428FF5 /* flutter go.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "flutter go.png"; sourceTree = "<group>"; };
10D9E78922B7651B003C2C98 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
813A089174EBE6F8695A172E /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
94722E5B22511D3600F63900 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A4868A865F318D337B7500AF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
B7B77D3AD1E975E5BE03D770 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
FAD0115E22F1B9DF0016E673 /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
FAD0115F22F1B9DF0016E673 /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Flutter.framework; sourceTree = "<group>"; };
FAD0116022F1B9DF0016E673 /* Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
FAD0116122F1B9DF0016E673 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = App.framework; sourceTree = "<group>"; };
FAD0116222F1B9DF0016E673 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AppFrameworkInfo.plist; sourceTree = "<group>"; };
FAD0116322F1B9DF0016E673 /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Generated.xcconfig; sourceTree = "<group>"; };
A9941E6EA19A9CEF6B117A70 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
CBA6E34746642008D95A119D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
DDA792F029EDD7A11295D192 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -105,11 +99,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
17DB4C25EDB98B3648015B9E /* libPods-Runner.a in Frameworks */,
FAD0116722F1B9DF0016E673 /* App.framework in Frameworks */,
FAD0116522F1B9DF0016E673 /* Flutter.framework in Frameworks */,
FA240D7922F2857D003025F3 /* Flutter.framework in Frameworks */,
FA240D7B22F28581003025F3 /* App.framework in Frameworks */,
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
333E5DAE7FC10AC69FEC26C0 /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -138,24 +130,46 @@
path = launch;
sourceTree = "<group>";
};
8B83D3FCE2CD78ED2CD9BC84 /* Frameworks */ = {
0C172CA58CDB230D5DA80034 /* Pods */ = {
isa = PBXGroup;
children = (
813A089174EBE6F8695A172E /* libPods-Runner.a */,
CBA6E34746642008D95A119D /* Pods-Runner.debug.xcconfig */,
A9941E6EA19A9CEF6B117A70 /* Pods-Runner.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
2EC8A3499721CE770475DCE7 /* Frameworks */ = {
isa = PBXGroup;
children = (
DDA792F029EDD7A11295D192 /* libPods-Runner.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
FAD0115D22F1B9DF0016E673 /* Flutter */,
0828E485220692A700A59437 /* launch */,
084A20872202E4FD00428FF5 /* flutter go.png */,
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
F1785F83FDEE22F813679AE5 /* Pods */,
8B83D3FCE2CD78ED2CD9BC84 /* Frameworks */,
0C172CA58CDB230D5DA80034 /* Pods */,
2EC8A3499721CE770475DCE7 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -170,7 +184,6 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
10D9E78922B7651B003C2C98 /* Runner.entitlements */,
94722E5B22511D3600F63900 /* GoogleService-Info.plist */,
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
@ -194,28 +207,6 @@
name = "Supporting Files";
sourceTree = "<group>";
};
F1785F83FDEE22F813679AE5 /* Pods */ = {
isa = PBXGroup;
children = (
A4868A865F318D337B7500AF /* Pods-Runner.debug.xcconfig */,
B7B77D3AD1E975E5BE03D770 /* Pods-Runner.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
FAD0115D22F1B9DF0016E673 /* Flutter */ = {
isa = PBXGroup;
children = (
FAD0115E22F1B9DF0016E673 /* Debug.xcconfig */,
FAD0115F22F1B9DF0016E673 /* Flutter.framework */,
FAD0116022F1B9DF0016E673 /* Release.xcconfig */,
FAD0116122F1B9DF0016E673 /* App.framework */,
FAD0116222F1B9DF0016E673 /* AppFrameworkInfo.plist */,
FAD0116322F1B9DF0016E673 /* Generated.xcconfig */,
);
path = Flutter;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -223,15 +214,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
FBE7DB4E8DD084FE99B9ED05 /* [CP] Check Pods Manifest.lock */,
443E32A5789BE5CCDA6B5E59 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
B34D03FFEA3831330E64E5C7 /* [CP] Embed Pods Frameworks */,
E54A6BDEF16ACE4A6988913A /* [CP] Copy Pods Resources */,
C38E5EAE601417DA9DF11753 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -248,26 +238,22 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = 4WLT68XRNA;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.Push = {
enabled = 1;
};
};
ProvisioningStyle = Manual;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
@ -286,7 +272,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FAD0116622F1B9DF0016E673 /* Release.xcconfig in Resources */,
0828E4A0220692B500A59437 /* iPad Landscape.png in Resources */,
0828E4A1220692B500A59437 /* iPhone XR Portrait.png in Resources */,
0828E49F220692B500A59437 /* iPhone XS Max Landscape.png in Resources */,
@ -294,20 +279,18 @@
0828E4A3220692B500A59437 /* iPhone XR Landscape.png in Resources */,
0828E4A2220692B500A59437 /* iPhone Portrait-Retina HD 5.5.png in Resources */,
0828E49A220692B500A59437 /* iPhone X_XS Portrait.png in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
0828E49E220692B500A59437 /* iPad Portrait@2x.png in Resources */,
0828E49D220692B500A59437 /* iPhone Portrait@2x.png in Resources */,
0828E499220692B500A59437 /* iPhone Portrait-Retina HD 4.7.png in Resources */,
FAD0116822F1B9DF0016E673 /* AppFrameworkInfo.plist in Resources */,
084A20882202E4FD00428FF5 /* flutter go.png in Resources */,
0828E497220692B500A59437 /* iPhone X_XS Landscape.png in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
0828E4A52206936100A59437 /* Images.xcassets in Resources */,
FAD0116922F1B9DF0016E673 /* Generated.xcconfig in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
0828E49B220692B500A59437 /* iPad Landscape@2x.png in Resources */,
0828E495220692B500A59437 /* iPhone Portrait-Retina 4.png in Resources */,
0828E498220692B500A59437 /* iPhone XS Max Portrait.png in Resources */,
FAD0116422F1B9DF0016E673 /* Debug.xcconfig in Resources */,
94722E5C22511D3600F63900 /* GoogleService-Info.plist in Resources */,
0828E496220692B500A59437 /* iPad Portrait.png in Resources */,
0828E49C220692B500A59437 /* iPhone Landscape-Retina HD 5.5.png in Resources */,
@ -329,11 +312,29 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
};
443E32A5789BE5CCDA6B5E59 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 12;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
@ -343,15 +344,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
B34D03FFEA3831330E64E5C7 /* [CP] Embed Pods Frameworks */ = {
C38E5EAE601417DA9DF11753 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
);
name = "[CP] Embed Pods Frameworks";
@ -360,47 +361,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
E54A6BDEF16ACE4A6988913A /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/flutter_downloader/FlutterDownloaderDatabase.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FlutterDownloaderDatabase.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
FBE7DB4E8DD084FE99B9ED05 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@ -440,9 +401,9 @@
/* Begin XCBuildConfiguration section */
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
@ -467,7 +428,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -496,9 +457,9 @@
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
@ -546,13 +507,12 @@
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FAD0115E22F1B9DF0016E673 /* Debug.xcconfig */;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Launch2;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 4WLT68XRNA;
ENABLE_BITCODE = NO;
@ -566,24 +526,21 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
ONLY_ACTIVE_ARCH = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.fluttergo;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
TARGETED_DEVICE_FAMILY = "1,2";
PROVISIONING_PROFILE_SPECIFIER = FlutterGO_alibaba_distribution_app_store;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FAD0116022F1B9DF0016E673 /* Release.xcconfig */;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Launch2;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 4WLT68XRNA;
ENABLE_BITCODE = NO;
@ -597,11 +554,9 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
ONLY_ACTIVE_ARCH = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.fluttergo;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
TARGETED_DEVICE_FAMILY = "1,2";
PROVISIONING_PROFILE_SPECIFIER = FlutterGO_alibaba_distribution_ad_hoc;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
@ -616,7 +571,7 @@
97C147041CF9000F007C117D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
@ -625,7 +580,7 @@
97C147071CF9000F007C117D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
</dict>
</plist>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -42,7 +42,7 @@
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@ -51,7 +51,8 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
@ -59,12 +60,12 @@
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
@ -84,7 +85,7 @@
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -1,6 +1,5 @@
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#include "FlutterJPushPlugin.h"
@import Firebase;// firebase
@ -11,8 +10,6 @@
[FIRApp configure];// firebase
[self startupJPush:launchOptions appKey:@"62eb07d227d1f11dd7fa6239" channel:@"jpush" isProduction:FALSE];
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
[NSThread sleepForTimeInterval:2];

View File

@ -1,12 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
@ -18,9 +14,9 @@
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>

View File

@ -22,8 +22,6 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSApplicationCategoryType</key>
<string></string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
</dict>
</plist>

View File

@ -1,36 +1,10 @@
class Api{
// static const String BASE_URL = 'http://flutter-go.alibaba.net/';
static const String BASE_URL = 'https://flutter-go.pub/api/';
// static const String BASE_URL = 'http://127.0.0.1:6001/';
static const String BASE_URL = 'http://flutter-go.alibaba.net/';
static const String DO_LOGIN = BASE_URL+'doLogin';//登陆
static const String CHECK_LOGIN = BASE_URL+'checkLogin';//验证登陆
static const String LOGOUT = BASE_URL+'logout';//退出登陆
static const String GET_USER_INFO = BASE_URL+'getUserInfo';//获取用户信息
static const String VERSION = BASE_URL+'getAppVersion';//检查版本
static const String FEEDBACK = BASE_URL+'auth/feedback';//建议反馈
// static const String LOTOUT = BASE_URL+'logout';//退出登陆
static const String GET_ALL_COLLECTION = BASE_URL+'auth/getAllUserCollection';//获取全部收藏
static const String REMOVE_COLLECTION = BASE_URL+'auth/removeCollection';//移除收藏
static const String ADD_COLLECTION = BASE_URL+'auth/addCollection';//添加收藏
static const String CHECK_COLLECTED = BASE_URL+'checkCollected';//校验收藏
static const String SET_THEMECOLOR = BASE_URL+'auth/setThemeColor';//设置主题颜色
static const String GET_THEMECOLOR = BASE_URL +'/getThemeColor';//获取主题颜色
static const String GET_WIDGET_TREE = BASE_URL + 'getCateList';//获取widget列表树
static const String SEARCH_WIDGET = BASE_URL+'searchWidget';//搜索组件
}
}

View File

@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import '../model/cat.dart';
import '../resources/widget_name_to_icon.dart';
import '../components/widget_item_container.dart';
import '../model/widget.dart';
class CateCard extends StatefulWidget {
final CategoryComponent category;
final Cat category;
CateCard({@required this.category});
@override
_CateCardState createState() => _CateCardState();
@ -13,15 +13,28 @@ class CateCard extends StatefulWidget {
class _CateCardState extends State<CateCard> {
// 一级菜单目录下的二级Cat集合
List<CommonItem> _firstChildList;
List<Cat> _firstChildList = new List();
CatControlModel catControl = new CatControlModel();
@override
void initState() {
super.initState();
_firstChildList = widget.category.children;
getFirstChildCategoriesByParentId();
}
// 获取一层目录下的二级内容
getFirstChildCategoriesByParentId() async {
int parentId = widget.category.id;
// 构建查询条件
Cat childCateCondition = new Cat(parentId: parentId);
List<Cat> list = await catControl.getList(childCateCondition);
if (list.isNotEmpty&&list.length>=1 && this.mounted) {
setState(() {
_firstChildList = list;
});
}
}
@override
Widget build(BuildContext context) {
@ -30,6 +43,7 @@ class _CateCardState extends State<CateCard> {
//首字母转为大写
widget.category.name.substring(0, 1),
widget.category.name.substring(0, 1).toUpperCase());
return Container(
width: screenWidth,
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
@ -105,8 +119,9 @@ class _CateCardState extends State<CateCard> {
),
),
child: WidgetItemContainer(
commonItems: this._firstChildList,
columnCount: 3
categories: this._firstChildList,
columnCount: 3,
isWidgetPoint:false
),
);
}

View File

@ -8,12 +8,11 @@ import '../model/widget.dart';
import '../widgets/index.dart';
import '../components/widget_item_container.dart';
enum CateOrWigdet { Cat, WidgetDemo }
class CategoryHome extends StatefulWidget {
CategoryHome(this.token);
final String token;
CategoryHome(this.name);
final String name;
@override
_CategoryHome createState() => new _CategoryHome();
@ -22,11 +21,12 @@ class CategoryHome extends StatefulWidget {
class _CategoryHome extends State<CategoryHome> {
String title = '';
// 显示列表 cat or widget;
List<CommonItem> items = [];
List<Object> widgetPoints = [];
List<CommonItem> catHistory = new List();
List<Cat> categories = [];
List<WidgetPoint> widgetPoints = [];
List<Cat> catHistory = new List();
CatControlModel catControl = new CatControlModel();
WidgetControlModel widgetControl = new WidgetControlModel();
// 所有的可用demos;
List widgetDemosList = new WidgetDemoList().getDemos();
@ -34,60 +34,80 @@ class _CategoryHome extends State<CategoryHome> {
void initState() {
super.initState();
// 初始化加入顶级的name
print("这是新界面的id:>>> ${widget.token}");
CommonItem targetGroup = Application.widgetTree.find(widget.token) ?? [];
print("targetGroup::: $targetGroup");
catHistory.add(
targetGroup
);
this.setState(() {
items = targetGroup.children;
this.getCatByName(widget.name).then((Cat cat) {
catHistory.add(cat);
searchCatOrWigdet();
});
searchCatOrWidget();
}
Future<Cat> getCatByName(String name) async {
return await catControl.getCatByName(name);
}
Future<bool> back() {
// if (catHistory.length == 1) {
// return Future<bool>.value(true);
// }
// catHistory.removeLast();
// searchCatOrWidget();
return Future<bool>.value(true);
if (catHistory.length == 1) {
return Future<bool>.value(true);
}
catHistory.removeLast();
searchCatOrWigdet();
return Future<bool>.value(false);
}
void go(CommonItem cat) {
void go(Cat cat) {
catHistory.add(cat);
searchCatOrWidget();
searchCatOrWigdet();
}
void searchCatOrWidget() async {
CommonItem widgetTree = Application.widgetTree;
// 假设进入这个界面的parent一定存在
CommonItem targetGroup = catHistory.last;
void searchCatOrWigdet() async {
// 假设进入这个界面的parent一定存在
Cat parentCat = catHistory.last;
// 继续搜索显示下一级depth: depth + 1, parentId: parentCat.id
List<Cat> _categories =
await catControl.getList(new Cat(parentId: parentCat.id));
List<WidgetPoint> _widgetPoints = new List();
if (_categories.isEmpty) {
_widgetPoints =
await widgetControl.getList(new WidgetPoint(catId: parentCat.id));
}
this.setState(() {
title = targetGroup.name;
categories = _categories;
title = parentCat.name;
widgetPoints = _widgetPoints;
});
}
void onCatgoryTap(CommonItem cat) {
void onCatgoryTap(Cat cat) {
go(cat);
}
void onWidgetTap(WidgetPoint widgetPoint) {
String targetName = widgetPoint.name;
String targetRouter = '/category/error/404';
widgetDemosList.forEach((item) {
// print("targetRouter = item.routerName> ${[item.name,targetName]}");
if (item.name == targetName) {
targetRouter = item.routerName;
}
});
Application.router.navigateTo(context, "$targetRouter");
}
Widget _buildContent() {
WidgetItemContainer wiContaienr = WidgetItemContainer(
columnCount: 3,
commonItems: items
categories: categories,
isWidgetPoint:false
);
if (widgetPoints.length > 0) {
wiContaienr = WidgetItemContainer(
categories: widgetPoints,
columnCount: 3,
isWidgetPoint:true
);
}
return Container(
padding: const EdgeInsets.only(bottom: 10.0, top: 5.0),
decoration: BoxDecoration(
@ -102,18 +122,14 @@ class _CategoryHome extends State<CategoryHome> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("$title"),
title: Text(title),
),
body: WillPopScope(
onWillPop: () {
return back();
},
child: ListView(
children: <Widget>[
_buildContent(),

View File

@ -1,27 +0,0 @@
// Copyright 2017 Google, Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,39 +0,0 @@
# Flutter Markdown
[![pub package](https://img.shields.io/pub/v/flutter_markdown.svg)](https://pub.dartlang.org/packages/flutter_markdown)
[![Build Status](https://travis-ci.org/flutter/flutter_markdown.svg?branch=master)](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`.

View File

@ -1,10 +0,0 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// A library to render markdown formatted text.
library flutter_markdown;
export 'src/builder.dart';
export 'src/style_sheet.dart';
export 'src/widget.dart';

View File

@ -1,376 +0,0 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io';
import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:path/path.dart' as p;
import 'style_sheet.dart';
typedef Widget DemoBuilder(Map<String, dynamic> attrs);
final Set<String> _kBlockTags = new Set<String>.from(<String>[
'p',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'li',
'blockquote',
'pre',
'ol',
'ul',
'hr',
]);
const List<String> _kListTags = const <String>['ul', 'ol'];
bool _isBlockTag(String tag) => _kBlockTags.contains(tag);
bool _isListTag(String tag) => _kListTags.contains(tag);
class _BlockElement {
_BlockElement(this.tag);
final String tag;
final List<Widget> children = <Widget>[];
int nextListIndex = 0;
}
/// A collection of widgets that should be placed adjacent to (inline with)
/// other inline elements in the same parent block.
///
/// Inline elements can be textual (a/em/strong) represented by [RichText]
/// widgets or images (img) represented by [Image.network] widgets.
///
/// Inline elements can be nested within other inline elements, inheriting their
/// parent's style along with the style of the block they are in.
///
/// When laying out inline widgets, first, any adjacent RichText widgets are
/// merged, then, all inline widgets are enclosed in a parent [Wrap] widget.
class _InlineElement {
_InlineElement(this.tag, {this.style});
final String tag;
/// Created by merging the style defined for this element's [tag] in the
/// delegate's [MarkdownStyleSheet] with the style of its parent.
final TextStyle style;
final List<Widget> children = <Widget>[];
}
/// A delegate used by [MarkdownBuilder] to control the widgets it creates.
abstract class MarkdownBuilderDelegate {
/// Returns a gesture recognizer to use for an `a` element with the given
/// `href` attribute.
GestureRecognizer createLink(String href);
/// Returns formatted text to use to display the given contents of a `pre`
/// element.
///
/// The `styleSheet` is the value of [MarkdownBuilder.styleSheet].
TextSpan formatText(MarkdownStyleSheet styleSheet, String code);
}
/// Builds a [Widget] tree from parsed Markdown.
///
/// See also:
///
/// * [Markdown], which is a widget that parses and displays Markdown.
class MarkdownBuilder implements md.NodeVisitor {
/// Creates an object that builds a [Widget] tree from parsed Markdown.
MarkdownBuilder({
this.delegate,
this.styleSheet,
this.imageDirectory,
this.demoParser
});
/// A delegate that controls how link and `pre` elements behave.
final MarkdownBuilderDelegate delegate;
/// Defines which [TextStyle] objects to use for each type of element.
final MarkdownStyleSheet styleSheet;
final DemoBuilder demoParser;
/// The base directory holding images referenced by Img tags with local file paths.
final Directory imageDirectory;
final List<String> _listIndents = <String>[];
final List<_BlockElement> _blocks = <_BlockElement>[];
final List<_InlineElement> _inlines = <_InlineElement>[];
final List<GestureRecognizer> _linkHandlers = <GestureRecognizer>[];
/// Returns widgets that display the given Markdown nodes.
///
/// The returned widgets are typically used as children in a [ListView].
List<Widget> build(List<md.Node> nodes) {
_listIndents.clear();
_blocks.clear();
_inlines.clear();
_linkHandlers.clear();
_blocks.add(new _BlockElement(null));
for (md.Node node in nodes) {
assert(_blocks.length == 1);
node.accept(this);
}
assert(_inlines.isEmpty);
return _blocks.single.children;
}
@override
void visitText(md.Text text) {
if (_blocks.last.tag == null) // Don't allow text directly under the root.
return;
_addParentInlineIfNeeded(_blocks.last.tag);
final TextSpan span = _blocks.last.tag == 'pre'
? delegate.formatText(styleSheet, text.text)
: new TextSpan(
style: _inlines.last.style,
text: text.text,
recognizer: _linkHandlers.isNotEmpty ? _linkHandlers.last : null,
);
_inlines.last.children.add(new RichText(
textScaleFactor: styleSheet.textScaleFactor,
text: span,
));
}
@override
bool visitElementBefore(md.Element element) {
// print("visitElementBefore ${element.tag}");
final String tag = element.tag;
if (_isBlockTag(tag)) {
_addAnonymousBlockIfNeeded(styleSheet.styles[tag]);
if (_isListTag(tag))
_listIndents.add(tag);
_blocks.add(new _BlockElement(tag));
} else {
_addParentInlineIfNeeded(_blocks.last.tag);
TextStyle parentStyle = _inlines.last.style;
_inlines.add(new _InlineElement(
tag,
style: parentStyle.merge(styleSheet.styles[tag]),
));
}
if (tag == 'a') {
_linkHandlers.add(delegate.createLink(element.attributes['href']));
}
return true;
}
@override
void visitElementAfter(md.Element element) {
final String tag = element.tag;
if (_isBlockTag(tag)) {
_addAnonymousBlockIfNeeded(styleSheet.styles[tag]);
final _BlockElement current = _blocks.removeLast();
Widget child;
if (current.children.isNotEmpty) {
child = new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: current.children,
);
} else {
child = const SizedBox();
}
if (_isListTag(tag)) {
assert(_listIndents.isNotEmpty);
_listIndents.removeLast();
} else if (tag == 'li') {
if (_listIndents.isNotEmpty) {
child = new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new SizedBox(
width: styleSheet.listIndent,
child: _buildBullet(_listIndents.last),
),
new Expanded(child: child)
],
);
}
} else if (tag == 'blockquote') {
child = new DecoratedBox(
decoration: styleSheet.blockquoteDecoration,
child: new Padding(
padding: new EdgeInsets.all(styleSheet.blockquotePadding),
child: child,
),
);
} else if (tag == 'pre') {
child = new DecoratedBox(
decoration: styleSheet.codeblockDecoration,
child: new Padding(
padding: new EdgeInsets.all(styleSheet.codeblockPadding),
child: child,
),
);
} else if (tag == 'hr') {
child = new DecoratedBox(
decoration: styleSheet.horizontalRuleDecoration,
child: child,
);
}
_addBlockChild(child);
} else {
final _InlineElement current = _inlines.removeLast();
final _InlineElement parent = _inlines.last;
if (tag == 'img') {
// create an image widget for this image
current.children.add(_buildImage(element.attributes['src']));
} else if (tag == 'a') {
_linkHandlers.removeLast();
} else if (tag == 'demo') {
current.children.add(_buildGoDemos(element.attributes));
}
if (current.children.isNotEmpty) {
parent.children.addAll(current.children);
}
}
}
Widget _buildGoDemos(Map<String, dynamic> attrs) {
Widget targetGoDemos;
if (demoParser != null) {
targetGoDemos = demoParser(attrs);
}
return targetGoDemos ?? new Text('demo not exits');
}
Widget _buildImage(String src) {
final List<String> parts = src.split('#');
if (parts.isEmpty)
return const SizedBox();
final String path = parts.first;
double width;
double height;
if (parts.length == 2) {
final List<String> dimensions = parts.last.split('x');
if (dimensions.length == 2) {
width = double.parse(dimensions[0]);
height = double.parse(dimensions[1]);
}
}
Uri uri = Uri.parse(path);
Widget child;
if (uri.scheme == 'http' || uri.scheme == 'https') {
child = new Image.network(uri.toString(), width: width, height: height);
} else if (uri.scheme == 'data') {
child = _handleDataSchemeUri(uri, width, height);
} else if (uri.scheme == "resource") {
child = new Image.asset(path.substring(9), width: width, height: height);
} else {
String filePath = (imageDirectory == null
? uri.toFilePath()
: p.join(imageDirectory.path, uri.toFilePath()));
child = new Image.file(new File(filePath), width: width, height: height);
}
if (_linkHandlers.isNotEmpty) {
TapGestureRecognizer recognizer = _linkHandlers.last;
return new GestureDetector(child: child, onTap: recognizer.onTap);
} else {
return child;
}
}
Widget _handleDataSchemeUri(Uri uri, final double width, final double height) {
final String mimeType = uri.data.mimeType;
if (mimeType.startsWith('image/')) {
return new Image.memory(uri.data.contentAsBytes(), width: width, height: height);
} else if (mimeType.startsWith('text/')) {
return new Text(uri.data.contentAsString());
}
return const SizedBox();
}
Widget _buildBullet(String listTag) {
if (listTag == 'ul')
return new Text('', textAlign: TextAlign.center, style: styleSheet.styles['li']);
final int index = _blocks.last.nextListIndex;
return new Padding(
padding: const EdgeInsets.only(right: 5.0),
child: new Text('${index + 1}.', textAlign: TextAlign.right, style: styleSheet.styles['li']),
);
}
void _addParentInlineIfNeeded(String tag) {
if (_inlines.isEmpty) {
_inlines.add(new _InlineElement(
tag,
style: styleSheet.styles[tag],
));
}
}
void _addBlockChild(Widget child) {
final _BlockElement parent = _blocks.last;
if (parent.children.isNotEmpty)
parent.children.add(new SizedBox(height: styleSheet.blockSpacing));
parent.children.add(child);
parent.nextListIndex += 1;
}
void _addAnonymousBlockIfNeeded(TextStyle style) {
if (_inlines.isEmpty) {
return;
}
final _InlineElement inline = _inlines.single;
if (inline.children.isNotEmpty) {
List<Widget> mergedInlines = _mergeInlineChildren(inline);
final Wrap wrap = new Wrap(children: mergedInlines);
_addBlockChild(wrap);
_inlines.clear();
}
}
/// Merges adjacent [TextSpan] children of the given [_InlineElement]
List<Widget> _mergeInlineChildren(_InlineElement inline) {
List<Widget> mergedTexts = <Widget>[];
for (Widget child in inline.children) {
if (mergedTexts.isNotEmpty && mergedTexts.last is RichText && child is RichText) {
RichText previous = mergedTexts.removeLast();
List<TextSpan> children = previous.text.children != null
? new List.from(previous.text.children)
: [previous.text];
children.add(child.text);
TextSpan mergedSpan = new TextSpan(children: children);
mergedTexts.add(new RichText(
textScaleFactor: styleSheet.textScaleFactor,
text: mergedSpan,
));
} else {
mergedTexts.add(child);
}
}
return mergedTexts;
}
}

View File

@ -1,307 +0,0 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
/// Defines which [TextStyle] objects to use for which Markdown elements.
class MarkdownStyleSheet {
/// Creates an explicit mapping of [TextStyle] objects to Markdown elements.
MarkdownStyleSheet({
this.a,
this.p,
this.code,
this.h1,
this.h2,
this.h3,
this.h4,
this.h5,
this.h6,
this.em,
this.strong,
this.blockquote,
this.img,
this.blockSpacing,
this.listIndent,
this.blockquotePadding,
this.blockquoteDecoration,
this.codeblockPadding,
this.codeblockDecoration,
this.horizontalRuleDecoration,
this.textScaleFactor = 1.0
}) : _styles = <String, TextStyle>{
'a': a,
'p': p,
'li': p,
'code': code,
'pre': p,
'h1': h1,
'h2': h2,
'h3': h3,
'h4': h4,
'h5': h5,
'h6': h6,
'em': em,
'strong': strong,
'blockquote': blockquote,
'img': img,
};
/// Creates a [MarkdownStyleSheet] from the [TextStyle]s in the provided [ThemeData].
factory MarkdownStyleSheet.fromTheme(ThemeData theme) {
assert(theme?.textTheme?.body1?.fontSize != null);
return new MarkdownStyleSheet(
a: const TextStyle(color: Colors.blue),
p: theme.textTheme.body1,
code: new TextStyle(
color: Colors.grey.shade700,
fontFamily: "monospace",
fontSize: theme.textTheme.body1.fontSize * 0.85
),
h1: theme.textTheme.headline,
h2: theme.textTheme.title,
h3: theme.textTheme.subhead,
h4: theme.textTheme.body2,
h5: theme.textTheme.body2,
h6: theme.textTheme.body2,
em: const TextStyle(fontStyle: FontStyle.italic),
strong: const TextStyle(fontWeight: FontWeight.bold),
blockquote: theme.textTheme.body1,
img: theme.textTheme.body1,
blockSpacing: 8.0,
listIndent: 32.0,
blockquotePadding: 8.0,
blockquoteDecoration: new BoxDecoration(
color: Colors.blue.shade100,
borderRadius: new BorderRadius.circular(2.0)
),
codeblockPadding: 8.0,
codeblockDecoration: new BoxDecoration(
color: Colors.grey.shade100,
borderRadius: new BorderRadius.circular(2.0)
),
horizontalRuleDecoration: new BoxDecoration(
border: new Border(
top: new BorderSide(width: 5.0, color: Colors.grey.shade300)
),
),
);
}
/// Creates a [MarkdownStyle] from the [TextStyle]s in the provided [ThemeData].
///
/// This constructor uses larger fonts for the headings than in
/// [MarkdownStyle.fromTheme].
factory MarkdownStyleSheet.largeFromTheme(ThemeData theme) {
return new MarkdownStyleSheet(
a: const TextStyle(color: Colors.blue),
p: theme.textTheme.body1,
code: new TextStyle(
color: Colors.grey.shade700,
fontFamily: "monospace",
fontSize: theme.textTheme.body1.fontSize * 0.85
),
h1: theme.textTheme.display3,
h2: theme.textTheme.display2,
h3: theme.textTheme.display1,
h4: theme.textTheme.headline,
h5: theme.textTheme.title,
h6: theme.textTheme.subhead,
em: const TextStyle(fontStyle: FontStyle.italic),
strong: const TextStyle(fontWeight: FontWeight.bold),
blockquote: theme.textTheme.body1,
img: theme.textTheme.body1,
blockSpacing: 8.0,
listIndent: 32.0,
blockquotePadding: 8.0,
blockquoteDecoration: new BoxDecoration(
color: Colors.blue.shade100,
borderRadius: new BorderRadius.circular(2.0)
),
codeblockPadding: 8.0,
codeblockDecoration: new BoxDecoration(
color: Colors.grey.shade100,
borderRadius: new BorderRadius.circular(2.0)
),
horizontalRuleDecoration: new BoxDecoration(
border: new Border(
top: new BorderSide(width: 5.0, color: Colors.grey.shade300)
),
),
);
}
/// Creates a new [MarkdownStyleSheet] based on the current style, with the
/// provided parameters overridden.
MarkdownStyleSheet copyWith({
TextStyle a,
TextStyle p,
TextStyle code,
TextStyle h1,
TextStyle h2,
TextStyle h3,
TextStyle h4,
TextStyle h5,
TextStyle h6,
TextStyle em,
TextStyle strong,
TextStyle blockquote,
TextStyle img,
double blockSpacing,
double listIndent,
double blockquotePadding,
Decoration blockquoteDecoration,
double codeblockPadding,
Decoration codeblockDecoration,
Decoration horizontalRuleDecoration,
double textScaleFactor,
}) {
return new MarkdownStyleSheet(
a: a ?? this.a,
p: p ?? this.p,
code: code ?? this.code,
h1: h1 ?? this.h1,
h2: h2 ?? this.h2,
h3: h3 ?? this.h3,
h4: h4 ?? this.h4,
h5: h5 ?? this.h5,
h6: h6 ?? this.h6,
em: em ?? this.em,
strong: strong ?? this.strong,
blockquote: blockquote ?? this.blockquote,
img: img ?? this.img,
blockSpacing: blockSpacing ?? this.blockSpacing,
listIndent: listIndent ?? this.listIndent,
blockquotePadding: blockquotePadding ?? this.blockquotePadding,
blockquoteDecoration: blockquoteDecoration ?? this.blockquoteDecoration,
codeblockPadding: codeblockPadding ?? this.codeblockPadding,
codeblockDecoration: codeblockDecoration ?? this.codeblockDecoration,
horizontalRuleDecoration: horizontalRuleDecoration ?? this.horizontalRuleDecoration,
textScaleFactor : textScaleFactor ?? this.textScaleFactor,
);
}
/// The [TextStyle] to use for `a` elements.
final TextStyle a;
/// The [TextStyle] to use for `p` elements.
final TextStyle p;
/// The [TextStyle] to use for `code` elements.
final TextStyle code;
/// The [TextStyle] to use for `h1` elements.
final TextStyle h1;
/// The [TextStyle] to use for `h2` elements.
final TextStyle h2;
/// The [TextStyle] to use for `h3` elements.
final TextStyle h3;
/// The [TextStyle] to use for `h4` elements.
final TextStyle h4;
/// The [TextStyle] to use for `h5` elements.
final TextStyle h5;
/// The [TextStyle] to use for `h6` elements.
final TextStyle h6;
/// The [TextStyle] to use for `em` elements.
final TextStyle em;
/// The [TextStyle] to use for `strong` elements.
final TextStyle strong;
/// The [TextStyle] to use for `blockquote` elements.
final TextStyle blockquote;
/// The [TextStyle] to use for `img` elements.
final TextStyle img;
/// The amount of vertical space to use between block-level elements.
final double blockSpacing;
/// The amount of horizontal space to indent list items.
final double listIndent;
/// The padding to use for `blockquote` elements.
final double blockquotePadding;
/// The decoration to use behind `blockquote` elements.
final Decoration blockquoteDecoration;
/// The padding to use for `pre` elements.
final double codeblockPadding;
/// The decoration to use behind for `pre` elements.
final Decoration codeblockDecoration;
/// The decoration to use for `hr` elements.
final Decoration horizontalRuleDecoration;
// The text scale factor to use in textual elements
final double textScaleFactor;
/// A [Map] from element name to the corresponding [TextStyle] object.
Map<String, TextStyle> get styles => _styles;
Map<String, TextStyle> _styles;
@override
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other.runtimeType != MarkdownStyleSheet)
return false;
final MarkdownStyleSheet typedOther = other;
return typedOther.a == a
&& typedOther.p == p
&& typedOther.code == code
&& typedOther.h1 == h1
&& typedOther.h2 == h2
&& typedOther.h3 == h3
&& typedOther.h4 == h4
&& typedOther.h5 == h5
&& typedOther.h6 == h6
&& typedOther.em == em
&& typedOther.strong == strong
&& typedOther.blockquote == blockquote
&& typedOther.img == img
&& typedOther.blockSpacing == blockSpacing
&& typedOther.listIndent == listIndent
&& typedOther.blockquotePadding == blockquotePadding
&& typedOther.blockquoteDecoration == blockquoteDecoration
&& typedOther.codeblockPadding == codeblockPadding
&& typedOther.codeblockDecoration == codeblockDecoration
&& typedOther.horizontalRuleDecoration == horizontalRuleDecoration
&& typedOther.textScaleFactor == textScaleFactor;
}
@override
int get hashCode {
return hashList([
a,
p,
code,
h1,
h2,
h3,
h4,
h5,
h6,
em,
strong,
blockquote,
img,
blockSpacing,
listIndent,
blockquotePadding,
blockquoteDecoration,
codeblockPadding,
codeblockDecoration,
horizontalRuleDecoration,
textScaleFactor,
]);
}
}

View File

@ -1,247 +0,0 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:meta/meta.dart';
import 'builder.dart';
import 'style_sheet.dart';
//
typedef Widget ItemDemoBuilder(Map<String, dynamic> attrs);
/// Signature for callbacks used by [MarkdownWidget] when the user taps a link.
///
/// Used by [MarkdownWidget.onTapLink].
typedef void MarkdownTapLinkCallback(String href);
/// Creates a format [TextSpan] given a string.
///
/// Used by [MarkdownWidget] to highlight the contents of `pre` elements.
abstract class SyntaxHighlighter { // ignore: one_member_abstracts
/// Returns the formated [TextSpan] for the given string.
TextSpan format(String source);
}
/// A base class for widgets that parse and display Markdown.
///
/// Supports all standard Markdown from the original
/// [Markdown specification](https://daringfireball.net/projects/markdown/).
///
/// See also:
///
/// * [Markdown], which is a scrolling container of Markdown.
/// * [MarkdownBody], which is a non-scrolling container of Markdown.
/// * <https://daringfireball.net/projects/markdown/>
abstract class MarkdownWidget extends StatefulWidget {
/// Creates a widget that parses and displays Markdown.
///
/// The [data] argument must not be null.
const MarkdownWidget({
Key key,
@required this.data,
this.styleSheet,
this.syntaxHighlighter,
this.onTapLink,
this.imageDirectory,
this.demoBuilder,
}) : assert(data != null),
super(key: key);
/// The Markdown to display.
final String data;
/// The styles to use when displaying the Markdown.
///
/// If null, the styles are inferred from the current [Theme].
final MarkdownStyleSheet styleSheet;
/// The syntax highlighter used to color text in `pre` elements.
///
/// If null, the [MarkdownStyleSheet.code] style is used for `pre` elements.
final SyntaxHighlighter syntaxHighlighter;
/// Called when the user taps a link.
final MarkdownTapLinkCallback onTapLink;
/// The base directory holding images referenced by Img tags with local file paths.
final Directory imageDirectory;
final ItemDemoBuilder demoBuilder;
/// Subclasses should override this function to display the given children,
/// which are the parsed representation of [data].
@protected
Widget build(BuildContext context, List<Widget> children);
@override
_MarkdownWidgetState createState() => new _MarkdownWidgetState();
}
class DemosSyntax extends md.InlineSyntax {
DemosSyntax() : super('\\[demo:([a-z0-9_+-]+)\\]');
bool onMatch(parser, match) {
var anchor = new md.Element.empty('demo');
anchor.attributes['id'] = match[1];
parser.addNode(anchor);
return true;
}
}
class _MarkdownWidgetState extends State<MarkdownWidget> implements MarkdownBuilderDelegate {
List<Widget> _children;
final List<GestureRecognizer> _recognizers = <GestureRecognizer>[];
@override
void didChangeDependencies() {
_parseMarkdown();
super.didChangeDependencies();
}
@override
void didUpdateWidget(MarkdownWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.data != oldWidget.data
|| widget.styleSheet != oldWidget.styleSheet)
_parseMarkdown();
}
@override
void dispose() {
_disposeRecognizers();
super.dispose();
}
void _parseMarkdown() {
final MarkdownStyleSheet styleSheet = widget.styleSheet ?? new MarkdownStyleSheet.fromTheme(Theme.of(context));
_disposeRecognizers();
// TODO: This can be optimized by doing the split and removing \r at the same time
final List<String> lines = widget.data.replaceAll('\r\n', '\n').split('\n');
final md.ExtensionSet extens = new md.ExtensionSet([
md.FencedCodeBlockSyntax()
], [
new DemosSyntax(),
new md.InlineHtmlSyntax(),
]);
final md.Document document = new md.Document(encodeHtml: false, extensionSet: extens);
final MarkdownBuilder builder = new MarkdownBuilder(
delegate: this,
styleSheet: styleSheet,
imageDirectory: widget.imageDirectory,
demoParser: widget.demoBuilder
);
_children = builder.build(document.parseLines(lines));
}
void _disposeRecognizers() {
if (_recognizers.isEmpty)
return;
final List<GestureRecognizer> localRecognizers = new List<GestureRecognizer>.from(_recognizers);
_recognizers.clear();
for (GestureRecognizer recognizer in localRecognizers)
recognizer.dispose();
}
@override
GestureRecognizer createLink(String href) {
final TapGestureRecognizer recognizer = new TapGestureRecognizer()
..onTap = () {
if (widget.onTapLink != null)
widget.onTapLink(href);
};
_recognizers.add(recognizer);
return recognizer;
}
@override
TextSpan formatText(MarkdownStyleSheet styleSheet, String code) {
if (widget.syntaxHighlighter != null)
return widget.syntaxHighlighter.format(code);
return new TextSpan(style: styleSheet.code, text: code);
}
@override
Widget build(BuildContext context) => widget.build(context, _children);
}
/// A non-scrolling widget that parses and displays Markdown.
///
/// Supports all standard Markdown from the original
/// [Markdown specification](https://daringfireball.net/projects/markdown/).
///
/// See also:
///
/// * [Markdown], which is a scrolling container of Markdown.
/// * <https://daringfireball.net/projects/markdown/>
class MarkdownBody extends MarkdownWidget {
/// Creates a non-scrolling widget that parses and displays Markdown.
const MarkdownBody({
Key key,
String data,
MarkdownStyleSheet styleSheet,
SyntaxHighlighter syntaxHighlighter,
MarkdownTapLinkCallback onTapLink,
Directory imageDirectory,
ItemDemoBuilder demoBuilder,
}) : super(
key: key,
data: data,
styleSheet: styleSheet,
syntaxHighlighter: syntaxHighlighter,
onTapLink: onTapLink,
imageDirectory: imageDirectory,
demoBuilder: demoBuilder
);
@override
Widget build(BuildContext context, List<Widget> children) {
if (children.length == 1)
return children.single;
return new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
);
}
}
/// A scrolling widget that parses and displays Markdown.
///
/// Supports all standard Markdown from the original
/// [Markdown specification](https://daringfireball.net/projects/markdown/).
///
/// See also:
///
/// * [MarkdownBody], which is a non-scrolling container of Markdown.
/// * <https://daringfireball.net/projects/markdown/>
class Markdown extends MarkdownWidget {
/// Creates a scrolling widget that parses and displays Markdown.
const Markdown({
Key key,
String data,
MarkdownStyleSheet styleSheet,
SyntaxHighlighter syntaxHighlighter,
MarkdownTapLinkCallback onTapLink,
Directory imageDirectory,
this.padding: const EdgeInsets.all(16.0),
}) : super(
key: key,
data: data,
styleSheet: styleSheet,
syntaxHighlighter: syntaxHighlighter,
onTapLink: onTapLink,
imageDirectory: imageDirectory,
);
/// The amount of space by which to inset the children.
final EdgeInsets padding;
@override
Widget build(BuildContext context, List<Widget> children) {
return new ListView(padding: padding, children: children);
}
}

View File

@ -9,10 +9,9 @@ import 'package:flutter_go/utils/example_code_parser.dart';
import 'package:flutter_go/utils/syntax_highlighter.dart';
class FullScreenCodeDialog extends StatefulWidget {
const FullScreenCodeDialog({this.filePath, this.remoteFilePath});
const FullScreenCodeDialog({this.filePath});
final String filePath;
final String remoteFilePath;
_FullScreenCodeDialogState createState() => _FullScreenCodeDialogState();
}

View File

@ -174,7 +174,6 @@ class _ListRefreshState extends State<ListRefresh> {
return widget.renderItem(index, items[index]);
}
}
return null;
},
controller: _scrollController,
),

View File

@ -1,94 +0,0 @@
//
// Created with Android Studio.
// User: 三帆
// Date: 07/08/2019
// Time: 08:40
// email: sanfan.hx@alibaba-inc.com
// tartget: 代码获取自: https://blog.csdn.net/O_time/article/details/86496537
//
import 'dart:async';
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class NetLoadingDialog extends StatefulWidget {
String loadingText;
bool outsideDismiss;
bool loading;
Function dismissCallback;
Future<dynamic> requestCallBack;
NetLoadingDialog(
{Key key,
this.loadingText = "loading...",
this.outsideDismiss = true,
this.dismissCallback,
this.loading,
this.requestCallBack})
: super(key: key);
@override
State<NetLoadingDialog> createState() => _LoadingDialog();
}
class _LoadingDialog extends State<NetLoadingDialog> {
_dismissDialog() {
if (widget.dismissCallback != null) {
widget.dismissCallback();
}
Navigator.of(context).pop();
}
@override
void initState() {
super.initState();
if (widget.requestCallBack != null) {
widget.requestCallBack.then((_) {
Navigator.pop(context);
});
}
}
@override
Widget build(BuildContext context) {
if (!widget.loading) {
return Container();
}
return new GestureDetector(
onTap: widget.outsideDismiss ? _dismissDialog : null,
child: Material(
type: MaterialType.transparency,
child: new Center(
child: new SizedBox(
width: 120.0,
height: 120.0,
child: new Container(
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
),
),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new CircularProgressIndicator(),
new Padding(
padding: const EdgeInsets.only(
top: 20.0,
),
child: new Text(
widget.loadingText,
style: new TextStyle(fontSize: 12.0),
),
),
],
),
),
),
),
),
);
}
}

View File

@ -1,4 +1,4 @@
import '../components/flutter_markdown/lib/flutter_markdown.dart' as md;
import 'package:flutter_markdown/flutter_markdown.dart' as md;
import 'package:flutter/material.dart';
import 'package:flutter_go/utils/high_light_code.dart';

View File

@ -1,47 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_go/event/event_bus.dart';
import 'package:flutter_go/event/event_model.dart';
// import 'package:event_bus/event_bus.dart';
class SingleThemeColor extends StatelessWidget {
final int themeColor;
final String coloeName;
const SingleThemeColor({Key key, this.themeColor, this.coloeName})
: super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
onTap: (){
if(ApplicationEvent.event != null){
print('fire ${this.themeColor}');
ApplicationEvent.event.fire(UserSettingThemeColorEvent(this.themeColor));
Navigator.of(context).pop();
}
},
child: Column(
children: <Widget>[
Container(
width: 50,
height: 50,
margin: const EdgeInsets.all(5.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
color: Color(this.themeColor),
),
),
Text(
this.coloeName,
style: TextStyle(
color: Color(this.themeColor),
fontSize: 14.0,
),
)
],
),
);
}
}

View File

@ -4,7 +4,6 @@
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:flutter_go/utils/data_utils.dart';
import '../routers/application.dart';
import '../routers/routers.dart';
@ -25,8 +24,8 @@ class WidgetDemo extends StatefulWidget {
{Key key,
@required this.title,
@required this.contentList,
this.codeUrl,
this.docUrl,
@required this.codeUrl,
@required this.docUrl,
this.bottomNaviBar})
: super(key: key);
@ -38,7 +37,7 @@ class _WidgetDemoState extends State<WidgetDemo> {
CollectionControlModel _collectionControl = new CollectionControlModel();
var _collectionIcons;
List widgetDemosList = new WidgetDemoList().getDemos();
String widgetType = 'old';
String _router = '';
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
List<Widget> _buildContent() {
@ -65,67 +64,56 @@ class _WidgetDemoState extends State<WidgetDemo> {
@override
void initState() {
super.initState();
// 这里不能直接 使用 ` ModalRoute.of(context)` 会产生报错
Future.delayed(Duration.zero, () {
String currentPath = ModalRoute.of(context).settings.name;
if (currentPath.indexOf('/standard-page') == 0) {
widgetType = 'standard';
}
Map<String, String> params = {
'type': widgetType,
"url": currentPath,
"name": widget.title
};
DataUtils.checkCollected(params).then((result) {
if (this.mounted) {
setState(() {
_hasCollected = result;
});
_collectionControl.getRouterByName(widget.title).then((list) {
widgetDemosList.forEach((item) {
if (item.name == widget.title) {
_router = item.routerName;
}
});
if (this.mounted) {
setState(() {
_hasCollected = list.length > 0;
});
}
});
}
// 点击收藏按钮
_getCollection() {
String currentRouterPath = ModalRoute.of(context).settings.name;
Map<String, String> params = {
"type": widgetType,
"url": currentRouterPath,
"name": widget.title
};
if (_hasCollected) {
// 删除操作
DataUtils.removeCollected(params, context).then((result) {
if (result) {
_collectionControl.deleteByName(widget.title).then((result) {
if (result > 0 && this.mounted) {
setState(() {
_hasCollected = false;
});
_scaffoldKey.currentState
.showSnackBar(SnackBar(content: Text('已取消收藏')));
if (ApplicationEvent.event != null) {
ApplicationEvent.event
.fire(CollectionEvent(widget.title, currentRouterPath, true));
}
if (this.mounted) {
setState(() {
_hasCollected = false;
});
.fire(CollectionEvent(widget.title, _router, true));
}
return;
}
print('删除错误');
});
} else {
// 插入操作
DataUtils.addCollected(params, context).then((result) {
if (result) {
if (this.mounted) {
setState(() {
_hasCollected = true;
});
}
_scaffoldKey.currentState
.showSnackBar(SnackBar(content: Text('收藏成功')));
_collectionControl
.insert(Collection(name: widget.title, router: _router))
.then((result) {
if (this.mounted) {
setState(() {
_hasCollected = true;
});
if (ApplicationEvent.event != null) {
ApplicationEvent.event
.fire(CollectionEvent(widget.title, currentRouterPath, false));
.fire(CollectionEvent(widget.title, _router, false));
}
_scaffoldKey.currentState
.showSnackBar(SnackBar(content: Text('收藏成功')));
}
});
}
@ -141,38 +129,7 @@ class _WidgetDemoState extends State<WidgetDemo> {
'${Routes.codeView}?filePath=${Uri.encodeComponent(widget.codeUrl)}');
}
}
List<PopupMenuEntry<String>> buildPopupMenu() {
List<PopupMenuEntry<String>> comps = [];
if (widget.docUrl != null) {
comps.add(
PopupMenuItem<String>(
value: 'doc',
child: ListTile(
leading: Icon(
Icons.library_books,
size: 22.0,
),
title: Text('查看文档'),
),
)
);
}
if (widget.codeUrl != null) {
comps.add(
PopupMenuItem<String>(
value: 'code',
child: ListTile(
leading: Icon(
Icons.code,
size: 22.0,
),
title: Text('查看Demo'),
),
)
);
}
return comps;
}
@override
Widget build(BuildContext context) {
if (_hasCollected) {
@ -180,34 +137,50 @@ class _WidgetDemoState extends State<WidgetDemo> {
} else {
_collectionIcons = Icons.favorite_border;
}
List<PopupMenuEntry<String>> menus = buildPopupMenu();
List<Widget> actions = [
new IconButton(
tooltip: 'goBack home',
onPressed: () {
Navigator.popUntil(context, ModalRoute.withName('/'));
},
icon: Icon(Icons.home),
),
new IconButton(
tooltip: 'collection',
onPressed: _getCollection,
icon: Icon(_collectionIcons),
),
];
if (menus.length > 0) {
actions.add(
PopupMenuButton<String>(
onSelected: _selectValue,
itemBuilder: (BuildContext context) => menus,
)
);
}
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text(widget.title),
actions: actions,
actions: <Widget>[
new IconButton(
tooltip: 'goBack home',
onPressed: () {
Navigator.popUntil(context, ModalRoute.withName('/'));
},
icon: Icon(Icons.home),
),
new IconButton(
tooltip: 'collection',
onPressed: _getCollection,
icon: Icon(_collectionIcons),
),
PopupMenuButton<String>(
onSelected: _selectValue,
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: 'doc',
child: ListTile(
leading: Icon(
Icons.library_books,
size: 22.0,
),
title: Text('查看文档'),
),
),
const PopupMenuDivider(),
const PopupMenuItem<String>(
value: 'code',
child: ListTile(
leading: Icon(
Icons.code,
size: 22.0,
),
title: Text('查看Demo'),
),
),
],
),
],
),
body: Container(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),

View File

@ -3,89 +3,56 @@ import 'package:fluro/fluro.dart';
import './widget_item.dart';
import '../routers/application.dart';
import '../widgets/index.dart';
import '../model/widget.dart';
class WidgetItemContainer extends StatelessWidget {
final int columnCount; //一行几个
final List<CommonItem> commonItems;
// final bool isWidgetPoint;
final List<dynamic> categories;
final bool isWidgetPoint;
// 所有的可用demos;
final List widgetDemosList = new WidgetDemoList().getDemos();
WidgetItemContainer(
{Key key,
@required this.commonItems,
@required this.categories,
@required this.columnCount,
// @required this.isWidgetPoint
})
@required this.isWidgetPoint})
: super(key: key);
/// 跳转goup
void tapToGroup(CategoryComponent cate, BuildContext context) {
Application.router
.navigateTo(context, "/category/${cate.token}", transition: TransitionType.inFromRight);
}
/// 跳转到老的widget界面
void tapToOldWidget(WidgetLeaf leaf, BuildContext context) {
String targetName = leaf.name;
String targetRouter = '/category/error/404';
widgetDemosList.forEach((item) {
if (item.name == targetName) {
targetRouter = item.routerName;
}
});
Application.router.navigateTo(context, targetRouter, transition: TransitionType.inFromRight);
}
/// 跳转到新的标准页
void tapToStandardPage(WidgetLeaf leaf, BuildContext context) {
String targetRouter = '/standard-page/${leaf.pageId}';
Application.router.navigateTo(context, targetRouter, transition: TransitionType.inFromRight);
}
List<Widget> _buildColumns(context) {
List<Widget> _listWidget = [];
List<Widget> _listRows = [];
int addI;
for (int i = 0, length = commonItems.length; i < length; i += columnCount) {
for (int i = 0, length = categories.length; i < length; i += columnCount) {
_listRows = [];
for (int innerI = 0; innerI < columnCount; innerI++) {
addI = innerI + i;
if (addI < length) {
CommonItem item = commonItems[addI];
dynamic item = categories[addI];
_listRows.add(
Expanded(
flex: 1,
child: WidgetItem(
title: item.name,
onTap: () {
String type = item.type;
if (type == "category") {
return tapToGroup(item as CategoryComponent, context);
if (isWidgetPoint) {
String targetName = item.name;
String targetRouter = '/category/error/404';
widgetDemosList.forEach((item) {
if (item.name == targetName) {
targetRouter = item.routerName;
}
});
Application.router.navigateTo(context, "$targetRouter", transition: TransitionType.inFromRight);
} else {
Application.router
.navigateTo(context, "/category/${item.name}", transition: TransitionType.inFromRight);
}
if (type == "widget") {
WidgetLeaf leaf = item as WidgetLeaf;
if (leaf.display == "standard") {
return tapToStandardPage(leaf, context);
} else {
return tapToOldWidget(leaf, context);
}
}
Application.router
.navigateTo(context, "/category/error/404", transition: TransitionType.inFromRight);
},
index: addI,
totalCount: length,
rowLength: columnCount,
textSize: true ? 'middle' : 'small',
textSize: isWidgetPoint ? 'middle' : 'small',
),
),
);
@ -114,4 +81,3 @@ class WidgetItemContainer extends StatelessWidget {
);
}
}

View File

@ -2,4 +2,4 @@ import 'package:event_bus/event_bus.dart';
class ApplicationEvent{
static EventBus event;
}
}

View File

@ -4,16 +4,4 @@ class CollectionEvent{
final bool isRemove;
// token uid...
CollectionEvent(this.widgetName,this.router,this.isRemove);
}
class UserGithubOAuthEvent{
final String loginName;
final String token;
final bool isSuccess;
UserGithubOAuthEvent(this.loginName,this.token,this.isSuccess);
}
class UserSettingThemeColorEvent{
final int settingThemeColor;
UserSettingThemeColorEvent(this.settingThemeColor);
}

View File

@ -11,23 +11,19 @@ import 'package:flutter_go/model/search_history.dart';
import 'package:flutter_go/utils/analytics.dart' as Analytics;
import 'package:flutter_go/views/login_page/login_page.dart';
import 'package:flutter_go/utils/data_utils.dart';
import 'package:flutter_go/model/user_info.dart';
import 'package:flutter_jpush/flutter_jpush.dart';
import 'package:flutter_go/event/event_bus.dart';
import 'package:flutter_go/event/event_model.dart';
import 'package:event_bus/event_bus.dart';
import 'package:flutter_go/model/widget.dart';
import 'package:flutter_go/standard_pages/index.dart';
//import 'views/welcome_page/index.dart';
const int ThemeColor = 0xFFC91B3A;
SpUtil sp;
var db;
class MyApp extends StatefulWidget {
MyApp() {
final router = new Router();
Routes.configureRoutes(router);
// 这里设置项目环境
Application.router = router;
}
@ -38,105 +34,28 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> {
bool _hasLogin = false;
bool _isLoading = true;
UserInformation _userInfo;
bool isConnected = false;
String registrationId;
List notificationList = [];
int themeColor = 0xFFC91B3A;
_MyAppState() {
final eventBus = new EventBus();
ApplicationEvent.event = eventBus;
}
@override
void initState() {
super.initState();
_startupJpush();
FlutterJPush.addConnectionChangeListener((bool connected) {
setState(() {
/// 是否连接,连接了才可以推送
print("连接状态改变:$connected");
this.isConnected = connected;
if (connected) {
//在启动的时候会去连接自己的服务器,连接并注册成功之后会返回一个唯一的设备号
try {
FlutterJPush.getRegistrationID().then((String regId) {
print("主动获取设备号:$regId");
setState(() {
this.registrationId = regId;
});
});
} catch (error) {
print('主动获取设备号Error:$error');
}
;
}
});
});
FlutterJPush.addReceiveNotificationListener(
(JPushNotification notification) {
setState(() {
/// 收到推送
print("收到推送提醒: $notification");
notificationList.add(notification);
});
});
FlutterJPush.addReceiveOpenNotificationListener(
(JPushNotification notification) {
setState(() {
print("打开了推送提醒: $notification");
/// 打开了推送提醒
notificationList.add(notification);
});
});
FlutterJPush.addReceiveCustomMsgListener((JPushMessage msg) {
setState(() {
print("收到推送消息提醒: $msg");
/// 打开了推送提醒
notificationList.add(msg);
});
});
DataUtils.checkLogin().then((hasLogin) {
if (hasLogin.runtimeType == UserInformation) {
setState(() {
_hasLogin = true;
_isLoading = false;
_userInfo = hasLogin;
// 设置初始化的主题色
// if (hasLogin.themeColor != 'default') {
// themeColor = int.parse(hasLogin.themeColor);
// }
});
} else {
setState(() {
_hasLogin = hasLogin;
_isLoading = false;
});
}
}).catchError((onError) {
setState(() {
_hasLogin = false;
_hasLogin = hasLogin;
_isLoading = false;
});
}).catchError((onError){
setState(() {
_hasLogin = true;
_isLoading = false;
});
print('身份信息验证失败:$onError');
});
ApplicationEvent.event.on<UserSettingThemeColorEvent>().listen((event) {
print('接收到的 event $event');
});
}
showWelcomePage() {
if (_isLoading) {
return Container(
color: Color(this.themeColor),
color: const Color(ThemeColor),
child: Center(
child: SpinKitPouringHourglass(color: Colors.white),
),
@ -144,7 +63,7 @@ class _MyAppState extends State<MyApp> {
} else {
// 判断是否已经登录
if (_hasLogin) {
return AppPage(_userInfo);
return AppPage();
} else {
return LoginPage();
}
@ -153,11 +72,10 @@ class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
// WidgetTree.getCommonItemByPath([15, 17], Application.widgetTree);
return new MaterialApp(
title: 'titles',
title: 'title',
theme: new ThemeData(
primaryColor: Color(this.themeColor),
primaryColor: Color(ThemeColor),
backgroundColor: Color(0xFFEFEFEF),
accentColor: Color(0xFF888888),
textTheme: TextTheme(
@ -165,7 +83,7 @@ class _MyAppState extends State<MyApp> {
body1: TextStyle(color: Color(0xFF888888), fontSize: 16.0),
),
iconTheme: IconThemeData(
color: Color(this.themeColor),
color: Color(ThemeColor),
size: 35.0,
),
),
@ -177,24 +95,11 @@ class _MyAppState extends State<MyApp> {
}
}
void _startupJpush() async {
print("初始化jpush");
await FlutterJPush.startup();
print("初始化jpush成功");
}
void main() async {
final provider = new Provider();
await provider.init(true);
sp = await SpUtil.getInstance();
new SearchHistoryList(sp);
await DataUtils.getWidgetTreeList().then((List json) {
List data = WidgetTree.insertDevPagesToList(json, StandardPages().getLocalList());
Application.widgetTree = WidgetTree.buildWidgetTree(data);
print("Application.widgetTree>>>> ${Application.widgetTree}");
});
db = Provider.db;
runApp(new MyApp());
}

View File

@ -1,107 +1,107 @@
//
//import 'dart:async';
//
//import 'package:flutter_go/utils/sql.dart';
//
//abstract class CatInterface{
// int get id;
// //类目名称
// String get name;
// //描述
// String get desc;
// //第几级类目,默认 1
// int get depth;
// //父类目id没有为 0
// int get parentId;
//}
//
//class Cat implements CatInterface {
// int id;
// String name;
// String desc;
// int depth;
// int parentId;
//
// Cat({this.id, this.name, this.desc, this.depth, this.parentId});
//
// Cat.fromJSON(Map json)
// : id = json['id'],
// name = json['name'],
// desc = json['desc'],
// depth = json['depth'],
// parentId = json['parentId'];
//
// String toString() {
// return '(Cat $name)';
// }
//
// Map toMap() {
// return {
// 'id': id,
// 'name': name,
// 'desc': desc,
// 'depth': depth,
// 'parentId': parentId
// };
// }
// Map toSqlCondition() {
// Map _map = this.toMap();
// Map condition = {};
// _map.forEach((k, value) {
//
// if (value != null) {
//
// condition[k] = value;
// }
// });
//
// if (condition.isEmpty) {
// return {};
// }
//
// return condition;
// }
//}
//
//
//class CatControlModel{
// final String table = 'cat';
// Sql sql;
// CatControlModel() {
// sql = Sql.setTable(table);
// }
//
// /// 获取一级类目
// Future<List> mainList() async{
// List listJson = await sql.getByCondition(conditions: {'parentId': 0});
// List<Cat> cats = listJson.map((json) {
// return new Cat.fromJSON(json);
// }).toList();
// return cats;
// }
//
// // 获取Cat不同深度与parent的列表
// Future<List<Cat>> getList([Cat cat]) async{
//
//
// if (cat == null) {
// cat = new Cat(depth: 1, parentId: 0);
// }
// // print("cat in getList ${cat.toMap()}");
// List listJson = await sql.getByCondition(conditions: cat.toSqlCondition());
// List<Cat> cats = listJson.map((json) {
// return new Cat.fromJSON(json);
// }).toList();
// return cats;
// }
//
// // 通过name获取Cat对象信息
// Future<Cat> getCatByName(String name) async {
// List json = await sql.getByCondition(conditions: {'name': name});
// if (json.isEmpty) {
// return null;
// }
// return new Cat.fromJSON(json.first);
// }
//
//}
import 'dart:async';
import 'package:flutter_go/utils/sql.dart';
abstract class CatInterface{
int get id;
//类目名称
String get name;
//描述
String get desc;
//第几级类目,默认 1
int get depth;
//父类目id没有为 0
int get parentId;
}
class Cat implements CatInterface {
int id;
String name;
String desc;
int depth;
int parentId;
Cat({this.id, this.name, this.desc, this.depth, this.parentId});
Cat.fromJSON(Map json)
: id = json['id'],
name = json['name'],
desc = json['desc'],
depth = json['depth'],
parentId = json['parentId'];
String toString() {
return '(Cat $name)';
}
Map toMap() {
return {
'id': id,
'name': name,
'desc': desc,
'depth': depth,
'parentId': parentId
};
}
Map toSqlCondition() {
Map _map = this.toMap();
Map condition = {};
_map.forEach((k, value) {
if (value != null) {
condition[k] = value;
}
});
if (condition.isEmpty) {
return {};
}
return condition;
}
}
class CatControlModel{
final String table = 'cat';
Sql sql;
CatControlModel() {
sql = Sql.setTable(table);
}
/// 获取一级类目
Future<List> mainList() async{
List listJson = await sql.getByCondition(conditions: {'parentId': 0});
List<Cat> cats = listJson.map((json) {
return new Cat.fromJSON(json);
}).toList();
return cats;
}
// 获取Cat不同深度与parent的列表
Future<List<Cat>> getList([Cat cat]) async{
if (cat == null) {
cat = new Cat(depth: 1, parentId: 0);
}
// print("cat in getList ${cat.toMap()}");
List listJson = await sql.getByCondition(conditions: cat.toSqlCondition());
List<Cat> cats = listJson.map((json) {
return new Cat.fromJSON(json);
}).toList();
return cats;
}
// 通过name获取Cat对象信息
Future<Cat> getCatByName(String name) async {
List json = await sql.getByCondition(conditions: {'name': name});
if (json.isEmpty) {
return null;
}
return new Cat.fromJSON(json.first);
}
}

View File

@ -49,21 +49,15 @@ class CollectionControlModel {
List list = await sql.getByCondition();
List<Collection> resultList = [];
list.forEach((item){
print('collection item =>> $item');
print(item);
resultList.add(Collection.fromJSON(item));
});
return resultList;
}
/// 通过收藏名获取router
/// 因为名称很容易重复. 所以这里使用path router做唯一判断
// Future getRouterByName(String name) async {
// List list = await sql.getByCondition(conditions: {'name': name});
// return list;
// }
Future getRouterByUrl(String path) async {
List list = await sql.getByCondition(conditions: {'router': path});
// 通过收藏名获取router
Future getRouterByName(String name) async {
List list = await sql.getByCondition(conditions: {'name': name});
return list;
}
@ -71,8 +65,4 @@ class CollectionControlModel {
Future deleteByName(String name) async{
return await sql.delete(name,'name');
}
// 通过path删除
Future deleteByPath(String path) async{
return await sql.delete(path,'router');
}
}

View File

@ -1,25 +0,0 @@
class ResponseData{
int status;
bool success;
String message;
ResponseData(this.status, this.success,this.message);
ResponseData.fromJson(Map<String, dynamic> json)
: status = json['status'],
success = json['success'],
message=json['message'];
Map<String, dynamic> toJson() =>
{
'status': status,
'success': success,
'messsage': message
};
@override
String toString() {
return 'status: $status ,success: $success,message: ${message.toString()}';
}
}

View File

@ -1,32 +1,24 @@
class UserInformation {
class UserInfo {
String username;
int id;
String avatarPic;
String themeColor;
String urlName;
UserInformation({
UserInfo({
this.avatarPic,
this.id,
this.themeColor,
this.urlName,
this.username,
});
factory UserInformation.fromJson(Map<String, dynamic> json) {
print('fromJOSN $json ${json['id'].runtimeType}');
String name = json['name'];
int userId ;
if(json['name'] == null){
name = json['url_name'];
}
if(json['id'].runtimeType == int){
userId = json['id'];
}else{
userId = int.parse(json['id']);
}
return UserInformation(
factory UserInfo.fromJson(Map<String, dynamic> json) {
return UserInfo(
avatarPic: json['avatar_pic'],
id: userId,
username: name,
themeColor: json['theme_color']);
id: int.parse(json['id']),
username: json['name'],
themeColor: json['theme_color'],
urlName: json['url_name']);
}
}

View File

@ -59,6 +59,4 @@ class UserInfoControlModel {
Future deleteAll() async{
return await sql.deleteAll();
}
}

View File

@ -1,29 +0,0 @@
class Data {
String version;
String name;
Data.fromJson(Map<String, dynamic> json)
: version = json['version'],
name = json['name'];
@override
String toString() {
return 'name: $name ,version: $version';
}
}
class Version {
Data data;
int status;
bool success;
Version.formJson(Map<String, dynamic> json)
: status = json['status'],
success = json['success'],
data = Data.fromJson(json['data']);
@override
String toString() {
return 'status: $status ,success: $success,date: ${data.toString()}';
}
}

View File

@ -2,16 +2,9 @@
import 'dart:async';
import "package:flutter/material.dart";
import "package:flutter_go/routers/application.dart";
import 'package:flutter_go/utils/sql.dart';
enum treeNode {
CategoryComponent,
WidgetLeaf
}
//typedef aaa
abstract class WidgetInterface {
int get id;
@ -149,226 +142,3 @@ class WidgetControlModel {
return widgets;
}
}
// 抽象类
abstract class CommonItem<T> {
int id;
String name;
int parentId;
String type;
List<CommonItem> children;
String token;
/// 父级节点, 存放整个CommonItem对象node = ! null
///
CommonItem parent;
String toString() {
return "CommonItem {name: $name, type: $type, parentId: $parentId, token: $token, children长度 ${children}";
}
T getChild(String token);
T addChildren(Object item);
// 从children树中. 查找任意子节点
T find(String token, [CommonItem node]);
}
// tree的group树干
class CategoryComponent extends CommonItem {
int id;
String name;
int parentId;
CommonItem parent;
String token;
List<CommonItem> children = [];
String type = 'category';
CategoryComponent({
@required this.id,
@required this.name,
@required this.parentId,
this.type = 'categoryw',
this.children,
this.parent
});
CategoryComponent.fromJson(Map json) {
if (json['id'] != null && json['id'].runtimeType == String) {
this.id = int.parse(json['id']);
} else {
this.id = json['id'];
}
this.name = json['name'];
this.parentId = json['parentId'];
this.token = json['id'].toString() + json['type'];
}
void addChildren(Object item) {
if (item is CategoryComponent) {
CategoryComponent cate = item;
cate.parent = this;
this.children.add(
cate
);
}
if (item is WidgetLeaf) {
WidgetLeaf widget = item;
widget.parent = this;
this.children.add(
widget
);
}
}
@override
CommonItem getChild(String token) {
return children.firstWhere((CommonItem item) => item.token == token, orElse: () => null);
}
@override
CommonItem find(String token, [CommonItem node]) {
CommonItem ret;
if (node !=null) {
if (node.token == token) {
return node;
} else {
// 循环到叶子节点, 返回 空
if (node.children == null) {
return null;
}
for (int i = 0; i < node.children.length; i++) {
CommonItem temp = this.find(token, node.children[i]);
if (temp != null) {
ret = temp;
}
}
}
} else {
ret = find(token, this);
}
return ret;
}
}
// 叶子节点
class WidgetLeaf extends CommonItem {
int id;
String name;
int parentId;
String display; // 展示类型, 区分老的widget文件下的详情
String author; // 文档负责人
String path; // 路由地址
String pageId; // 界面ID
CommonItem parent;
String type = 'widget';
WidgetLeaf({
@required this.id,
@required this.name,
@required this.display,
this.author,
this.path,
this.pageId
});
WidgetLeaf.fromJson(Map json) {
if (json['id'] != null && json['id'].runtimeType == String) {
this.id = int.parse(json['id']);
} else {
this.id = json['id'];
}
this.name = json['name'];
this.display = json['display'];
this.author = json['author'] ?? null;
this.path = json['path'] ?? null;
this.pageId = json['pageId'] ?? null;
this.token = json['id'].toString() + json['type'];
}
@override
CommonItem getChild(String token) {
return null;
}
@override
addChildren(Object item) {
// TODO: implement addChildren
return null;
}
CommonItem find(String token, [CommonItem node]){
return null;
}
}
class WidgetTree {
// 构建树型结构
static CategoryComponent buildWidgetTree(List json, [parent]){
CategoryComponent current;
if (parent != null) {
current = parent;
} else {
current = CategoryComponent(id: 0, name: 'root', parentId: null, children: []);
}
json.forEach((item) {
// 归属分类级别
if (['root', 'category'].indexOf(item['type']) != -1) {
CategoryComponent cate = CategoryComponent.fromJson(item);
if (cate.children != null) {
buildWidgetTree(item['children'], cate);
}
current.addChildren(cate);
} else {
// 归属最后一层叶子节点
WidgetLeaf cate = WidgetLeaf.fromJson(item);
current.addChildren(cate);
}
});
return current;
}
static insertDevPagesToList(List list, List devPages) {
List devChildren = [];
int index = 9999999;
if (Application.env == ENV.PRODUCTION) {
return list;
}
devPages.forEach((item) {
index++;
if (item['id'] != null) {
devChildren.add({
"id": index.toString(),
"name": item['name'],
"parentId": "99999999999",
"type": "widget",
"display": "standard",
"author": item['author'],
"pageId": item['id']
});
}
});
list.forEach((item) {
if (item['name'].toString().toUpperCase() == 'DEVELOPER') {
List children = item['children'];
children.insert(0, {
"id": "99999999999",
"name": "本地代码",
"parentId": item['id'],
"type": "category",
"children": devChildren
});
}
});
return list;
}
static CategoryComponent getCommonItemById(List<int> path, CategoryComponent root) {
print("getCommonItemByPath $path");
print("root $root");
CommonItem childLeaf;
int first = path.first;
path = path.sublist(1);
print("path:::: $path");
if (path.length >= 0) {
// childLeaf = root.getChild(path.first);
}
return childLeaf;
}
}

View File

@ -1 +0,0 @@
[{"name":"demoName","screenShot":"","author":"yourName","email":"yourEmail","desc":"这是一个测试的标准demo","id":"1a29aa8e_32ae_4241_9c8a_5c9e1f92b096"},{"name":"local","screenShot":"","author":"ab","email":"email","desc":"ags","id":"2c1d57d0_42ae_4241_9c8a_5c9e1f92b096"}]

View File

@ -1,9 +0,0 @@
{
"name": "demoName",
"screenShot": "",
"author":"yourName",
"email": "yourEmail",
"desc": "这是一个测试的标准demo",
"id": "1a29aa8e_32ae_4241_9c8a_5c9e1f92b096"
}

View File

@ -1,15 +0,0 @@
//
// Created with flutter go cli
// User: yourName
// Time: 2019-06-10 20:37:27.289097
// email: yourEmail
// desc: 这是一个测试的标准demo
//
import 'src/index.dart';
var demoWidgets = [
new Demo()
];

View File

@ -1,16 +0,0 @@
import 'package:flutter/material.dart';
class Demo extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Demo> {
@override
Widget build(BuildContext context) {
return Container(
child: RaisedButton(onPressed: () {}, child: Text('我是md中引入的demo'))
);
}
}

View File

@ -1,6 +0,0 @@
import 'demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardDemo_demoName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096;
import 'local_ab_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardDemo_local_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096;
var demoObjects = {
'1a29aa8e_32ae_4241_9c8a_5c9e1f92b096': StandardDemo_demoName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096.demoWidgets,
'2c1d57d0_42ae_4241_9c8a_5c9e1f92b096': StandardDemo_local_2c1d57d0_42ae_4241_9c8a_5c9e1f92b096.demoWidgets
};

View File

@ -1,17 +0,0 @@
{
"70c429df-c27d-4843-8e28-1e6885c9276b": {
"name": "button-red",
"screenShot": "",
"author": "sanfan",
"email": "sanfan.hx@alibaba-inc.com",
"desc": "desc",
}
}

View File

@ -1,9 +0,0 @@
{
"name": "local",
"screenShot": "",
"author":"ab",
"email": "email",
"desc": "ags",
"id": "2c1d57d0_42ae_4241_9c8a_5c9e1f92b096"
}

View File

@ -1,15 +0,0 @@
//
// Created with flutter go cli
// User: ab
// Time: 2019-08-06 17:26:02.905889
// email: email
// desc: ags
//
import 'src/index.dart';
var demoWidgets = [
new Demo()
];

View File

@ -1,16 +0,0 @@
import 'package:flutter/material.dart';
class Demo extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Demo> {
@override
Widget build(BuildContext context) {
return Container(
child: Text("this is flutter go init demo"),
);
}
}

View File

@ -1,20 +0,0 @@
# 目录说明
本目录文件结构与文件命名, 使用cli进行更新
# demos 目录文件结构
```
demos
├── ${demoName}-${author}-${32位demoID}
│   ├── index.dart
│   └── src
│   ├── .demo.json
│   └── ${demoName}.dart
├── ...${demoName}-${author}-${32位demoID}
├── index.dart
├── info.json
└── readme.md
```

View File

@ -1,11 +1,9 @@
import 'package:flutter/material.dart';
class WidgetName2Icon {
static Map<String,dynamic> icons = {
"Developer": Icons.developer_mode,
"Standard": Icons.pages ,
"Element":Icons.explicit,
"Components":Icons.extension,
"Theme":Icons.filter_b_and_w,
"Themes":Icons.filter_b_and_w,
"Form":Icons.table_chart,
"Frame":Icons.aspect_ratio,
"Media":Icons.subscriptions,

View File

@ -1,20 +1,12 @@
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter_go/utils/shared_preferences.dart';
import '../model/widget.dart';
enum ENV {
PRODUCTION,
DEV,
}
class Application {
/// 通过Application设计环境变量
static ENV env = ENV.DEV;
static Router router;
static TabController controller;
static SpUtil sharePeference;
static CategoryComponent widgetTree;
static SpUtil sharePeferences;
static Map<String, String> github = {
'widgetsURL':'https://github.com/alibaba/flutter-go/blob/develop/lib/widgets/',
@ -22,15 +14,4 @@ class Application {
//'master':'https://github.com/alibaba-paimai-frontend/flutter-common-widgets-app/tree/master/lib/widgets/'
};
/// 所有获取配置的唯一入口
Map<String, String> get config {
if (Application.env == ENV.PRODUCTION) {
return {};
}
if (Application.env == ENV.DEV) {
return {};
}
return {};
}
}

View File

@ -7,57 +7,38 @@ import 'package:flutter_go/components/full_screen_code_dialog.dart';
import 'package:flutter_go/views/web_page/web_view_page.dart';
import 'package:flutter_go/views/home.dart';
import 'package:flutter_go/views/login_page/login_page.dart';
import 'package:flutter_go/model/user_info.dart';
import 'package:flutter_go/views/collection_page/collection_page.dart';
import 'package:flutter_go/views/collection_page/collection_full_page.dart';
import 'package:flutter_go/views/standard_demo_page/index.dart';
import 'package:flutter_go/views/issuse_message_page/issuse_message_page.dart';
// app的首页
var homeHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
return new AppPage(UserInformation(id: 0));
return new AppPage();
},
);
var collectionFullHandler = new Handler(
handlerFunc: (BuildContext context,Map<String,List<String>> params){
bool hasLogined = params['hasLogin']?.first == 'true';
return CollectionFullPage(hasLogined: hasLogined);
}
);
var collectionHandler = new Handler(
handlerFunc: (BuildContext context,Map<String,List<String>> params){
bool hasLogined = params['hasLogin']?.first == 'true';
return CollectionPage(hasLogined: hasLogined);
}
);
var categoryHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
String ids = params["ids"]?.first;
String name = params["type"]?.first;
return new CategoryHome(ids);
return new CategoryHome(name);
},
);
var widgetNotFoundHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
return new WidgetNotFound();
});
return new WidgetNotFound();
});
var loginPageHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
return LoginPage();
});
return LoginPage();
});
var fullScreenCodeDialog = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
String path = params['filePath']?.first;
return new FullScreenCodeDialog(
filePath: path,
);
});
String path = params['filePath']?.first;
return new FullScreenCodeDialog(
filePath: path,
);
});
var webViewPageHand = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
@ -65,17 +46,3 @@ var webViewPageHand = new Handler(
String url = params['url']?.first;
return new WebViewPage(url, title);
});
var standardPageHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
String id = params['id']?.first;
return StandardView(id: id);
}
);
var issuesMessageHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
return IssuesMessagePage();
});

View File

@ -2,21 +2,17 @@
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:flutter_go/utils/analytics.dart' show analytics;
import '../widgets/index.dart';
import './router_handler.dart';
import '../standard_pages/index.dart';
class Routes {
static String root = "/";
static String home = "/home";
static String widgetDemo = '/widget-demo';
static String codeView = '/code-view';
static String githubCodeView = '/github-code-view';
static String webViewPage = '/web-view-page';
static String loginPage = '/loginpage';
static String issuesMessage='/issuesMessage';
static String collectionPage = '/collection-page';
static String collectionFullPage = '/collection-full-page';
static String standardPage = '/standard-page/:id';
static void configureRoutes(Router router) {
List widgetDemosList = new WidgetDemoList().getDemos();
@ -24,14 +20,12 @@ class Routes {
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
});
router.define(home, handler: homeHandler);
router.define(collectionPage,handler:collectionHandler);
router.define(collectionFullPage,handler:collectionFullHandler);
router.define('/category/:ids', handler: categoryHandler);
router.define('/category/:type', handler: categoryHandler);
router.define('/category/error/404', handler: widgetNotFoundHandler);
router.define(loginPage, handler: loginPageHandler);
router.define(codeView,handler:fullScreenCodeDialog);
router.define(webViewPage,handler:webViewPageHand);
router.define(issuesMessage, handler: issuesMessageHandler);
widgetDemosList.forEach((demo) {
Handler handler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
@ -42,10 +36,5 @@ class Routes {
});
router.define('${demo.routerName}', handler: handler);
});
router.define(standardPage,handler:standardPageHandler);
// router.define(webViewPage,handler:webViewPageHand);
// standardPages.forEach((String id, String md) => {
//
// });
}
}

View File

@ -1 +0,0 @@
[{"name":"local","screenShot":"","author":"hnaxu","title":"本地","email":"hanxu@qq.com","desc":"desc","id":"5d7178d0_42ae_4241_9c8a_5c9e1f92b096"},{"name":"test","screenShot":"","author":"abc","title":"ya","email":"adsf.com","desc":"desc","id":"84f38e00_42ae_4241_9c8a_5c9e1f92b096"},{"name":"standard","screenShot":"","author":"sanfan","title":"介绍页","email":"hanxu317@qq.com","desc":"desc","id":"ee4feb8e_32ae_4241_9c8a_5c9e1f92b096"},{"name":"standard_for_slider","screenShot":"","author":"sanfan","title":"slider组件","email":"hanxu@qq.com","desc":"slider, new Slider","id":"8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096"}]

View File

@ -1,35 +0,0 @@
import 'local_hnaxu_5d7178d0_42ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_local_5d7178d0_42ae_4241_9c8a_5c9e1f92b096;
import 'test_abc_84f38e00_42ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_test_84f38e00_42ae_4241_9c8a_5c9e1f92b096;
import 'standard_sanfan_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_standard_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096;
import 'standard_for_slider_sanfan_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096/index.dart' as StandardPage_standard_for_slider_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096;
class StandardPages {
Map<String, String> standardPages;
Map<String, String> getPages() {
return {
"0": "0" ,
"5d7178d0_42ae_4241_9c8a_5c9e1f92b096" : StandardPage_local_5d7178d0_42ae_4241_9c8a_5c9e1f92b096.getMd()
,
"84f38e00_42ae_4241_9c8a_5c9e1f92b096" : StandardPage_test_84f38e00_42ae_4241_9c8a_5c9e1f92b096.getMd()
,
"ee4feb8e_32ae_4241_9c8a_5c9e1f92b096" : StandardPage_standard_ee4feb8e_32ae_4241_9c8a_5c9e1f92b096.getMd()
,
"8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096" : StandardPage_standard_for_slider_8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096.getMd()
};
}
List<Map<String, String>> getLocalList() {
return [
{},
{ "id": "5d7178d0_42ae_4241_9c8a_5c9e1f92b096", "name": "local", "email": "hanxu@qq.com", "author": "hnaxu"}
,
{ "id": "84f38e00_42ae_4241_9c8a_5c9e1f92b096", "name": "test", "email": "adsf.com", "author": "abc"}
,
{ "id": "ee4feb8e_32ae_4241_9c8a_5c9e1f92b096", "name": "standard", "email": "hanxu317@qq.com", "author": "sanfan"}
,
{ "id": "8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096", "name": "standard_for_slider", "email": "hanxu@qq.com", "author": "sanfan"}
];
}
}

View File

@ -1,10 +0,0 @@
{
"name": "local",
"screenShot": "",
"author":"hnaxu",
"title":"本地",
"email": "hanxu@qq.com",
"desc": "desc",
"id": "5d7178d0_42ae_4241_9c8a_5c9e1f92b096"
}

View File

@ -1,52 +0,0 @@
String getMd() {
return """
# 标准的详情页
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
您可以通过goCli创建详情页所需要的demo
```
goCLi createDemo
```
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
[✓] 请输入新增加的demo名称? demoName
[✓] 请输入您的姓名(使用英文) yourName
[✓] 请输入您的github的email地址 yourEmail
[✓] 请输入您demo的描述 这是一个测试的标准demo
在完成以上操作后, 可以得到这样的输出:
```
------------------
您新增的组件信息如下
==================
{
name : demoName
author : yourName
email : yourEmail
desc : 这是一个测试的标准demo
}
==================
[✓] Is this the config you want ? (Y/n) y
{
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
}
```
您可以在任意详情页中, 通过以下方式调用
```
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```""";
}

View File

@ -1,48 +0,0 @@
# 标准的详情页
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
您可以通过goCli创建详情页所需要的demo
```
goCLi createDemo
```
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
[✓] 请输入新增加的demo名称? demoName
[✓] 请输入您的姓名(使用英文) yourName
[✓] 请输入您的github的email地址 yourEmail
[✓] 请输入您demo的描述 这是一个测试的标准demo
在完成以上操作后, 可以得到这样的输出:
```
------------------
您新增的组件信息如下
==================
{
name : demoName
author : yourName
email : yourEmail
desc : 这是一个测试的标准demo
}
==================
[✓] Is this the config you want ? (Y/n) y
{
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
}
```
您可以在任意详情页中, 通过以下方式调用
```
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```

View File

@ -1,10 +0,0 @@
{
"name": "standard_for_slider",
"screenShot": "",
"author":"sanfan",
"title":"slider组件",
"email": "hanxu@qq.com",
"desc": "slider, new Slider",
"id": "8ab2b5c2_42ae_4241_9c8a_5c9e1f92b096"
}

View File

@ -1,61 +0,0 @@
String getMd() {
return """
# Slider Page
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
您可以通过goCli创建详情页所需要的demo
```
goCLi createDemo
```
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
[✓] 请输入新增加的demo名称? demoName
[✓] 请输入您的姓名(使用英文) yourName
[✓] 请输入您的github的email地址 yourEmail
[✓] 请输入您demo的描述 这是一个测试的标准demo
在完成以上操作后, 可以得到这样的输出:
```
------------------
您新增的组件信息如下
==================
{
name : demoName
author : yourName
email : yourEmail
desc : 这是一个测试的标准demo
}
==================
[✓] Is this the config you want ? (Y/n) y
{
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
}
```
您可以在任意详情页中, 通过以下方式调用
```
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```
调用效果:
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]""";
}

View File

@ -1,55 +0,0 @@
# Slider Page
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
您可以通过goCli创建详情页所需要的demo
```
goCLi createDemo
```
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
[✓] 请输入新增加的demo名称? demoName
[✓] 请输入您的姓名(使用英文) yourName
[✓] 请输入您的github的email地址 yourEmail
[✓] 请输入您demo的描述 这是一个测试的标准demo
在完成以上操作后, 可以得到这样的输出:
```
------------------
您新增的组件信息如下
==================
{
name : demoName
author : yourName
email : yourEmail
desc : 这是一个测试的标准demo
}
==================
[✓] Is this the config you want ? (Y/n) y
{
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
}
```
您可以在任意详情页中, 通过以下方式调用
```
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```
调用效果:
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]

View File

@ -1,10 +0,0 @@
{
"name": "standard",
"screenShot": "",
"author":"sanfan",
"title":"介绍页",
"email": "hanxu317@qq.com",
"desc": "desc",
"id": "ee4feb8e_32ae_4241_9c8a_5c9e1f92b096"
}

View File

@ -1,56 +0,0 @@
String getMd() {
return """
# 标准的详情页
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
您可以通过goCli创建详情页所需要的demo
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```
goCLi createDemo
```
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
[✓] 请输入新增加的demo名称? demoName
[✓] 请输入您的姓名(使用英文) yourName
[✓] 请输入您的github的email地址 yourEmail
[✓] 请输入您demo的描述 这是一个测试的标准demo
在完成以上操作后, 可以得到这样的输出:
```
------------------
您新增的组件信息如下
==================
{
name : demoName
author : yourName
email : yourEmail
desc : 这是一个测试的标准demo
}
==================
[✓] Is this the config you want ? (Y/n) y
{
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
}
```
您可以在任意详情页中, 通过以下方式调用
```
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```""";
}

View File

@ -1,50 +0,0 @@
# 标准的详情页
您可以在这个界面中, 编写大多数的markdown文案, 他会在 **goCli watch** 下同步被编译成 **dart** 文件
您可以通过goCli创建详情页所需要的demo
[demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```
goCLi createDemo
```
在flutter go 根文件下通过命令行输入以上命令可以进行以下操作
[✓] 请输入新增加的demo名称? demoName
[✓] 请输入您的姓名(使用英文) yourName
[✓] 请输入您的github的email地址 yourEmail
[✓] 请输入您demo的描述 这是一个测试的标准demo
在完成以上操作后, 可以得到这样的输出:
```
------------------
您新增的组件信息如下
==================
{
name : demoName
author : yourName
email : yourEmail
desc : 这是一个测试的标准demo
}
==================
[✓] Is this the config you want ? (Y/n) y
{
新建的demo文件位于 : /flutter go/lib/page_demo_package/demoName_yourName_1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
demoId为 : 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096
markdown中调用方式 : [demo:1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
}
```
您可以在任意详情页中, 通过以下方式调用
```
[demo: 1a29aa8e_32ae_4241_9c8a_5c9e1f92b096]
```

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