improved debug pages

This commit is contained in:
Thibault Deckers 2020-05-12 18:48:19 +09:00
parent 8696dc9a93
commit c351e4a785
2 changed files with 230 additions and 182 deletions

View file

@ -12,6 +12,7 @@ import 'package:aves/widgets/fullscreen/info/info_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:outline_material_icons/outline_material_icons.dart';
import 'package:tuple/tuple.dart';
class DebugPage extends StatefulWidget {
@ -42,194 +43,229 @@ class DebugPageState extends State<DebugPage> {
@override
Widget build(BuildContext context) {
final catalogued = entries.where((entry) => entry.isCatalogued);
final withGps = catalogued.where((entry) => entry.hasGps);
final located = withGps.where((entry) => entry.isLocated);
return MediaQueryDataProvider(
child: Scaffold(
appBar: AppBar(
title: const Text('Debug'),
),
body: SafeArea(
child: ListView(
padding: const EdgeInsets.all(8),
children: [
const Text('Storage'),
FutureBuilder(
future: _volumePermissionLoader,
builder: (context, AsyncSnapshot<List<Tuple2<String, bool>>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final permissions = snapshot.data;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...AndroidFileUtils.storageVolumes.expand((v) => [
const SizedBox(height: 16),
Text(v.path),
InfoRowGroup({
'description': '${v.description}',
'isEmulated': '${v.isEmulated}',
'isPrimary': '${v.isPrimary}',
'isRemovable': '${v.isRemovable}',
'state': '${v.state}',
'permission': '${permissions.firstWhere((t) => t.item1 == v.path, orElse: () => null)?.item2 ?? false}',
}),
])
],
);
},
),
const Divider(),
Row(
children: [
const Text('Settings'),
const Spacer(),
RaisedButton(
onPressed: () => settings.reset().then((_) => setState(() {})),
child: const Text('Reset'),
),
],
),
Text('collectionGroupFactor: ${settings.collectionGroupFactor}'),
Text('collectionSortFactor: ${settings.collectionSortFactor}'),
Text('collectionTileExtent: ${settings.collectionTileExtent}'),
Text('infoMapZoom: ${settings.infoMapZoom}'),
const Divider(),
Text('Entries: ${entries.length}'),
Text('Catalogued: ${catalogued.length}'),
Text('With GPS: ${withGps.length}'),
Text('With address: ${located.length}'),
const Divider(),
FutureBuilder(
future: _dbFileSizeLoader,
builder: (context, AsyncSnapshot<int> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB file size: ${formatFilesize(snapshot.data)}'),
const Spacer(),
RaisedButton(
onPressed: () => metadataDb.reset().then((_) => _startDbReport()),
child: const Text('Reset'),
),
],
);
},
),
FutureBuilder(
future: _dbDateLoader,
builder: (context, AsyncSnapshot<List<DateMetadata>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB date rows: ${snapshot.data.length}'),
const Spacer(),
RaisedButton(
onPressed: () => metadataDb.clearDates().then((_) => _startDbReport()),
child: const Text('Clear'),
),
],
);
},
),
FutureBuilder(
future: _dbMetadataLoader,
builder: (context, AsyncSnapshot<List<CatalogMetadata>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB metadata rows: ${snapshot.data.length}'),
const Spacer(),
RaisedButton(
onPressed: () => metadataDb.clearMetadataEntries().then((_) => _startDbReport()),
child: const Text('Clear'),
),
],
);
},
),
FutureBuilder(
future: _dbAddressLoader,
builder: (context, AsyncSnapshot<List<AddressDetails>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB address rows: ${snapshot.data.length}'),
const Spacer(),
RaisedButton(
onPressed: () => metadataDb.clearAddresses().then((_) => _startDbReport()),
child: const Text('Clear'),
),
],
);
},
),
FutureBuilder(
future: _dbFavouritesLoader,
builder: (context, AsyncSnapshot<List<FavouriteRow>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB favourite rows: ${snapshot.data.length} (${favourites.count} in memory)'),
const Spacer(),
RaisedButton(
onPressed: () => favourites.clear().then((_) => _startDbReport()),
child: const Text('Clear'),
),
],
);
},
),
const Divider(),
Row(
children: [
Text('Image cache: ${imageCache.currentSize} items, ${formatFilesize(imageCache.currentSizeBytes)}'),
const Spacer(),
RaisedButton(
onPressed: () {
imageCache.clear();
setState(() {});
},
child: const Text('Clear'),
),
],
),
Row(
children: [
Text('SVG cache: ${PictureProvider.cacheCount} items'),
const Spacer(),
RaisedButton(
onPressed: () {
PictureProvider.clearCache();
setState(() {});
},
child: const Text('Clear'),
),
],
),
const Divider(),
const Text('Time dilation'),
Slider(
value: timeDilation,
onChanged: (v) => setState(() => timeDilation = v),
min: 1.0,
max: 10.0,
divisions: 9,
label: '$timeDilation',
),
],
child: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: const Text('Debug'),
bottom: TabBar(
tabs: [
Tab(icon: Icon(OMIcons.whatshot)),
Tab(icon: Icon(OMIcons.settings)),
Tab(icon: Icon(OMIcons.sdStorage)),
],
),
),
body: SafeArea(
child: TabBarView(
children: [
_buildGeneralTabView(),
_buildSettingsTabView(),
_buildStorageTabView(),
],
),
),
),
),
);
}
Widget _buildGeneralTabView() {
final catalogued = entries.where((entry) => entry.isCatalogued);
final withGps = catalogued.where((entry) => entry.hasGps);
final located = withGps.where((entry) => entry.isLocated);
return ListView(
padding: const EdgeInsets.all(16),
children: [
const Text('Time dilation'),
Slider(
value: timeDilation,
onChanged: (v) => setState(() => timeDilation = v),
min: 1.0,
max: 10.0,
divisions: 9,
label: '$timeDilation',
),
const Divider(),
Text('Entries: ${entries.length}'),
Text('Catalogued: ${catalogued.length}'),
Text('With GPS: ${withGps.length}'),
Text('With address: ${located.length}'),
const Divider(),
Row(
children: [
Text('Image cache: ${imageCache.currentSize} items, ${formatFilesize(imageCache.currentSizeBytes)}'),
const Spacer(),
RaisedButton(
onPressed: () {
imageCache.clear();
setState(() {});
},
child: const Text('Clear'),
),
],
),
Row(
children: [
Text('SVG cache: ${PictureProvider.cacheCount} items'),
const Spacer(),
RaisedButton(
onPressed: () {
PictureProvider.clearCache();
setState(() {});
},
child: const Text('Clear'),
),
],
),
const Divider(),
FutureBuilder(
future: _dbFileSizeLoader,
builder: (context, AsyncSnapshot<int> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB file size: ${formatFilesize(snapshot.data)}'),
const Spacer(),
RaisedButton(
onPressed: () => metadataDb.reset().then((_) => _startDbReport()),
child: const Text('Reset'),
),
],
);
},
),
FutureBuilder(
future: _dbDateLoader,
builder: (context, AsyncSnapshot<List<DateMetadata>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB date rows: ${snapshot.data.length}'),
const Spacer(),
RaisedButton(
onPressed: () => metadataDb.clearDates().then((_) => _startDbReport()),
child: const Text('Clear'),
),
],
);
},
),
FutureBuilder(
future: _dbMetadataLoader,
builder: (context, AsyncSnapshot<List<CatalogMetadata>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB metadata rows: ${snapshot.data.length}'),
const Spacer(),
RaisedButton(
onPressed: () => metadataDb.clearMetadataEntries().then((_) => _startDbReport()),
child: const Text('Clear'),
),
],
);
},
),
FutureBuilder(
future: _dbAddressLoader,
builder: (context, AsyncSnapshot<List<AddressDetails>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB address rows: ${snapshot.data.length}'),
const Spacer(),
RaisedButton(
onPressed: () => metadataDb.clearAddresses().then((_) => _startDbReport()),
child: const Text('Clear'),
),
],
);
},
),
FutureBuilder(
future: _dbFavouritesLoader,
builder: (context, AsyncSnapshot<List<FavouriteRow>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row(
children: [
Text('DB favourite rows: ${snapshot.data.length} (${favourites.count} in memory)'),
const Spacer(),
RaisedButton(
onPressed: () => favourites.clear().then((_) => _startDbReport()),
child: const Text('Clear'),
),
],
);
},
),
],
);
}
Widget _buildSettingsTabView() {
return ListView(
padding: const EdgeInsets.all(16),
children: [
Row(
children: [
const Text('Settings'),
const Spacer(),
RaisedButton(
onPressed: () => settings.reset().then((_) => setState(() {})),
child: const Text('Reset'),
),
],
),
InfoRowGroup({
'collectionGroupFactor': '${settings.collectionGroupFactor}',
'collectionSortFactor': '${settings.collectionSortFactor}',
'collectionTileExtent': '${settings.collectionTileExtent}',
'infoMapZoom': '${settings.infoMapZoom}',
}),
],
);
}
Widget _buildStorageTabView() {
return ListView(
padding: const EdgeInsets.all(16),
children: [
FutureBuilder(
future: _volumePermissionLoader,
builder: (context, AsyncSnapshot<List<Tuple2<String, bool>>> snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final permissions = snapshot.data;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...AndroidFileUtils.storageVolumes.expand((v) => [
Text(v.path),
InfoRowGroup({
'description': '${v.description}',
'isEmulated': '${v.isEmulated}',
'isPrimary': '${v.isPrimary}',
'isRemovable': '${v.isRemovable}',
'state': '${v.state}',
'permission': '${permissions.firstWhere((t) => t.item1 == v.path, orElse: () => null)?.item2 ?? false}',
}),
const Divider(),
])
],
);
},
),
],
);
}
void _startDbReport() {
_dbFileSizeLoader = metadataDb.dbFileSize();
_dbDateLoader = metadataDb.loadDates();

View file

@ -28,6 +28,7 @@ class _FullscreenDebugPageState extends State<FullscreenDebugPage> {
@override
Widget build(BuildContext context) {
final catalog = widget.entry.catalogMetadata;
return Scaffold(
appBar: AppBar(
title: const Text('Debug'),
@ -103,7 +104,18 @@ class _FullscreenDebugPageState extends State<FullscreenDebugPage> {
},
),
const Divider(),
Text('Catalog metadata: ${widget.entry.catalogMetadata}'),
Text('Catalog metadata:${catalog == null ? ' no data' : ''}'),
if (catalog != null)
InfoRowGroup({
'contentId': '${catalog.contentId}',
'dateMillis': '${catalog.dateMillis}',
'isAnimated': '${catalog.isAnimated}',
'videoRotation': '${catalog.videoRotation}',
'latitude': '${catalog.latitude}',
'longitude': '${catalog.longitude}',
'xmpSubjects': '${catalog.xmpSubjects}',
'xmpTitleDescription': '${catalog.xmpTitleDescription}',
}),
],
),
),