Compare commits
1 commit
develop
...
977_catalo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5c1db57965 |
8 changed files with 91 additions and 3 deletions
|
@ -302,6 +302,7 @@ open class MainActivity : FlutterFragmentActivity() {
|
||||||
INTENT_DATA_KEY_PAGE to intent.getStringExtra(EXTRA_KEY_PAGE),
|
INTENT_DATA_KEY_PAGE to intent.getStringExtra(EXTRA_KEY_PAGE),
|
||||||
INTENT_DATA_KEY_FILTERS to extractFiltersFromIntent(intent),
|
INTENT_DATA_KEY_FILTERS to extractFiltersFromIntent(intent),
|
||||||
INTENT_DATA_KEY_EXPLORER_PATH to intent.getStringExtra(EXTRA_KEY_EXPLORER_PATH),
|
INTENT_DATA_KEY_EXPLORER_PATH to intent.getStringExtra(EXTRA_KEY_EXPLORER_PATH),
|
||||||
|
INTENT_DATA_KEY_DEBUG to intent.getBooleanExtra(EXTRA_KEY_DEBUG, false),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +534,17 @@ open class MainActivity : FlutterFragmentActivity() {
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val shortcutInfoList = listOf(videos, search, map)
|
val debug = ShortcutInfoCompat.Builder(this, "debug")
|
||||||
|
.setShortLabel("debug")
|
||||||
|
.setIntent(
|
||||||
|
Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java)
|
||||||
|
.putExtra(EXTRA_KEY_DEBUG, true)
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
// val shortcutInfoList = listOf(videos, search, map)
|
||||||
|
val shortcutInfoList = listOf(debug)
|
||||||
|
|
||||||
ShortcutManagerCompat.setDynamicShortcuts(this, shortcutInfoList)
|
ShortcutManagerCompat.setDynamicShortcuts(this, shortcutInfoList)
|
||||||
Log.i(LOG_TAG, "set shortcuts: ${shortcutInfoList.joinToString(", ") { v -> v.id }}")
|
Log.i(LOG_TAG, "set shortcuts: ${shortcutInfoList.joinToString(", ") { v -> v.id }}")
|
||||||
}
|
}
|
||||||
|
@ -579,12 +590,14 @@ open class MainActivity : FlutterFragmentActivity() {
|
||||||
const val INTENT_DATA_KEY_SECURE_URIS = "secureUris"
|
const val INTENT_DATA_KEY_SECURE_URIS = "secureUris"
|
||||||
const val INTENT_DATA_KEY_URI = "uri"
|
const val INTENT_DATA_KEY_URI = "uri"
|
||||||
const val INTENT_DATA_KEY_WIDGET_ID = "widgetId"
|
const val INTENT_DATA_KEY_WIDGET_ID = "widgetId"
|
||||||
|
const val INTENT_DATA_KEY_DEBUG = "debug"
|
||||||
|
|
||||||
const val EXTRA_KEY_PAGE = "page"
|
const val EXTRA_KEY_PAGE = "page"
|
||||||
const val EXTRA_KEY_EXPLORER_PATH = "explorerPath"
|
const val EXTRA_KEY_EXPLORER_PATH = "explorerPath"
|
||||||
const val EXTRA_KEY_FILTERS_ARRAY = "filters"
|
const val EXTRA_KEY_FILTERS_ARRAY = "filters"
|
||||||
const val EXTRA_KEY_FILTERS_STRING = "filtersString"
|
const val EXTRA_KEY_FILTERS_STRING = "filtersString"
|
||||||
const val EXTRA_KEY_WIDGET_ID = "widgetId"
|
const val EXTRA_KEY_WIDGET_ID = "widgetId"
|
||||||
|
const val EXTRA_KEY_DEBUG = "debug"
|
||||||
|
|
||||||
// dart page routes
|
// dart page routes
|
||||||
const val COLLECTION_PAGE_ROUTE_NAME = "/collection"
|
const val COLLECTION_PAGE_ROUTE_NAME = "/collection"
|
||||||
|
|
|
@ -24,4 +24,7 @@ class IntentDataKeys {
|
||||||
static const secureUris = 'secureUris';
|
static const secureUris = 'secureUris';
|
||||||
static const uri = 'uri';
|
static const uri = 'uri';
|
||||||
static const widgetId = 'widgetId';
|
static const widgetId = 'widgetId';
|
||||||
|
|
||||||
|
// #977
|
||||||
|
static const debug = 'debug';
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,12 @@ abstract class LocalMediaDb {
|
||||||
|
|
||||||
Future<void> removeIds(Set<int> ids, {Set<EntryDataType>? dataTypes});
|
Future<void> removeIds(Set<int> ids, {Set<EntryDataType>? dataTypes});
|
||||||
|
|
||||||
|
// debug
|
||||||
|
|
||||||
|
Future<void> logCatalog(String message);
|
||||||
|
|
||||||
|
Future<List<String>> getCatalogLog();
|
||||||
|
|
||||||
// entries
|
// entries
|
||||||
|
|
||||||
Future<void> clearEntries();
|
Future<void> clearEntries();
|
||||||
|
|
|
@ -34,6 +34,7 @@ class SqfliteLocalMediaDb implements LocalMediaDb {
|
||||||
static const vaultTable = SqfliteLocalMediaDbSchema.vaultTable;
|
static const vaultTable = SqfliteLocalMediaDbSchema.vaultTable;
|
||||||
static const trashTable = SqfliteLocalMediaDbSchema.trashTable;
|
static const trashTable = SqfliteLocalMediaDbSchema.trashTable;
|
||||||
static const videoPlaybackTable = SqfliteLocalMediaDbSchema.videoPlaybackTable;
|
static const videoPlaybackTable = SqfliteLocalMediaDbSchema.videoPlaybackTable;
|
||||||
|
static const debugTable = SqfliteLocalMediaDbSchema.debugTable;
|
||||||
|
|
||||||
static const _entryInsertSliceMaxCount = 10000; // number of entries
|
static const _entryInsertSliceMaxCount = 10000; // number of entries
|
||||||
static const _queryCursorBufferSize = 1000; // number of rows
|
static const _queryCursorBufferSize = 1000; // number of rows
|
||||||
|
@ -48,7 +49,7 @@ class SqfliteLocalMediaDb implements LocalMediaDb {
|
||||||
await path,
|
await path,
|
||||||
onCreate: (db, version) => SqfliteLocalMediaDbSchema.createLatestVersion(db),
|
onCreate: (db, version) => SqfliteLocalMediaDbSchema.createLatestVersion(db),
|
||||||
onUpgrade: LocalMediaDbUpgrader.upgradeDb,
|
onUpgrade: LocalMediaDbUpgrader.upgradeDb,
|
||||||
version: 15,
|
version: 16,
|
||||||
);
|
);
|
||||||
|
|
||||||
final maxIdRows = await _db.rawQuery('SELECT MAX(id) AS maxId FROM $entryTable');
|
final maxIdRows = await _db.rawQuery('SELECT MAX(id) AS maxId FROM $entryTable');
|
||||||
|
@ -101,6 +102,19 @@ class SqfliteLocalMediaDb implements LocalMediaDb {
|
||||||
await batch.commit(noResult: true);
|
await batch.commit(noResult: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// debug
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> logCatalog(String message) async {
|
||||||
|
await _db.insert(debugTable, {'message': message});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<String>> getCatalogLog() async {
|
||||||
|
final rows = await _db.query(debugTable);
|
||||||
|
return rows.map((row) => row['message'] as String).toList();
|
||||||
|
}
|
||||||
|
|
||||||
// entries
|
// entries
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -11,6 +11,7 @@ class SqfliteLocalMediaDbSchema {
|
||||||
static const vaultTable = 'vaults';
|
static const vaultTable = 'vaults';
|
||||||
static const trashTable = 'trash';
|
static const trashTable = 'trash';
|
||||||
static const videoPlaybackTable = 'videoPlayback';
|
static const videoPlaybackTable = 'videoPlayback';
|
||||||
|
static const debugTable = 'debug';
|
||||||
|
|
||||||
static const allTables = [
|
static const allTables = [
|
||||||
entryTable,
|
entryTable,
|
||||||
|
@ -23,6 +24,7 @@ class SqfliteLocalMediaDbSchema {
|
||||||
vaultTable,
|
vaultTable,
|
||||||
trashTable,
|
trashTable,
|
||||||
videoPlaybackTable,
|
videoPlaybackTable,
|
||||||
|
debugTable,
|
||||||
];
|
];
|
||||||
|
|
||||||
static Future<void> createLatestVersion(Database db) async {
|
static Future<void> createLatestVersion(Database db) async {
|
||||||
|
@ -111,6 +113,11 @@ class SqfliteLocalMediaDbSchema {
|
||||||
'id INTEGER PRIMARY KEY'
|
'id INTEGER PRIMARY KEY'
|
||||||
', resumeTimeMillis INTEGER'
|
', resumeTimeMillis INTEGER'
|
||||||
')');
|
')');
|
||||||
|
case debugTable:
|
||||||
|
return db.execute('CREATE TABLE $debugTable('
|
||||||
|
'id INTEGER PRIMARY KEY AUTOINCREMENT'
|
||||||
|
', message TEXT'
|
||||||
|
')');
|
||||||
default:
|
default:
|
||||||
throw Exception('unknown table=$table');
|
throw Exception('unknown table=$table');
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ class LocalMediaDbUpgrader {
|
||||||
static const vaultTable = SqfliteLocalMediaDbSchema.vaultTable;
|
static const vaultTable = SqfliteLocalMediaDbSchema.vaultTable;
|
||||||
static const trashTable = SqfliteLocalMediaDbSchema.trashTable;
|
static const trashTable = SqfliteLocalMediaDbSchema.trashTable;
|
||||||
static const videoPlaybackTable = SqfliteLocalMediaDbSchema.videoPlaybackTable;
|
static const videoPlaybackTable = SqfliteLocalMediaDbSchema.videoPlaybackTable;
|
||||||
|
static const debugTable = SqfliteLocalMediaDbSchema.debugTable;
|
||||||
|
|
||||||
// warning: "ALTER TABLE ... RENAME COLUMN ..." is not supported
|
// warning: "ALTER TABLE ... RENAME COLUMN ..." is not supported
|
||||||
// on SQLite <3.25.0, bundled on older Android devices
|
// on SQLite <3.25.0, bundled on older Android devices
|
||||||
|
@ -53,6 +54,8 @@ class LocalMediaDbUpgrader {
|
||||||
await _upgradeFrom13(db);
|
await _upgradeFrom13(db);
|
||||||
case 14:
|
case 14:
|
||||||
await _upgradeFrom14(db);
|
await _upgradeFrom14(db);
|
||||||
|
case 15:
|
||||||
|
await _upgradeFrom15(db);
|
||||||
}
|
}
|
||||||
oldVersion++;
|
oldVersion++;
|
||||||
}
|
}
|
||||||
|
@ -500,4 +503,13 @@ class LocalMediaDbUpgrader {
|
||||||
// (dateTakenTable, metadataTable, addressTable, trashTable, videoPlaybackTable)
|
// (dateTakenTable, metadataTable, addressTable, trashTable, videoPlaybackTable)
|
||||||
// for users with a potentially corrupted DB following upgrade to v1.12.4
|
// for users with a potentially corrupted DB following upgrade to v1.12.4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<void> _upgradeFrom15(Database db) async {
|
||||||
|
debugPrint('upgrading DB from v15');
|
||||||
|
|
||||||
|
await db.execute('CREATE TABLE $debugTable('
|
||||||
|
'id INTEGER PRIMARY KEY AUTOINCREMENT'
|
||||||
|
', message TEXT'
|
||||||
|
')');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,9 @@ class PlatformMetadataFetchService implements MetadataFetchService {
|
||||||
Future<CatalogMetadata?> getCatalogMetadata(AvesEntry entry, {bool background = false}) async {
|
Future<CatalogMetadata?> getCatalogMetadata(AvesEntry entry, {bool background = false}) async {
|
||||||
if (entry.isSvg) return null;
|
if (entry.isSvg) return null;
|
||||||
|
|
||||||
|
// #977
|
||||||
|
await localMediaDb.logCatalog('${DateTime.now().toIso8601String()} ${entry.path ?? entry.uri}');
|
||||||
|
|
||||||
Future<CatalogMetadata?> call() async {
|
Future<CatalogMetadata?> call() async {
|
||||||
try {
|
try {
|
||||||
// returns map with:
|
// returns map with:
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/geo/uri.dart';
|
import 'package:aves/geo/uri.dart';
|
||||||
|
@ -14,6 +16,8 @@ import 'package:aves/model/settings/enums/home_page.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
|
import 'package:aves/ref/locales.dart';
|
||||||
|
import 'package:aves/ref/mime_types.dart';
|
||||||
import 'package:aves/services/analysis_service.dart';
|
import 'package:aves/services/analysis_service.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/services/global_search.dart';
|
import 'package:aves/services/global_search.dart';
|
||||||
|
@ -22,6 +26,7 @@ import 'package:aves/services/widget_service.dart';
|
||||||
import 'package:aves/theme/themes.dart';
|
import 'package:aves/theme/themes.dart';
|
||||||
import 'package:aves/utils/android_file_utils.dart';
|
import 'package:aves/utils/android_file_utils.dart';
|
||||||
import 'package:aves/widgets/collection/collection_page.dart';
|
import 'package:aves/widgets/collection/collection_page.dart';
|
||||||
|
import 'package:aves/widgets/common/action_mixins/feedback.dart';
|
||||||
import 'package:aves/widgets/common/basic/scaffold.dart';
|
import 'package:aves/widgets/common/basic/scaffold.dart';
|
||||||
import 'package:aves/widgets/common/behaviour/routes.dart';
|
import 'package:aves/widgets/common/behaviour/routes.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
@ -42,6 +47,7 @@ import 'package:aves/widgets/wallpaper_page.dart';
|
||||||
import 'package:aves_model/aves_model.dart';
|
import 'package:aves_model/aves_model.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -61,7 +67,7 @@ class HomePage extends StatefulWidget {
|
||||||
State<HomePage> createState() => _HomePageState();
|
State<HomePage> createState() => _HomePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> with FeedbackMixin {
|
||||||
AvesEntry? _viewerEntry;
|
AvesEntry? _viewerEntry;
|
||||||
int? _widgetId;
|
int? _widgetId;
|
||||||
String? _initialRouteName, _initialSearchQuery;
|
String? _initialRouteName, _initialSearchQuery;
|
||||||
|
@ -108,11 +114,35 @@ class _HomePageState extends State<HomePage> {
|
||||||
var appMode = AppMode.main;
|
var appMode = AppMode.main;
|
||||||
var error = false;
|
var error = false;
|
||||||
final intentData = widget.intentData ?? await IntentService.getIntentData();
|
final intentData = widget.intentData ?? await IntentService.getIntentData();
|
||||||
|
final debug = intentData[IntentDataKeys.debug] ?? false;
|
||||||
final intentAction = intentData[IntentDataKeys.action] as String?;
|
final intentAction = intentData[IntentDataKeys.action] as String?;
|
||||||
_initialFilters = null;
|
_initialFilters = null;
|
||||||
_initialExplorerPath = null;
|
_initialExplorerPath = null;
|
||||||
_secureUris = null;
|
_secureUris = null;
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
await localMediaDb.init();
|
||||||
|
final logs = await localMediaDb.getCatalogLog();
|
||||||
|
|
||||||
|
final success = await storageService.createFile(
|
||||||
|
'aves_issue977_logs-${DateFormat('yyyyMMdd_HHmmss', asciiLocale).format(DateTime.now())}.txt',
|
||||||
|
MimeTypes.plainText,
|
||||||
|
Uint8List.fromList(utf8.encode(logs.join('\n'))),
|
||||||
|
);
|
||||||
|
if (success != null) {
|
||||||
|
if (success) {
|
||||||
|
showFeedback(context, FeedbackType.info, context.l10n.genericSuccessFeedback);
|
||||||
|
} else {
|
||||||
|
showFeedback(context, FeedbackType.warn, context.l10n.genericFailureFeedback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unawaited(Navigator.maybeOf(context)?.pushAndRemoveUntil(
|
||||||
|
await _getRedirectRoute(appMode),
|
||||||
|
(route) => false,
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await availability.onNewIntent();
|
await availability.onNewIntent();
|
||||||
await androidFileUtils.init();
|
await androidFileUtils.init();
|
||||||
if (!{
|
if (!{
|
||||||
|
|
Loading…
Reference in a new issue