mirror of
https://github.com/qinglong-app/qinglong_app.git
synced 2025-10-09 16:48:19 +08:00
新增代码文件支持行号显示
This commit is contained in:
@@ -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) {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user