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/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:outline_material_icons/outline_material_icons.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class DebugPage extends StatefulWidget { class DebugPage extends StatefulWidget {
@ -42,194 +43,229 @@ class DebugPageState extends State<DebugPage> {
@override @override
Widget build(BuildContext context) { 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( return MediaQueryDataProvider(
child: Scaffold( child: DefaultTabController(
appBar: AppBar( length: 3,
title: const Text('Debug'), child: Scaffold(
), appBar: AppBar(
body: SafeArea( title: const Text('Debug'),
child: ListView( bottom: TabBar(
padding: const EdgeInsets.all(8), tabs: [
children: [ Tab(icon: Icon(OMIcons.whatshot)),
const Text('Storage'), Tab(icon: Icon(OMIcons.settings)),
FutureBuilder( Tab(icon: Icon(OMIcons.sdStorage)),
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(); body: SafeArea(
final permissions = snapshot.data; child: TabBarView(
return Column( children: [
crossAxisAlignment: CrossAxisAlignment.start, _buildGeneralTabView(),
children: [ _buildSettingsTabView(),
...AndroidFileUtils.storageVolumes.expand((v) => [ _buildStorageTabView(),
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',
),
],
), ),
), ),
), ),
); );
} }
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() { void _startDbReport() {
_dbFileSizeLoader = metadataDb.dbFileSize(); _dbFileSizeLoader = metadataDb.dbFileSize();
_dbDateLoader = metadataDb.loadDates(); _dbDateLoader = metadataDb.loadDates();

View file

@ -28,6 +28,7 @@ class _FullscreenDebugPageState extends State<FullscreenDebugPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final catalog = widget.entry.catalogMetadata;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Debug'), title: const Text('Debug'),
@ -103,7 +104,18 @@ class _FullscreenDebugPageState extends State<FullscreenDebugPage> {
}, },
), ),
const Divider(), 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}',
}),
], ],
), ),
), ),