Merge branch 'main' into ios

This commit is contained in:
GFWFighter
2023-10-24 18:38:48 +03:30
committed by GitHub
44 changed files with 747 additions and 1717 deletions

View File

@@ -8,7 +8,7 @@ import 'package:combine/combine.dart';
import 'package:ffi/ffi.dart';
import 'package:fpdart/fpdart.dart';
import 'package:hiddify/domain/connectivity/connectivity.dart';
import 'package:hiddify/domain/singbox/config_options.dart';
import 'package:hiddify/domain/singbox/singbox.dart';
import 'package:hiddify/gen/singbox_generated_bindings.dart';
import 'package:hiddify/services/singbox/shared.dart';
import 'package:hiddify/services/singbox/singbox_service.dart';
@@ -16,6 +16,7 @@ import 'package:hiddify/utils/utils.dart';
import 'package:loggy/loggy.dart';
import 'package:path/path.dart' as p;
import 'package:rxdart/rxdart.dart';
import 'package:watcher/watcher.dart';
final _logger = Loggy('FFISingboxService');
@@ -301,33 +302,47 @@ class FFISingboxService
);
}
final _logBuffer = <String>[];
int _logFilePosition = 0;
@override
Stream<String> watchLogs(String path) {
var linesRead = 0;
return Stream.periodic(
const Duration(seconds: 1),
).asyncMap((_) async {
final result = await _readLogs(path, linesRead);
linesRead = result.$2;
return result.$1;
}).transform(
StreamTransformer.fromHandlers(
handleData: (data, sink) {
for (final item in data) {
sink.add(item);
}
},
),
);
Stream<List<String>> watchLogs(String path) async* {
yield await _readLogFile(File(path));
yield* Watcher(path, pollingDelay: const Duration(seconds: 1))
.events
.asyncMap((event) async {
if (event.type == ChangeType.MODIFY) {
await _readLogFile(File(path));
}
return _logBuffer;
});
}
Future<(List<String>, int)> _readLogs(String path, int from) async {
return CombineWorker().execute(
@override
TaskEither<String, Unit> clearLogs() {
return TaskEither(
() async {
final lines = await File(path).readAsLines();
final to = lines.length;
return (lines.sublist(from), to);
_logBuffer.clear();
return right(unit);
},
);
}
Future<List<String>> _readLogFile(File file) async {
if (_logFilePosition == 0 && file.lengthSync() == 0) return [];
final content =
await file.openRead(_logFilePosition).transform(utf8.decoder).join();
_logFilePosition = file.lengthSync();
final lines = const LineSplitter().convert(content);
if (lines.length > 300) {
lines.removeRange(0, lines.length - 300);
}
for (final line in lines) {
_logBuffer.add(line);
if (_logBuffer.length > 300) {
_logBuffer.removeAt(0);
}
}
return _logBuffer;
}
}

View File

@@ -163,11 +163,18 @@ class MobileSingboxService
}
@override
Stream<String> watchLogs(String path) {
return _logsChannel.receiveBroadcastStream().map(
(event) {
// loggy.debug("received log: $event");
return event as String;
Stream<List<String>> watchLogs(String path) async* {
yield* _logsChannel
.receiveBroadcastStream()
.map((event) => (event as List).map((e) => e as String).toList());
}
@override
TaskEither<String, Unit> clearLogs() {
return TaskEither(
() async {
await _methodChannel.invokeMethod("clear_logs");
return right(unit);
},
);
}

View File

@@ -48,5 +48,7 @@ abstract interface class SingboxService {
Stream<String> watchStats();
Stream<String> watchLogs(String path);
Stream<List<String>> watchLogs(String path);
TaskEither<String, Unit> clearLogs();
}