Skip to content

Commit 972a788

Browse files
committed
Add logging panel
1 parent 6e1a2f0 commit 972a788

21 files changed

+733
-523
lines changed

lib/about_page.dart

Lines changed: 0 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,15 @@
1414
* limitations under the License.
1515
*/
1616

17-
import 'dart:convert';
18-
import 'dart:io';
19-
2017
import 'package:flutter/material.dart';
2118
import 'package:flutter_riverpod/flutter_riverpod.dart';
22-
import 'package:logging/logging.dart';
23-
import 'package:material_symbols_icons/symbols.dart';
2419

25-
import 'android/state.dart';
2620
import 'app/app_url_launcher.dart';
27-
import 'app/logging.dart';
28-
import 'app/message.dart';
29-
import 'app/state.dart';
3021
import 'app/views/keys.dart';
31-
import 'core/state.dart';
32-
import 'desktop/state.dart';
3322
import 'generated/l10n/app_localizations.dart';
3423
import 'version.dart';
35-
import 'widgets/choice_filter_chip.dart';
3624
import 'widgets/responsive_dialog.dart';
3725

38-
final _log = Logger('about');
39-
4026
class AboutPage extends ConsumerWidget {
4127
const AboutPage({super.key});
4228

@@ -136,120 +122,9 @@ class AboutPage extends ConsumerWidget {
136122
),
137123
],
138124
),
139-
const Padding(
140-
padding: EdgeInsets.only(top: 24.0, bottom: 8.0),
141-
child: Divider(),
142-
),
143-
Padding(
144-
padding: const EdgeInsets.symmetric(vertical: 16.0),
145-
child: Text(
146-
l10n.s_troubleshooting,
147-
style: Theme.of(context).textTheme.titleMedium,
148-
),
149-
),
150-
const LoggingPanel(),
151-
152-
// Diagnostics (desktop only)
153-
if (isDesktop) ...[
154-
const SizedBox(height: 12.0),
155-
ActionChip(
156-
key: diagnosticsChip,
157-
avatar: const Icon(Symbols.bug_report),
158-
label: Text(l10n.s_run_diagnostics),
159-
onPressed: () async {
160-
_log.info('Running diagnostics...');
161-
final response = await ref
162-
.read(rpcProvider)
163-
.requireValue
164-
.command('diagnose', []);
165-
final data = response['diagnostics'] as List;
166-
data.insert(0, {
167-
'app_version': version,
168-
'dart': Platform.version,
169-
'os': Platform.operatingSystem,
170-
'os_version': Platform.operatingSystemVersion,
171-
});
172-
data.insert(data.length - 1, ref.read(featureFlagProvider));
173-
final text = const JsonEncoder.withIndent(' ').convert(data);
174-
await ref.read(clipboardProvider).setText(text);
175-
await ref.read(withContextProvider)(
176-
(context) async {
177-
showMessage(context, l10n.l_diagnostics_copied);
178-
},
179-
);
180-
},
181-
),
182-
],
183-
184-
// Enable screenshots (Android only)
185-
if (isAndroid) ...[
186-
const SizedBox(height: 12.0),
187-
FilterChip(
188-
key: screenshotChip,
189-
label: Text(l10n.s_allow_screenshots),
190-
selected: ref.watch(androidAllowScreenshotsProvider),
191-
onSelected: (value) async {
192-
ref
193-
.read(androidAllowScreenshotsProvider.notifier)
194-
.setAllowScreenshots(value);
195-
},
196-
),
197-
],
198125
],
199126
),
200127
),
201128
);
202129
}
203130
}
204-
205-
class LoggingPanel extends ConsumerWidget {
206-
const LoggingPanel({super.key});
207-
208-
@override
209-
Widget build(BuildContext context, WidgetRef ref) {
210-
final l10n = AppLocalizations.of(context);
211-
final logLevel = ref.watch(logLevelProvider);
212-
return Wrap(
213-
alignment: WrapAlignment.center,
214-
spacing: 4.0,
215-
runSpacing: 8.0,
216-
children: [
217-
ChoiceFilterChip<Level>(
218-
avatar: Icon(
219-
Symbols.insights,
220-
color: Theme.of(context).colorScheme.primary,
221-
),
222-
value: logLevel,
223-
items: Levels.LEVELS,
224-
selected: logLevel != Level.INFO,
225-
labelBuilder: (value) => Text(l10n.s_log_level(
226-
value.name[0] + value.name.substring(1).toLowerCase())),
227-
itemBuilder: (value) =>
228-
Text('${value.name[0]}${value.name.substring(1).toLowerCase()}'),
229-
onChanged: (level) {
230-
ref.read(logLevelProvider.notifier).setLogLevel(level);
231-
_log.debug('Log level set to $level');
232-
},
233-
),
234-
ActionChip(
235-
key: logChip,
236-
avatar: const Icon(Symbols.content_copy),
237-
label: Text(l10n.s_copy_log),
238-
onPressed: () async {
239-
_log.info('Copying log to clipboard ($version)...');
240-
final logs = await ref.read(logLevelProvider.notifier).getLogs();
241-
var clipboard = ref.read(clipboardProvider);
242-
await clipboard.setText(logs.join('\n'));
243-
if (!clipboard.platformGivesFeedback()) {
244-
await ref.read(withContextProvider)(
245-
(context) async {
246-
showMessage(context, l10n.l_log_copied);
247-
},
248-
);
249-
}
250-
},
251-
),
252-
],
253-
);
254-
}
255-
}

lib/android/init.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ Future<Widget> initialize() async {
8282
clipboardProvider.overrideWith(
8383
(ref) => ref.watch(androidClipboardProvider),
8484
),
85+
logPanelVisibilityProvider
86+
.overrideWith((ref) => LogPanelVisibilityNotifier(kDebugMode)),
8587
androidSdkVersionProvider.overrideWithValue(await getAndroidSdkVersion()),
8688
androidNfcSupportProvider.overrideWithValue(await getHasNfc()),
8789
supportedSectionsProvider.overrideWithValue([

lib/android/keys.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const readFromImage = Key('$_prefix.read_image_file');
2727
const nfcBypassTouchSetting = Key('$_prefix.nfc_bypass_touch');
2828
const nfcSilenceSoundsSettings = Key('$_prefix.nfc_silence_sounds');
2929
const usbOpenApp = Key('$_prefix.usb_open_app');
30+
const allowScreenshotsSetting = Key('$_prefix.allow_screenshots');
3031

3132
const nfcTapSetting = Key('$_prefix.nfc_tap');
3233
Key nfcTapOption(NfcTapAction action) =>

lib/android/views/settings_views.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,23 @@ class UsbOpenAppView extends ConsumerWidget {
187187
});
188188
}
189189
}
190+
191+
class AllowScreenshotsView extends ConsumerWidget {
192+
const AllowScreenshotsView({super.key});
193+
194+
@override
195+
Widget build(BuildContext context, WidgetRef ref) {
196+
final l10n = AppLocalizations.of(context);
197+
final allowScreenshots = ref.watch(androidAllowScreenshotsProvider);
198+
return SwitchListTile(
199+
title: Text(l10n.s_allow_screenshots),
200+
subtitle: Text(l10n.l_allow_screenshots_desc),
201+
value: allowScreenshots,
202+
key: keys.allowScreenshotsSetting,
203+
onChanged: (value) {
204+
ref
205+
.read(androidAllowScreenshotsProvider.notifier)
206+
.setAllowScreenshots(value);
207+
});
208+
}
209+
}

lib/app/app.dart

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
2121

2222
import '../generated/l10n/app_localizations.dart';
2323
import '../theme.dart';
24-
import 'logging.dart';
2524
import 'shortcuts.dart';
2625
import 'state.dart';
2726

@@ -31,26 +30,24 @@ class YubicoAuthenticatorApp extends StatelessWidget {
3130

3231
@override
3332
Widget build(BuildContext context) => GlobalShortcuts(
34-
child: LogWarningOverlay(
35-
child: Consumer(builder: (context, ref, _) {
36-
final primaryColor = ref.watch(primaryColorProvider);
37-
return MaterialApp(
38-
title: ref.watch(l10nProvider).app_name,
39-
theme: AppTheme.getLightTheme(primaryColor),
40-
darkTheme: AppTheme.getDarkTheme(primaryColor),
41-
themeMode: ref.watch(themeModeProvider),
42-
home: page,
43-
debugShowCheckedModeBanner: false,
44-
locale: ref.watch(currentLocaleProvider),
45-
supportedLocales: AppLocalizations.supportedLocales,
46-
localizationsDelegates: const [
47-
AppLocalizations.delegate,
48-
GlobalMaterialLocalizations.delegate,
49-
GlobalWidgetsLocalizations.delegate,
50-
GlobalCupertinoLocalizations.delegate,
51-
],
52-
);
53-
}),
54-
),
33+
child: Consumer(builder: (context, ref, _) {
34+
final primaryColor = ref.watch(primaryColorProvider);
35+
return MaterialApp(
36+
title: ref.watch(l10nProvider).app_name,
37+
theme: AppTheme.getLightTheme(primaryColor),
38+
darkTheme: AppTheme.getDarkTheme(primaryColor),
39+
themeMode: ref.watch(themeModeProvider),
40+
home: page,
41+
debugShowCheckedModeBanner: false,
42+
locale: ref.watch(currentLocaleProvider),
43+
supportedLocales: AppLocalizations.supportedLocales,
44+
localizationsDelegates: const [
45+
AppLocalizations.delegate,
46+
GlobalMaterialLocalizations.delegate,
47+
GlobalWidgetsLocalizations.delegate,
48+
GlobalCupertinoLocalizations.delegate,
49+
],
50+
);
51+
}),
5552
);
5653
}

0 commit comments

Comments
 (0)