Files
FlClash/lib/views/developer.dart
T
chen08209 8378c7081c feat(views): rework the proxies and scan pages, lay out records by their parts and unify search
A queued delay test shows a static clock until the task pool runs it, so
only the running tests animate while the list scrolls.

Changelog: Hide timed-out nodes and search every list
2026-10-02 20:32:42 +08:00

116 lines
3.6 KiB
Dart

import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/common.dart';
import 'package:fl_clash/providers/action.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class DeveloperView extends ConsumerWidget {
const DeveloperView({super.key});
Widget _getDeveloperList(BuildContext context, WidgetRef ref) {
final appLocalizations = context.appLocalizations;
return generateSectionV3(
title: appLocalizations.options,
items: [
ListItem(
title: Text(appLocalizations.messageTest),
onTap: () {
for (final level in MessageLevel.values) {
context.showNotifier(
'${level.name}: ${appLocalizations.messageTestTip}',
level: level,
);
}
},
),
ListItem(
title: Text(appLocalizations.logsTest),
onTap: () {
for (int i = 0; i < 1000; i++) {
ref
.read(logsProvider.notifier)
.add(
Log.app(
'[$i]${generateRandomString(maxLength: 200, minLength: 20)}',
),
);
}
},
),
if (globalState.canCrashCore)
ListItem(
title: Text(appLocalizations.crashTest),
onTap: () async {
final coreAction = ref.read(coreActionProvider.notifier);
final res = await dialogs.showMessage(
message: TextSpan(text: appLocalizations.confirmForceCrashCore),
);
if (res != true) {
return;
}
unawaited(coreAction.crash());
},
),
ListItem(
title: Text(appLocalizations.clearData),
onTap: () async {
final storeAction = ref.read(storeActionProvider.notifier);
final res = await dialogs.showMessage(
message: TextSpan(text: appLocalizations.confirmClearAllData),
);
if (res != true) {
return;
}
await storeAction.handleClear();
},
),
ListItem(
title: Text(appLocalizations.pruneCache),
onTap: () async {
await ref.read(storeActionProvider.notifier).shakingStore();
},
),
],
);
}
@override
Widget build(BuildContext context, ref) {
final appLocalizations = context.appLocalizations;
final enable = ref.watch(
appSettingProvider.select((state) => state.developerMode),
);
return BaseScaffold(
title: appLocalizations.developerMode,
body: ListView(
padding: const EdgeInsets.symmetric(
horizontal: 16,
).copyWith(top: context.contentTopPadding, bottom: 16),
children: [
generateSectionV3(
items: [
ListItem.toggle(
title: Text(appLocalizations.developerMode),
value: enable,
onChanged: (value) {
ref
.read(appSettingProvider.notifier)
.update((state) => state.copyWith(developerMode: value));
},
),
],
),
_getDeveloperList(context, ref),
],
),
);
}
}