Merge branch 'main' into ios
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user