feat:参照研听的基础工程
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
import '../../../common/config/shorebird_service.dart';
|
||||
import '../../../common/network/auth_interceptor.dart';
|
||||
import '../../../common/network/dio_provider.dart';
|
||||
import '../../../common/router/app_router.dart';
|
||||
import '../../../common/services/device_header_service.dart';
|
||||
import '../../../common/storage/storage_keys.dart';
|
||||
import '../../../common/storage/storage_service.dart';
|
||||
import '../../../common/theme/theme_controller.dart';
|
||||
|
||||
class DebugInfoPage extends ConsumerWidget {
|
||||
const DebugInfoPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final appConfig = ref.watch(appConfigProvider);
|
||||
final dio = ref.watch(dioProvider);
|
||||
final themeMode = ref.watch(themeModeControllerProvider);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
if (context.canPop()) {
|
||||
context.pop();
|
||||
} else {
|
||||
context.go(AppRoutes.debug);
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back_ios_new),
|
||||
),
|
||||
title: const Text('Info'),
|
||||
),
|
||||
body: FutureBuilder<_DebugInfoSnapshot>(
|
||||
future: _loadSnapshot(
|
||||
apiBaseUrl: appConfig.apiBaseUrl,
|
||||
themeMode: themeMode.name,
|
||||
dio: dio,
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
final text = snapshot.data?.text ?? 'loading...';
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: SelectableText(text, style: const TextStyle(fontSize: 12)),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<_DebugInfoSnapshot> _loadSnapshot({
|
||||
required String apiBaseUrl,
|
||||
required String themeMode,
|
||||
required Dio dio,
|
||||
}) async {
|
||||
await DeviceHeaderService.to.ensureInitialized();
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final deviceInfo = await _readDeviceInfo();
|
||||
final storage = StorageService.to;
|
||||
final jwt = await loadJwt();
|
||||
final commonHeaders = DeviceHeaderService.to.commonHeaders();
|
||||
final platformHeaders = DeviceHeaderService.to.platformIdentityHeaders();
|
||||
final headers = <String, dynamic>{
|
||||
...commonHeaders,
|
||||
...platformHeaders,
|
||||
...dio.options.headers,
|
||||
};
|
||||
final gitVersion = const String.fromEnvironment(
|
||||
'GITVERSION',
|
||||
defaultValue: 'unknown',
|
||||
);
|
||||
final patch = ShorebirdService.instance.currentPatch;
|
||||
final jwtLine = jwt?.isNotEmpty == true ? 'Bearer <redacted>' : '';
|
||||
|
||||
final text = StringBuffer()
|
||||
..writeln('[build]')
|
||||
..writeln('app_name: ${packageInfo.appName}')
|
||||
..writeln('mode: ${kReleaseMode ? 'release' : 'debug'}')
|
||||
..writeln('package_name: ${packageInfo.packageName}')
|
||||
..writeln('version: ${packageInfo.version}')
|
||||
..writeln('build_number: ${packageInfo.buildNumber}')
|
||||
..writeln('theme_mode: $themeMode')
|
||||
..writeln('platform: ${defaultTargetPlatform.name}')
|
||||
..writeln('is_web: $kIsWeb')
|
||||
..writeln()
|
||||
..writeln('[environment]')
|
||||
..writeln('api_base: $apiBaseUrl')
|
||||
..writeln(
|
||||
'connect_timeout_ms: ${dio.options.connectTimeout?.inMilliseconds}',
|
||||
)
|
||||
..writeln(
|
||||
'receive_timeout_ms: ${dio.options.receiveTimeout?.inMilliseconds}',
|
||||
)
|
||||
..writeln('response_type: ${dio.options.responseType.name}')
|
||||
..writeln('git_version: $gitVersion')
|
||||
..writeln()
|
||||
..writeln('[storage]')
|
||||
..writeln('privacy_agreed: ${storage.getBool(storagePrivacyAgreed)}')
|
||||
..writeln('ios_startup_seen: ${storage.getBool(storageIosStartupSeen)}')
|
||||
..writeln('device_id: ${DeviceHeaderService.to.deviceId}')
|
||||
..writeln('android_id: ${storage.getString(storageAndroidId) ?? ''}')
|
||||
..writeln('device_token: ${storage.getString(storageDeviceToken) ?? ''}')
|
||||
..writeln('android_oaid: ${storage.getString(storageAndroidOaid) ?? ''}')
|
||||
..writeln('android_imei: ${storage.getString(storageAndroidImei) ?? ''}')
|
||||
..writeln('android_mac: ${storage.getString(storageAndroidMac) ?? ''}')
|
||||
..writeln('ios_idfa: ${storage.getString(storageIosIdfa) ?? ''}')
|
||||
..writeln('ios_paid: ${storage.getString(storageIosPaid) ?? ''}')
|
||||
..writeln()
|
||||
..writeln('[auth]')
|
||||
..writeln('jwt: $jwtLine')
|
||||
..writeln()
|
||||
..writeln('[headers]')
|
||||
..writeln('common: $commonHeaders')
|
||||
..writeln('platform: $platformHeaders')
|
||||
..writeln('dio: $headers')
|
||||
..writeln()
|
||||
..writeln('[shorebird]')
|
||||
..writeln('current_patch: ${patch?.number ?? 'none'}')
|
||||
..writeln('patch: ${patch ?? 'none'}')
|
||||
..writeln()
|
||||
..writeln('[device]')
|
||||
..writeln(deviceInfo);
|
||||
|
||||
return _DebugInfoSnapshot(text.toString());
|
||||
}
|
||||
|
||||
Future<String> _readDeviceInfo() async {
|
||||
try {
|
||||
if (!kIsWeb &&
|
||||
defaultTargetPlatform == TargetPlatform.android &&
|
||||
!StorageService.to.getBool(storagePrivacyAgreed)) {
|
||||
return 'privacy policy not accepted; device info not read';
|
||||
}
|
||||
final plugin = DeviceInfoPlugin();
|
||||
if (kIsWeb) {
|
||||
final info = await plugin.webBrowserInfo;
|
||||
return info.data.toString();
|
||||
}
|
||||
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
final info = await plugin.androidInfo;
|
||||
return info.data.toString();
|
||||
case TargetPlatform.iOS:
|
||||
final info = await plugin.iosInfo;
|
||||
return info.data.toString();
|
||||
case TargetPlatform.macOS:
|
||||
final info = await plugin.macOsInfo;
|
||||
return info.data.toString();
|
||||
case TargetPlatform.windows:
|
||||
final info = await plugin.windowsInfo;
|
||||
return info.data.toString();
|
||||
case TargetPlatform.linux:
|
||||
final info = await plugin.linuxInfo;
|
||||
return info.data.toString();
|
||||
case TargetPlatform.fuchsia:
|
||||
return 'fuchsia';
|
||||
}
|
||||
} catch (error) {
|
||||
return 'unavailable: $error';
|
||||
}
|
||||
}
|
||||
|
||||
class _DebugInfoSnapshot {
|
||||
const _DebugInfoSnapshot(this.text);
|
||||
|
||||
final String text;
|
||||
}
|
||||
Reference in New Issue
Block a user