refactor(many files): 页面部分的文件结构调整

1.views 文件夹里面分类,页面相关文件;2.公共组件全部放在components里;3.创建resources文件夹放置资源dart文件4.修改二级菜单文字大小

BREAKING CHANGE: 重构,建议删除本地db,再编译
This commit is contained in:
ryan
2019-01-28 17:45:18 +08:00
parent baecc158a9
commit d48942b55d
186 changed files with 214 additions and 355 deletions

View File

@ -0,0 +1,43 @@
/*
* @Author: 一凨
* @Date: 2019-01-14 11:42:36
* @Last Modified by: 一凨
* @Last Modified time: 2019-01-14 16:53:11
*/
// 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:async';
import '../routers/application.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter/material.dart';
Map<String, String> _exampleCode;
String _code;
void _launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
Future<String> getExampleCode(context,String filePath, AssetBundle bundle) async {
if (_exampleCode == null) await _parseExampleCode(context,filePath, bundle);
return _code;
}
Future<void> _parseExampleCode(context,String filePath, AssetBundle bundle) async {
String code;
try {
code = await bundle.loadString('lib/widgets/$filePath');
} catch (err) {
Navigator.of(context).pop();
_launchURL(Application.github['widgetsURL'] + filePath);
}
_code = code;
}

View File

@ -0,0 +1,359 @@
// 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';
import 'package:string_scanner/string_scanner.dart';
/// final SyntaxHighlighterStyle style = SyntaxHighlighterStyle.lightThemeStyle();
/// DartSyntaxHighlighter(style).format(source)
class SyntaxHighlighterStyle {
SyntaxHighlighterStyle({
this.baseStyle,
this.numberStyle,
this.commentStyle,
this.keywordStyle,
this.stringStyle,
this.punctuationStyle,
this.classStyle,
this.constantStyle
});
static SyntaxHighlighterStyle lightThemeStyle() {
return SyntaxHighlighterStyle(
baseStyle: const TextStyle(color: Color(0xFF000000)),
numberStyle: const TextStyle(color: Color(0xFF1565C0)),
commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
keywordStyle: const TextStyle(color: Color(0xFF9C27B0)),
stringStyle: const TextStyle(color: Color(0xFF43A047)),
punctuationStyle: const TextStyle(color: Color(0xFF000000)),
classStyle: const TextStyle(color: Color(0xFF512DA8)),
constantStyle: const TextStyle(color: Color(0xFF795548))
);
}
static SyntaxHighlighterStyle darkThemeStyle() {
return SyntaxHighlighterStyle(
baseStyle: const TextStyle(color: Color(0xFFFFFFFF)),
numberStyle: const TextStyle(color: Color(0xFF1565C0)),
commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
keywordStyle: const TextStyle(color: Color(0xFF80CBC4)),
stringStyle: const TextStyle(color: Color(0xFF009688)),
punctuationStyle: const TextStyle(color: Color(0xFFFFFFFF)),
classStyle: const TextStyle(color: Color(0xFF009688)),
constantStyle: const TextStyle(color: Color(0xFF795548))
);
}
final TextStyle baseStyle;
final TextStyle numberStyle;
final TextStyle commentStyle;
final TextStyle keywordStyle;
final TextStyle stringStyle;
final TextStyle punctuationStyle;
final TextStyle classStyle;
final TextStyle constantStyle;
}
abstract class Highlighter { // ignore: one_member_abstracts
TextSpan format(String src);
}
class DartSyntaxHighlighter extends Highlighter {
DartSyntaxHighlighter([this._style]) {
_spans = <_HighlightSpan>[];
_style ??= SyntaxHighlighterStyle.darkThemeStyle();
}
SyntaxHighlighterStyle _style;
static const List<String> _keywords = <String>[
'abstract', 'as', 'assert', 'async', 'await', 'break', 'case', 'catch',
'class', 'const', 'continue', 'default', 'deferred', 'do', 'dynamic', 'else',
'enum', 'export', 'external', 'extends', 'factory', 'false', 'final',
'finally', 'for', 'get', 'if', 'implements', 'import', 'in', 'is', 'library',
'new', 'null', 'operator', 'part', 'rethrow', 'return', 'set', 'static',
'super', 'switch', 'sync', 'this', 'throw', 'true', 'try', 'typedef', 'var',
'void', 'while', 'with', 'yield'
];
static const List<String> _builtInTypes = <String>[
'int', 'double', 'num', 'bool'
];
String _src;
StringScanner _scanner;
List<_HighlightSpan> _spans;
@override
TextSpan format(String src) {
_src = src;
_scanner = StringScanner(_src);
if (_generateSpans()) {
// Successfully parsed the code
final List<TextSpan> formattedText = <TextSpan>[];
int currentPosition = 0;
for (_HighlightSpan span in _spans) {
if (currentPosition != span.start)
formattedText.add(TextSpan(text: _src.substring(currentPosition, span.start)));
formattedText.add(TextSpan(style: span.textStyle(_style), text: span.textForSpan(_src)));
currentPosition = span.end;
}
if (currentPosition != _src.length)
formattedText.add(TextSpan(text: _src.substring(currentPosition, _src.length)));
return TextSpan(style: _style.baseStyle, children: formattedText);
} else {
// Parsing failed, return with only basic formatting
return TextSpan(style: _style.baseStyle, text: src);
}
}
bool _generateSpans() {
int lastLoopPosition = _scanner.position;
while (!_scanner.isDone) {
// Skip White space
_scanner.scan(RegExp(r'\s+'));
// Block comments
if (_scanner.scan(RegExp(r'/\*(.|\n)*\*/'))) {
_spans.add(_HighlightSpan(
_HighlightType.comment,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Line comments
if (_scanner.scan('//')) {
final int startComment = _scanner.lastMatch.start;
bool eof = false;
int endComment;
if (_scanner.scan(RegExp(r'.*\n'))) {
endComment = _scanner.lastMatch.end - 1;
} else {
eof = true;
endComment = _src.length;
}
_spans.add(_HighlightSpan(
_HighlightType.comment,
startComment,
endComment
));
if (eof)
break;
continue;
}
// Raw r"String"
if (_scanner.scan(RegExp(r'r".*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Raw r'String'
if (_scanner.scan(RegExp(r"r'.*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline """String"""
if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline '''String'''
if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// "String"
if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// 'String'
if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Double
if (_scanner.scan(RegExp(r'\d+\.\d+'))) {
_spans.add(_HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Integer
if (_scanner.scan(RegExp(r'\d+'))) {
_spans.add(_HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end)
);
continue;
}
// Punctuation
if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) {
_spans.add(_HighlightSpan(
_HighlightType.punctuation,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Meta data
if (_scanner.scan(RegExp(r'@\w+'))) {
_spans.add(_HighlightSpan(
_HighlightType.keyword,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Words
if (_scanner.scan(RegExp(r'\w+'))) {
_HighlightType type;
String word = _scanner.lastMatch[0];
if (word.startsWith('_'))
word = word.substring(1);
if (_keywords.contains(word))
type = _HighlightType.keyword;
else if (_builtInTypes.contains(word))
type = _HighlightType.keyword;
else if (_firstLetterIsUpperCase(word))
type = _HighlightType.klass;
else if (word.length >= 2 && word.startsWith('k') && _firstLetterIsUpperCase(word.substring(1)))
type = _HighlightType.constant;
if (type != null) {
_spans.add(_HighlightSpan(
type,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
}
}
// Check if this loop did anything
if (lastLoopPosition == _scanner.position) {
// Failed to parse this file, abort gracefully
return false;
}
lastLoopPosition = _scanner.position;
}
_simplify();
return true;
}
void _simplify() {
for (int i = _spans.length - 2; i >= 0; i -= 1) {
if (_spans[i].type == _spans[i + 1].type && _spans[i].end == _spans[i + 1].start) {
_spans[i] = _HighlightSpan(
_spans[i].type,
_spans[i].start,
_spans[i + 1].end
);
_spans.removeAt(i + 1);
}
}
}
bool _firstLetterIsUpperCase(String str) {
if (str.isNotEmpty) {
final String first = str.substring(0, 1);
return first == first.toUpperCase();
}
return false;
}
}
enum _HighlightType {
number,
comment,
keyword,
string,
punctuation,
klass,
constant
}
class _HighlightSpan {
_HighlightSpan(this.type, this.start, this.end);
final _HighlightType type;
final int start;
final int end;
String textForSpan(String src) {
return src.substring(start, end);
}
TextStyle textStyle(SyntaxHighlighterStyle style) {
if (type == _HighlightType.number)
return style.numberStyle;
else if (type == _HighlightType.comment)
return style.commentStyle;
else if (type == _HighlightType.keyword)
return style.keywordStyle;
else if (type == _HighlightType.string)
return style.stringStyle;
else if (type == _HighlightType.punctuation)
return style.punctuationStyle;
else if (type == _HighlightType.klass)
return style.classStyle;
else if (type == _HighlightType.constant)
return style.constantStyle;
else
return style.baseStyle;
}
}

17
lib/utils/net_utils.dart Normal file
View File

@ -0,0 +1,17 @@
import 'package:dio/dio.dart';
import 'dart:async';
var dio = new Dio();
class NetUtils {
static Future get(String url,{Map<String,dynamic> params}) async{
var response = await dio.get(url, data: params);
return response.data;
}
static Future post(String url,Map<String,dynamic> params) async{
var response = await dio.post(url, data: params);
return response.data;
}
}

90
lib/utils/provider.dart Normal file
View File

@ -0,0 +1,90 @@
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:flutter/services.dart' show rootBundle;
//const createSql = {
// 'cat': """
// CREATE TABLE "cat" (
// `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
// `name` TEXT NOT NULL UNIQUE,
// `depth` INTEGER NOT NULL DEFAULT 1,
// `parentId` INTEGER NOT NULL,
// `desc` TEXT
// );
// """,
// 'collectio': """
// CREATE TABLE collection (id INTEGER PRIMARY KEY NOT NULL UNIQUE, name TEXT NOT NULL, router TEXT);
// """,
// 'widget': """
// CREATE TABLE widget (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, name TEXT NOT NULL, cnName TEXT NOT NULL, image TEXT NOT NULL, doc TEXT, demo TEXT, catId INTEGER NOT NULL REFERENCES cat (id), owner TEXT);
// """;
//};
class Provider {
static Database db;
// 获取数据库中所有的表
Future<List> getTables() async {
if (db == null) {
return Future.value([]);
}
List tables = await db.rawQuery('SELECT name FROM sqlite_master WHERE type = "table"');
List<String> targetList = [];
tables.forEach((item) {
targetList.add(item['name']);
});
return targetList;
}
// 检查数据库中, 表是否完整, 在部份android中, 会出现表丢失的情况
Future checkTableIsRight() async {
List<String> expectTables = ['cat', 'widget', 'collection'];
List<String> tables = await getTables();
for(int i = 0; i < expectTables.length; i++) {
if (!tables.contains(expectTables[i])) {
return false;
}
}
return true;
}
//初始化数据库
Future init(bool isCreate) async {
//Get a location using getDatabasesPath
String databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'flutter.db');
try {
db = await openDatabase(path);
} catch (e) {
print("Error $e");
}
bool tableIsRight = await this.checkTableIsRight();
if (!tableIsRight) {
// 关闭上面打开的db否则无法执行open
db.close();
// Delete the database
await deleteDatabase(path);
ByteData data = await rootBundle.load(join("assets", "app.db"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await new File(path).writeAsBytes(bytes);
db = await openDatabase(path, version: 1,
onCreate: (Database db, int version) async {
print('db created version is $version');
}, onOpen: (Database db) async {
print('new db opened');
});
} else {
print("Opening existing database");
}
}
}

98
lib/utils/sql.dart Normal file
View File

@ -0,0 +1,98 @@
import './provider.dart';
import 'dart:async';
import 'package:sqflite/sqflite.dart';
class BaseModel{
Database db;
final String table = '';
var query;
BaseModel(this.db){
query = db.query;
}
}
class Sql extends BaseModel {
final String tableName;
Sql.setTable(String name)
: tableName = name,
super(Provider.db);
// sdf
Future<List> get() async{
return await this.query(tableName);
}
String getTableName () {
return tableName;
}
Future<int> delete(String value,String key) async{
return await this.db.delete(tableName,where:'$key = ?',whereArgs:[value]);
}
Future<List> getByCondition({Map<dynamic, dynamic> conditions}) async {
if (conditions == null || conditions.isEmpty) {
return this.get();
}
String stringConditions = '';
int index = 0;
conditions.forEach((key, value) {
if (value == null) {
return ;
}
if (value.runtimeType == String) {
stringConditions = '$stringConditions $key = "$value"';
}
if (value.runtimeType == int) {
stringConditions = '$stringConditions $key = $value';
}
if (index >= 0 && index < conditions.length -1) {
stringConditions = '$stringConditions and';
}
index++;
});
// print("this is string condition for sql > $stringConditions");
return await this.query(tableName, where: stringConditions);
}
Future<Map<String, dynamic>> insert(Map<String, dynamic> json) async {
var id = await this.db.insert(tableName, json);
json['id'] = id;
return json;
}
///
/// 搜索
/// @param Object condition
/// @mods [And, Or] default is Or
/// search({'name': "hanxu', 'id': 1};
///
Future<List> search({Map<String, dynamic> conditions, String mods = 'Or'}) async {
if (conditions == null || conditions.isEmpty) {
return this.get();
}
String stringConditions = '';
int index = 0;
conditions.forEach((key, value) {
if (value == null) {
return ;
}
if (value.runtimeType == String) {
stringConditions = '$stringConditions $key like "%$value%"';
}
if (value.runtimeType == int) {
stringConditions = '$stringConditions $key = "%$value%"';
}
if (index >= 0 && index < conditions.length -1) {
stringConditions = '$stringConditions $mods';
}
index++;
});
return await this.query(tableName, where: stringConditions);
}
}

29
lib/utils/style.dart Normal file
View File

@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
//颜色配置
class AppColor{
static const int white = 0xFFFFFFFF;
static const int mainTextColor = 0xFF121917;
static const int subTextColor = 0xff959595;
}
//文本设置
class AppText{
static const middleSize = 16.0;
static const middleText = TextStyle(
color: Color(AppColor.mainTextColor),
fontSize: middleSize,
);
static const middleSubText = TextStyle(
color: Color(AppColor.subTextColor),
fontSize: middleSize,
);
}
class WidgetDemoColor {
static const int fontColor = 0xFF607173;
static const int iconColor = 0xFF607173;
static const int borderColor = 0xFFEFEFEF;
}

View File

@ -0,0 +1,362 @@
/*
* @Author: 一凨
* @Date: 2019-01-14 11:42:39
* @Last Modified by: 一凨
* @Last Modified time: 2019-01-14 11:42:39
*/
// 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';
import 'package:string_scanner/string_scanner.dart';
class SyntaxHighlighterStyle {
SyntaxHighlighterStyle({
this.baseStyle,
this.numberStyle,
this.commentStyle,
this.keywordStyle,
this.stringStyle,
this.punctuationStyle,
this.classStyle,
this.constantStyle
});
static SyntaxHighlighterStyle lightThemeStyle() {
return SyntaxHighlighterStyle(
baseStyle: const TextStyle(color: Color(0xFF000000)),
numberStyle: const TextStyle(color: Color(0xFF1565C0)),
commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
keywordStyle: const TextStyle(color: Color(0xFF9C27B0)),
stringStyle: const TextStyle(color: Color(0xFF43A047)),
punctuationStyle: const TextStyle(color: Color(0xFF000000)),
classStyle: const TextStyle(color: Color(0xFF512DA8)),
constantStyle: const TextStyle(color: Color(0xFF795548))
);
}
static SyntaxHighlighterStyle darkThemeStyle() {
return SyntaxHighlighterStyle(
baseStyle: const TextStyle(color: Color(0xFFFFFFFF)),
numberStyle: const TextStyle(color: Color(0xFF1565C0)),
commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
keywordStyle: const TextStyle(color: Color(0xFF80CBC4)),
stringStyle: const TextStyle(color: Color(0xFF009688)),
punctuationStyle: const TextStyle(color: Color(0xFFFFFFFF)),
classStyle: const TextStyle(color: Color(0xFF009688)),
constantStyle: const TextStyle(color: Color(0xFF795548))
);
}
final TextStyle baseStyle;
final TextStyle numberStyle;
final TextStyle commentStyle;
final TextStyle keywordStyle;
final TextStyle stringStyle;
final TextStyle punctuationStyle;
final TextStyle classStyle;
final TextStyle constantStyle;
}
abstract class SyntaxHighlighter { // ignore: one_member_abstracts
TextSpan format(String src);
}
class DartSyntaxHighlighter extends SyntaxHighlighter {
DartSyntaxHighlighter([this._style]) {
_spans = <_HighlightSpan>[];
_style ??= SyntaxHighlighterStyle.darkThemeStyle();
}
SyntaxHighlighterStyle _style;
static const List<String> _keywords = <String>[
'abstract', 'as', 'assert', 'async', 'await', 'break', 'case', 'catch',
'class', 'const', 'continue', 'default', 'deferred', 'do', 'dynamic', 'else',
'enum', 'export', 'external', 'extends', 'factory', 'false', 'final',
'finally', 'for', 'get', 'if', 'implements', 'import', 'in', 'is', 'library',
'new', 'null', 'operator', 'part', 'rethrow', 'return', 'set', 'static',
'super', 'switch', 'sync', 'this', 'throw', 'true', 'try', 'typedef', 'var',
'void', 'while', 'with', 'yield'
];
static const List<String> _builtInTypes = <String>[
'int', 'double', 'num', 'bool'
];
String _src;
StringScanner _scanner;
List<_HighlightSpan> _spans;
@override
TextSpan format(String src) {
_src = src;
_scanner = StringScanner(_src);
if (_generateSpans()) {
// Successfully parsed the code
final List<TextSpan> formattedText = <TextSpan>[];
int currentPosition = 0;
for (_HighlightSpan span in _spans) {
if (currentPosition != span.start)
formattedText.add(TextSpan(text: _src.substring(currentPosition, span.start)));
formattedText.add(TextSpan(style: span.textStyle(_style), text: span.textForSpan(_src)));
currentPosition = span.end;
}
if (currentPosition != _src.length)
formattedText.add(TextSpan(text: _src.substring(currentPosition, _src.length)));
return TextSpan(style: _style.baseStyle, children: formattedText);
} else {
// Parsing failed, return with only basic formatting
return TextSpan(style: _style.baseStyle, text: src);
}
}
bool _generateSpans() {
int lastLoopPosition = _scanner.position;
while (!_scanner.isDone) {
// Skip White space
_scanner.scan(RegExp(r'\s+'));
// Block comments
if (_scanner.scan(RegExp(r'/\*(.|\n)*\*/'))) {
_spans.add(_HighlightSpan(
_HighlightType.comment,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Line comments
if (_scanner.scan('//')) {
final int startComment = _scanner.lastMatch.start;
bool eof = false;
int endComment;
if (_scanner.scan(RegExp(r'.*\n'))) {
endComment = _scanner.lastMatch.end - 1;
} else {
eof = true;
endComment = _src.length;
}
_spans.add(_HighlightSpan(
_HighlightType.comment,
startComment,
endComment
));
if (eof)
break;
continue;
}
// Raw r"String"
if (_scanner.scan(RegExp(r'r".*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Raw r'String'
if (_scanner.scan(RegExp(r"r'.*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline """String"""
if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline '''String'''
if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// "String"
if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// 'String'
if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Double
if (_scanner.scan(RegExp(r'\d+\.\d+'))) {
_spans.add(_HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Integer
if (_scanner.scan(RegExp(r'\d+'))) {
_spans.add(_HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end)
);
continue;
}
// Punctuation
if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) {
_spans.add(_HighlightSpan(
_HighlightType.punctuation,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Meta data
if (_scanner.scan(RegExp(r'@\w+'))) {
_spans.add(_HighlightSpan(
_HighlightType.keyword,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Words
if (_scanner.scan(RegExp(r'\w+'))) {
_HighlightType type;
String word = _scanner.lastMatch[0];
if (word.startsWith('_'))
word = word.substring(1);
if (_keywords.contains(word))
type = _HighlightType.keyword;
else if (_builtInTypes.contains(word))
type = _HighlightType.keyword;
else if (_firstLetterIsUpperCase(word))
type = _HighlightType.klass;
else if (word.length >= 2 && word.startsWith('k') && _firstLetterIsUpperCase(word.substring(1)))
type = _HighlightType.constant;
if (type != null) {
_spans.add(_HighlightSpan(
type,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
}
}
// Check if this loop did anything
if (lastLoopPosition == _scanner.position) {
// Failed to parse this file, abort gracefully
return false;
}
lastLoopPosition = _scanner.position;
}
_simplify();
return true;
}
void _simplify() {
for (int i = _spans.length - 2; i >= 0; i -= 1) {
if (_spans[i].type == _spans[i + 1].type && _spans[i].end == _spans[i + 1].start) {
_spans[i] = _HighlightSpan(
_spans[i].type,
_spans[i].start,
_spans[i + 1].end
);
_spans.removeAt(i + 1);
}
}
}
bool _firstLetterIsUpperCase(String str) {
if (str.isNotEmpty) {
final String first = str.substring(0, 1);
return first == first.toUpperCase();
}
return false;
}
}
enum _HighlightType {
number,
comment,
keyword,
string,
punctuation,
klass,
constant
}
class _HighlightSpan {
_HighlightSpan(this.type, this.start, this.end);
final _HighlightType type;
final int start;
final int end;
String textForSpan(String src) {
return src.substring(start, end);
}
TextStyle textStyle(SyntaxHighlighterStyle style) {
if (type == _HighlightType.number)
return style.numberStyle;
else if (type == _HighlightType.comment)
return style.commentStyle;
else if (type == _HighlightType.keyword)
return style.keywordStyle;
else if (type == _HighlightType.string)
return style.stringStyle;
else if (type == _HighlightType.punctuation)
return style.punctuationStyle;
else if (type == _HighlightType.klass)
return style.classStyle;
else if (type == _HighlightType.constant)
return style.constantStyle;
else
return style.baseStyle;
}
}

90
lib/utils/util.dart Normal file
View File

@ -0,0 +1,90 @@
import 'package:flutter/material.dart';
const Map<String, Color> emumMap = const {
"Objective-C": Color(0xFF438EFF),
"Perl": Color(0xFF0298C3),
"Python": Color(0xFF0298C3),
"JavaScript": Color(0xFFF1E05A),
"PHP": Color(0xFF4F5D95),
"R": Color(0xFF188CE7),
"Lua": Color(0xFFC22D40),
"Scala": Color(0xFF020080),
"Swift": Color(0xFFFFAC45),
"Kotlin": Color(0xFFF18E33),
"Vue": Colors.black,
"Ruby": Color(0xFF701617),
"Shell": Color(0xFF89E051),
"TypeScript": Color(0xFF2B7489),
"C++": Color(0xFFF34B7D),
"CSS": Color(0xFF563C7C),
"Java": Color(0xFFB07219),
"C#": Color(0xFF178600),
"Go": Color(0xFF375EAB),
"Erlang": Color(0xFFB83998),
"C": Color(0xFF555555),
};
class Util {
static String getTimeDuration(String comTime) {
var nowTime = DateTime.now();
var compareTime = DateTime.parse(comTime);
if (nowTime.isAfter(compareTime)) {
if (nowTime.year == compareTime.year) {
if (nowTime.month == compareTime.month) {
if (nowTime.day == compareTime.day) {
if (nowTime.hour == compareTime.hour) {
if (nowTime.minute == compareTime.minute) {
return '片刻之间';
}
return (nowTime.minute - compareTime.minute).toString() + '分钟前';
}
return (nowTime.hour - compareTime.hour).toString() + '小时前';
}
return (nowTime.day - compareTime.day).toString() + '天前';
}
return (nowTime.month - compareTime.month).toString() + '月前';
}
return (nowTime.year - compareTime.year).toString() + '年前';
}
return 'time error';
}
static double setPercentage(percentage, context) {
return MediaQuery.of(context).size.width * percentage;
}
static Color getLangColor(String language) {
if (emumMap.containsKey(language)) {
return emumMap[language];
}
return Colors.black26;
}
static String getTimeDate(String comTime) {
var compareTime = DateTime.parse(comTime);
String weekDay = '';
switch (compareTime.weekday) {
case 2:
weekDay = '周二';
break;
case 3:
weekDay = '周三';
break;
case 4:
weekDay = '周四';
break;
case 5:
weekDay = '周五';
break;
case 6:
weekDay = '周六';
break;
case 7:
weekDay = '周日';
break;
default:
weekDay = '周一';
}
return '${compareTime.month}-${compareTime.day} $weekDay';
}
}