新增代码文件支持行号显示

This commit is contained in:
jyuesong
2022-06-15 11:05:49 +08:00
parent 4e3f8a0df9
commit 2005083d2e
117 changed files with 4625 additions and 136 deletions

View File

@@ -1,12 +1,16 @@
import 'package:code_text_field/code_text_field.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:highlight/languages/powershell.dart';
import 'package:qinglong_app/base/http/api.dart';
import 'package:qinglong_app/base/http/http.dart';
import 'package:qinglong_app/base/ql_app_bar.dart';
import 'package:qinglong_app/base/sp_const.dart';
import 'package:qinglong_app/base/theme.dart';
import 'package:qinglong_app/utils/extension.dart';
import 'package:qinglong_app/utils/sp_utils.dart';
class ConfigEditPage extends ConsumerStatefulWidget {
final String content;
@@ -21,6 +25,8 @@ class ConfigEditPage extends ConsumerStatefulWidget {
class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
CodeController? _codeController;
late String result;
late String preResult;
List<String> operateList = [];
@override
void dispose() {
@@ -31,18 +37,23 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
@override
void initState() {
result = widget.content;
preResult = widget.content;
super.initState();
generateOperateList();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
focusNode.requestFocus();
checkClipBoard();
});
}
Future<void> notifyICloud(BuildContext context, String? title, String? content) async {
}
@override
Widget build(BuildContext context) {
_codeController ??= CodeController(
text: widget.content,
text: result,
language: powershell,
onChange: (value) {
result = value;
@@ -56,13 +67,78 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
appBar: QlAppBar(
canBack: true,
backCall: () {
Navigator.of(context).pop();
FocusManager.instance.primaryFocus?.unfocus();
if (preResult == result) {
Navigator.of(context).pop();
} else {
showCupertinoDialog(
context: context,
useRootNavigator: false,
builder: (childContext) => CupertinoAlertDialog(
title: const Text("温馨提示"),
content: const Text("你编辑的内容还没用提交,确定退出吗?"),
actions: [
CupertinoDialogAction(
child: const Text(
"取消",
style: TextStyle(
color: Color(0xff999999),
),
),
onPressed: () {
Navigator.of(childContext).pop();
},
),
CupertinoDialogAction(
child: Text(
"确定",
style: TextStyle(
color: ref.watch(themeProvider).primaryColor,
),
),
onPressed: () {
Navigator.of(childContext).pop();
Navigator.of(context).pop();
},
),
],
),
);
}
},
title: '编辑${widget.title}',
actions: [
const SizedBox(
width: 15,
),
Material(
color: Colors.transparent,
child: PopupMenuButton<String>(
onSelected: (String result) {
updateValueBykey(result);
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
...operateList
.map(
(e) => PopupMenuItem<String>(
child: Text(e),
value: e,
),
)
.toList(),
],
child: const Center(
child: Icon(
CupertinoIcons.arrow_up_right_diamond,
),
),
),
),
InkWell(
onTap: () async {
HttpResponse<NullResponse> response = await Api.saveFile(widget.title, result);
await notifyICloud(context, widget.title, result);
if (response.success) {
"提交成功".toast();
Navigator.of(context).pop(widget.title);
@@ -89,23 +165,176 @@ class _ConfigEditPageState extends ConsumerState<ConfigEditPage> {
),
body: SafeArea(
top: false,
child: CodeField(
controller: _codeController!,
expands: true,
wrap: true,
lineNumberStyle: const LineNumberStyle(
width: 0,
margin: 0,
textStyle: TextStyle(
color: Colors.transparent,
fontSize: 0,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10,
),
child: CodeField(
controller: _codeController!,
expands: true,
background: Colors.white,
wrap: SpUtil.getBool(spShowLine, defValue: false) ? false : true,
hideColumn: !SpUtil.getBool(spShowLine, defValue: false),
lineNumberStyle: LineNumberStyle(
textStyle: TextStyle(
color: ref.watch(themeProvider).themeColor.descColor(),
fontSize: 12,
),
),
),
background: ref.watch(themeProvider).themeColor.settingBgColor(),
),
),
);
}
FocusNode focusNode = FocusNode();
void generateOperateList() {
operateList.clear();
List<String> array = result.split("\n");
for (String a in array) {
String t = a.replaceAll(" ", "");
if (t.trim().startsWith("export")) {
int i = t.indexOf("export") + 6;
int j = t.indexOf("=");
operateList.add(t.substring(i, j));
}
}
}
void updateValueBykey(String key) async {
String defaultValue = "";
try {
var clipBoard = await Clipboard.getData(Clipboard.kTextPlain);
if (clipBoard != null && clipBoard.text != null) {
String tempText = clipBoard.text!;
if (tempText.trim().contains("export")) {
int i = tempText.trim().indexOf("\"");
int j = tempText.trim().lastIndexOf("\"");
if (i == -1 || j == -1) {
i = tempText.trim().indexOf("'");
j = tempText.trim().lastIndexOf("'");
}
defaultValue = tempText.trim().substring(i, j);
} else {
defaultValue = tempText;
}
}
} catch (e) {}
TextEditingController controller = TextEditingController(text: defaultValue.replaceAll("\"", "").replaceAll("'", ""));
showCupertinoDialog(
useRootNavigator: false,
context: context,
builder: (context) => CupertinoAlertDialog(
title: Text("编辑$key:"),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
),
child: TextField(
controller: controller,
decoration: const InputDecoration(
isDense: true,
contentPadding: EdgeInsets.all(4),
hintText: "请输入值",
hintStyle: TextStyle(
fontSize: 14,
),
),
autofocus: false,
),
),
],
),
actions: [
CupertinoDialogAction(
child: const Text(
"取消",
style: TextStyle(
color: Color(0xff999999),
),
),
onPressed: () {
Navigator.of(context).pop();
},
),
CupertinoDialogAction(
child: Text(
"确定",
style: TextStyle(
color: ref.watch(themeProvider).primaryColor,
),
),
onPressed: () async {
Navigator.of(context).pop();
updateValueByKey(key, controller.text);
},
),
],
),
);
}
void updateValueByKey(String key, String text) {
List<String> array = result.split("\n");
for (String a in array) {
String t = a.replaceAll(" ", "");
if (t.trim().startsWith("export")) {
int i = t.indexOf("export") + 6;
int j = t.indexOf("=");
String tempResult = t.substring(i, j);
if (tempResult == key) {
result = result.replaceAll(a, "\nexport $key = \"$text\" \n\n");
break;
}
}
}
_codeController = null;
setState(() {});
"已修改".toast();
}
void checkClipBoard() async {
try {
String key = "";
String value = "";
var clipBoard = await Clipboard.getData(Clipboard.kTextPlain);
if (clipBoard != null && clipBoard.text != null) {
String tempText = clipBoard.text!;
if (tempText.trim().contains("export")) {
int kI = tempText.trim().indexOf("export");
int kJ = tempText.trim().indexOf("=");
key = tempText.trim().substring(kI + 6, kJ);
int i = tempText.trim().indexOf("\"");
int j = tempText.trim().lastIndexOf("\"");
if (i == -1 || j == -1) {
i = tempText.trim().indexOf("'");
j = tempText.trim().lastIndexOf("'");
}
value = tempText.trim().substring(i, j);
if (key.isNotEmpty && result.contains(key) && value.isNotEmpty) {
WidgetsBinding.instance.endOfFrame.then((value) {
updateValueBykey(key);
});
}
}
}
} catch (e) {}
}
}