Add debug mode
This commit is contained in:
@@ -78,7 +78,9 @@
|
||||
"pageTitle": "logs",
|
||||
"clearLogsButtonText": "clear",
|
||||
"filterHint": "filter",
|
||||
"allLevelsFilter": "all"
|
||||
"allLevelsFilter": "all",
|
||||
"shareCoreLogs": "share core logs",
|
||||
"shareAppLogs": "share app logs"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "settings",
|
||||
@@ -120,7 +122,9 @@
|
||||
"miscellaneous": {
|
||||
"sectionTitle": "miscellaneous",
|
||||
"connectionTestUrl": "connection test url",
|
||||
"concurrentTestCount": "concurrent test count"
|
||||
"concurrentTestCount": "concurrent test count",
|
||||
"debugMode": "debug mode",
|
||||
"debugModeMsg": "restart the app for this to take effect"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
|
||||
@@ -78,7 +78,9 @@
|
||||
"pageTitle": "لاگها",
|
||||
"clearLogsButtonText": "پاکسازی",
|
||||
"filterHint": "فیلتر",
|
||||
"allLevelsFilter": "همه"
|
||||
"allLevelsFilter": "همه",
|
||||
"shareCoreLogs": "اشتراکگذاری لاگ هسته",
|
||||
"shareAppLogs": "اشتراکگذاری لاگ برنامه"
|
||||
},
|
||||
"settings": {
|
||||
"pageTitle": "تنظیمات",
|
||||
@@ -120,7 +122,9 @@
|
||||
"miscellaneous": {
|
||||
"sectionTitle": "متفرقه",
|
||||
"connectionTestUrl": "لینک تست کانکشن",
|
||||
"concurrentTestCount": "شمار تست همزمان"
|
||||
"concurrentTestCount": "شمار تست همزمان",
|
||||
"debugMode": "دیباگ مود",
|
||||
"debugModeMsg": "برای اعمال این تغییر اپ را ریاستارت کنید"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||
import 'package:hiddify/core/app/app.dart';
|
||||
import 'package:hiddify/core/prefs/misc_prefs.dart';
|
||||
import 'package:hiddify/core/prefs/prefs.dart';
|
||||
import 'package:hiddify/data/data_providers.dart';
|
||||
import 'package:hiddify/features/common/active_profile/active_profile_notifier.dart';
|
||||
@@ -41,10 +42,12 @@ Future<void> lazyBootstrap(WidgetsBinding widgetsBinding) async {
|
||||
overrides: [sharedPreferencesProvider.overrideWithValue(sharedPreferences)],
|
||||
);
|
||||
|
||||
final debug = container.read(debugModeProvider) || kDebugMode;
|
||||
|
||||
final filesEditor = container.read(filesEditorServiceProvider);
|
||||
await filesEditor.init();
|
||||
|
||||
initLoggers(container.read);
|
||||
initLoggers(container.read, debug);
|
||||
_loggy.info(
|
||||
"os: ${Platform.operatingSystem}(${Platform.operatingSystemVersion})",
|
||||
);
|
||||
@@ -76,9 +79,10 @@ Future<void> lazyBootstrap(WidgetsBinding widgetsBinding) async {
|
||||
|
||||
void initLoggers(
|
||||
Result Function<Result>(ProviderListenable<Result>) read,
|
||||
bool debug,
|
||||
) {
|
||||
const logLevel = kDebugMode ? LogLevel.all : LogLevel.info;
|
||||
final logToFile = !Platform.isAndroid && !Platform.isIOS;
|
||||
final logLevel = debug ? LogLevel.all : LogLevel.info;
|
||||
final logToFile = debug || (!Platform.isAndroid && !Platform.isIOS);
|
||||
Loggy.initLoggy(
|
||||
logPrinter: MultiLogPrinter(
|
||||
const PrettyPrinter(),
|
||||
@@ -86,8 +90,7 @@ void initLoggers(
|
||||
? FileLogPrinter(read(filesEditorServiceProvider).appLogsPath)
|
||||
: null,
|
||||
),
|
||||
// ignore: avoid_redundant_argument_values
|
||||
logOptions: const LogOptions(logLevel),
|
||||
logOptions: LogOptions(logLevel),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,3 +8,5 @@ final concurrentTestCountProvider = PrefNotifier.provider(
|
||||
"concurrent_test_count",
|
||||
Defaults.concurrentTestCount,
|
||||
);
|
||||
|
||||
final debugModeProvider = PrefNotifier.provider("debug_mode", false);
|
||||
|
||||
@@ -98,7 +98,7 @@ class CoreFacadeImpl with ExceptionHandler, InfraLogger implements CoreFacade {
|
||||
@override
|
||||
Stream<Either<CoreServiceFailure, String>> watchLogs() {
|
||||
return singbox
|
||||
.watchLogs(filesEditor.logsPath)
|
||||
.watchLogs(filesEditor.coreLogsPath)
|
||||
.handleExceptions(CoreServiceFailure.unexpected);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hiddify/core/core_providers.dart';
|
||||
import 'package:hiddify/core/prefs/misc_prefs.dart';
|
||||
import 'package:hiddify/domain/clash/clash.dart';
|
||||
import 'package:hiddify/domain/failures.dart';
|
||||
import 'package:hiddify/features/common/common.dart';
|
||||
import 'package:hiddify/features/logs/notifier/notifier.dart';
|
||||
import 'package:hiddify/services/service_providers.dart';
|
||||
import 'package:hiddify/utils/utils.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:recase/recase.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:tint/tint.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class LogsPage extends HookConsumerWidget {
|
||||
const LogsPage({super.key});
|
||||
@@ -21,6 +27,45 @@ class LogsPage extends HookConsumerWidget {
|
||||
final asyncState = ref.watch(logsNotifierProvider);
|
||||
final notifier = ref.watch(logsNotifierProvider.notifier);
|
||||
|
||||
final debug = ref.watch(debugModeProvider);
|
||||
|
||||
final List<PopupMenuEntry> popupButtons = debug || PlatformUtils.isDesktop
|
||||
? [
|
||||
PopupMenuItem(
|
||||
child: Text(t.logs.shareCoreLogs.sentenceCase),
|
||||
onTap: () async {
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await launchUrl(
|
||||
ref.read(filesEditorServiceProvider).logsDir.uri,
|
||||
);
|
||||
} else {
|
||||
final file = XFile(
|
||||
ref.read(filesEditorServiceProvider).coreLogsPath,
|
||||
mimeType: "text/plain",
|
||||
);
|
||||
await Share.shareXFiles([file]);
|
||||
}
|
||||
},
|
||||
),
|
||||
PopupMenuItem(
|
||||
child: Text(t.logs.shareAppLogs.sentenceCase),
|
||||
onTap: () async {
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await launchUrl(
|
||||
ref.read(filesEditorServiceProvider).logsDir.uri,
|
||||
);
|
||||
} else {
|
||||
final file = XFile(
|
||||
ref.read(filesEditorServiceProvider).appLogsPath,
|
||||
mimeType: "text/plain",
|
||||
);
|
||||
await Share.shareXFiles([file]);
|
||||
}
|
||||
},
|
||||
),
|
||||
]
|
||||
: [];
|
||||
|
||||
switch (asyncState) {
|
||||
case AsyncData(value: final state):
|
||||
return Scaffold(
|
||||
@@ -28,6 +73,14 @@ class LogsPage extends HookConsumerWidget {
|
||||
// TODO: fix height
|
||||
toolbarHeight: 90,
|
||||
title: Text(t.logs.pageTitle.titleCase),
|
||||
actions: [
|
||||
if (popupButtons.isNotEmpty)
|
||||
PopupMenuButton(
|
||||
itemBuilder: (context) {
|
||||
return popupButtons;
|
||||
},
|
||||
),
|
||||
],
|
||||
bottom: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(36),
|
||||
child: Padding(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hiddify/core/core_providers.dart';
|
||||
import 'package:hiddify/core/prefs/misc_prefs.dart';
|
||||
import 'package:hiddify/domain/constants.dart';
|
||||
@@ -16,6 +17,7 @@ class MiscellaneousSettingTiles extends HookConsumerWidget {
|
||||
|
||||
final connectionTestUrl = ref.watch(connectionTestUrlProvider);
|
||||
final concurrentTestCount = ref.watch(concurrentTestCountProvider);
|
||||
final debug = ref.watch(debugModeProvider);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
@@ -37,7 +39,7 @@ class MiscellaneousSettingTiles extends HookConsumerWidget {
|
||||
subtitle: Text(concurrentTestCount.toString()),
|
||||
onTap: () async {
|
||||
final val = await SettingsInputDialog<int>(
|
||||
title: t.settings.miscellaneous.connectionTestUrl.titleCase,
|
||||
title: t.settings.miscellaneous.concurrentTestCount.titleCase,
|
||||
initialValue: concurrentTestCount,
|
||||
resetValue: Defaults.concurrentTestCount,
|
||||
mapTo: (value) => int.tryParse(value),
|
||||
@@ -47,6 +49,34 @@ class MiscellaneousSettingTiles extends HookConsumerWidget {
|
||||
await ref.read(concurrentTestCountProvider.notifier).update(val);
|
||||
},
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(t.settings.miscellaneous.debugMode.titleCase),
|
||||
value: debug,
|
||||
onChanged: (value) async {
|
||||
if (value) {
|
||||
await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(t.settings.miscellaneous.debugMode.titleCase),
|
||||
content: Text(
|
||||
t.settings.miscellaneous.debugModeMsg.sentenceCase,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(true),
|
||||
child: Text(
|
||||
MaterialLocalizations.of(context).okButtonLabel,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
await ref.read(debugModeProvider.notifier).update(value);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ class FilesEditorService with InfraLogger {
|
||||
late final Directory baseDir;
|
||||
late final Directory workingDir;
|
||||
late final Directory tempDir;
|
||||
late final Directory logsDir;
|
||||
late final Directory _configsDir;
|
||||
|
||||
Future<void> init() async {
|
||||
@@ -24,10 +25,12 @@ class FilesEditorService with InfraLogger {
|
||||
workingDir = await getApplicationDocumentsDirectory();
|
||||
}
|
||||
tempDir = await getTemporaryDirectory();
|
||||
logsDir = workingDir;
|
||||
|
||||
loggy.debug("base dir: ${baseDir.path}");
|
||||
loggy.debug("working dir: ${workingDir.path}");
|
||||
loggy.debug("temp dir: ${tempDir.path}");
|
||||
loggy.debug("logs dire: ${logsDir.path}");
|
||||
|
||||
_configsDir =
|
||||
Directory(p.join(workingDir.path, Constants.configsFolderName));
|
||||
@@ -49,13 +52,12 @@ class FilesEditorService with InfraLogger {
|
||||
}
|
||||
|
||||
await _populateGeoAssets();
|
||||
if (PlatformUtils.isDesktop) {
|
||||
final logFile = File(logsPath);
|
||||
if (await logFile.exists()) {
|
||||
await logFile.writeAsString("");
|
||||
|
||||
final coreLogFile = File(coreLogsPath);
|
||||
if (await coreLogFile.exists()) {
|
||||
await coreLogFile.writeAsString("");
|
||||
} else {
|
||||
await logFile.create(recursive: true);
|
||||
}
|
||||
await coreLogFile.create(recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,8 +70,8 @@ class FilesEditorService with InfraLogger {
|
||||
return getApplicationDocumentsDirectory();
|
||||
}
|
||||
|
||||
String get appLogsPath => p.join(workingDir.path, "app.log");
|
||||
String get logsPath => p.join(workingDir.path, "box.log");
|
||||
String get appLogsPath => p.join(logsDir.path, "app.log");
|
||||
String get coreLogsPath => p.join(logsDir.path, "box.log");
|
||||
|
||||
String configPath(String fileName) {
|
||||
return p.join(_configsDir.path, "$fileName.json");
|
||||
|
||||
Reference in New Issue
Block a user