mirror of
https://github.com/chenasraf/mudblock.git
synced 2026-05-18 01:48:57 +00:00
feat: strip colors from output
This commit is contained in:
22
lib/core/color_utils.dart
Normal file
22
lib/core/color_utils.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mudblock/core/consts.dart';
|
||||
|
||||
class ColorUtils {
|
||||
static stripColor(String text) {
|
||||
return text
|
||||
// esc
|
||||
// .replaceAll(esc, '')
|
||||
// .replaceAll(r'^[', '')
|
||||
// color
|
||||
.replaceAll(RegExp(esc + r'\[\d*m'), '')
|
||||
|
||||
// color
|
||||
// .replaceAll(RegExp(r'\[\d+m'), '')
|
||||
// esc
|
||||
// .replaceAll(String.fromCharCode(0xff), '');
|
||||
|
||||
//
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
const newline = '\n';
|
||||
const ansiEscapePattern = r'\x1B\[[0-?]*[ -/]*[@-~]';
|
||||
// const ansiEscapePattern = r'\x1B\[[0-?]*[ -/]*[@-~]';
|
||||
// final esc = String.fromCharCodes([0xff]);
|
||||
const esc = '\x1B';
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:ctelnet/ctelnet.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'color_utils.dart';
|
||||
import 'consts.dart';
|
||||
|
||||
const maxLines = 2000;
|
||||
@@ -12,6 +13,8 @@ class GameStore extends ChangeNotifier {
|
||||
final List<String> _lines = [];
|
||||
late final CTelnetClient _client;
|
||||
late final ScrollController scrollController;
|
||||
final TextEditingController input = TextEditingController();
|
||||
final FocusNode inputFocus = FocusNode();
|
||||
|
||||
GameStore init() {
|
||||
addLine('Connecting...');
|
||||
@@ -37,7 +40,8 @@ class GameStore extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void onData(String data) {
|
||||
debugPrint('onData: $data');
|
||||
debugPrint('onData: $data');
|
||||
debugPrint('stripped: ${ColorUtils.stripColor(data)}');
|
||||
// final pattern = RegExp("$newline|$ansiEscapePattern");
|
||||
// ignore: unnecessary_string_interpolations
|
||||
final pattern = RegExp("$newline");
|
||||
@@ -59,6 +63,7 @@ class GameStore extends ChangeNotifier {
|
||||
void addLine(String line) {
|
||||
_lines.add(line);
|
||||
notifyListeners();
|
||||
scrollToEnd();
|
||||
}
|
||||
|
||||
void send(String line) {
|
||||
@@ -69,11 +74,26 @@ class GameStore extends ChangeNotifier {
|
||||
void submitInput(String text) {
|
||||
addLine(text);
|
||||
send(text);
|
||||
scrollController.animateTo(
|
||||
scrollController.offset,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOut,
|
||||
scrollToEnd();
|
||||
selectInput();
|
||||
}
|
||||
|
||||
void scrollToEnd() {
|
||||
Future.delayed(const Duration(milliseconds: 10), () {
|
||||
scrollController.animateTo(
|
||||
scrollController.position.maxScrollExtent,
|
||||
duration: const Duration(milliseconds: 50),
|
||||
curve: Curves.easeIn,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void selectInput() {
|
||||
input.selection = TextSelection(
|
||||
baseOffset: 0,
|
||||
extentOffset: input.text.length,
|
||||
);
|
||||
inputFocus.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,17 +15,20 @@ class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
title: 'Mudblock',
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Mudblock'),
|
||||
),
|
||||
body: ChangeNotifierProvider(
|
||||
create: (_) => GameStore().init(),
|
||||
builder: (context, snapshot) {
|
||||
return const HomePage();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mudblock/core/color_utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../core/store.dart';
|
||||
@@ -11,15 +12,20 @@ class HomePage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _HomePageState extends State<HomePage> with GameStoreMixin {
|
||||
final TextEditingController _input = TextEditingController();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const textStyle = TextStyle(color: Colors.white);
|
||||
return Material(
|
||||
color: Colors.black,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
const consoleStyle = TextStyle(
|
||||
color: Colors.white,
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: 16,
|
||||
);
|
||||
final inputStyle = consoleStyle.copyWith(color: Colors.grey);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Material(
|
||||
color: Colors.black,
|
||||
child: Consumer<GameStore>(
|
||||
builder: (context, store, child) {
|
||||
final lines = store.lines;
|
||||
@@ -30,7 +36,10 @@ class _HomePageState extends State<HomePage> with GameStoreMixin {
|
||||
return RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(text: lines[index], style: textStyle),
|
||||
TextSpan(
|
||||
text: ColorUtils.stripColor(lines[index]),
|
||||
style: consoleStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -40,19 +49,25 @@ class _HomePageState extends State<HomePage> with GameStoreMixin {
|
||||
},
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
controller: _input,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: TextField(
|
||||
focusNode: store.inputFocus,
|
||||
controller: store.input,
|
||||
onSubmitted: (text) {
|
||||
store.submitInput(text);
|
||||
},
|
||||
style: textStyle,
|
||||
onTap: store.selectInput,
|
||||
style: consoleStyle.copyWith(color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Enter command',
|
||||
hintStyle: textStyle.copyWith(color: Colors.grey),
|
||||
border: const OutlineInputBorder(),
|
||||
hintStyle: inputStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user