albums: case insensitive unique names
This commit is contained in:
parent
1bf5a2e315
commit
08bd187c7d
5 changed files with 26 additions and 7 deletions
|
@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
- opening app from launcher always show home page
|
||||
- use dates with western arabic numerals for maghreb arabic locales
|
||||
- album unique names are case insensitive
|
||||
- upgraded Flutter to stable v3.19.5
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -196,19 +196,19 @@ mixin AlbumMixin on SourceBase {
|
|||
final parts = pContext.split(dirPath);
|
||||
for (var i = parts.length - 1; i > 0; i--) {
|
||||
final name = pContext.joinAll(['', ...parts.skip(i)]);
|
||||
final testName = '$separator$name';
|
||||
final testName = '$separator${name.toLowerCase()}';
|
||||
if (others.every((item) => !item.endsWith(testName))) return name;
|
||||
}
|
||||
return dirPath;
|
||||
}
|
||||
|
||||
final otherAlbumsOnDevice = _directories.whereNotNull().where((item) => item != dirPath).toSet();
|
||||
final otherAlbumsOnDevice = _directories.whereNotNull().where((item) => item != dirPath).map((v) => v.toLowerCase()).toSet();
|
||||
final uniqueNameInDevice = unique(dirPath, otherAlbumsOnDevice);
|
||||
if (uniqueNameInDevice.length <= relativeDir.length) {
|
||||
return uniqueNameInDevice;
|
||||
}
|
||||
|
||||
final volumePath = dir.volumePath;
|
||||
final volumePath = dir.volumePath.toLowerCase();
|
||||
String trimVolumePath(String? path) => path!.substring(dir.volumePath.length);
|
||||
final otherAlbumsOnVolume = otherAlbumsOnDevice.where((path) => path.startsWith(volumePath)).map(trimVolumePath).toSet();
|
||||
final uniqueNameInVolume = unique(trimVolumePath(dirPath), otherAlbumsOnVolume);
|
||||
|
|
|
@ -76,7 +76,7 @@ Future<void> _init() async {
|
|||
|
||||
enum AnalyzerState { running, stopping, stopped }
|
||||
|
||||
class Analyzer {
|
||||
class Analyzer with WidgetsBindingObserver {
|
||||
late AppLocalizations _l10n;
|
||||
final ValueNotifier<AnalyzerState> _serviceStateNotifier = ValueNotifier<AnalyzerState>(AnalyzerState.stopped);
|
||||
AnalysisController? _controller;
|
||||
|
@ -102,6 +102,7 @@ class Analyzer {
|
|||
}
|
||||
_serviceStateNotifier.addListener(_onServiceStateChanged);
|
||||
_source.stateNotifier.addListener(_onSourceStateChanged);
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
|
@ -111,11 +112,18 @@ class Analyzer {
|
|||
}
|
||||
_stopUpdateTimer();
|
||||
_controller?.dispose();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
_serviceStateNotifier.removeListener(_onServiceStateChanged);
|
||||
_source.stateNotifier.removeListener(_onSourceStateChanged);
|
||||
_source.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didHaveMemoryPressure() {
|
||||
super.didHaveMemoryPressure();
|
||||
reportService.log('Analyzer memory pressure');
|
||||
}
|
||||
|
||||
Future<void> start(dynamic args) async {
|
||||
List<int>? entryIds;
|
||||
var force = false;
|
||||
|
@ -126,7 +134,7 @@ class Analyzer {
|
|||
progressTotal = args['progressTotal'];
|
||||
progressOffset = args['progressOffset'];
|
||||
}
|
||||
debugPrint('$runtimeType start for ${entryIds?.length ?? 'all'} entries, at $progressOffset/$progressTotal');
|
||||
await reportService.log('Analyzer start for ${entryIds?.length ?? 'all'} entries, at $progressOffset/$progressTotal');
|
||||
_controller?.dispose();
|
||||
_controller = AnalysisController(
|
||||
canStartService: false,
|
||||
|
@ -147,8 +155,8 @@ class Analyzer {
|
|||
});
|
||||
}
|
||||
|
||||
void stop() {
|
||||
debugPrint('$runtimeType stop');
|
||||
Future<void> stop() async {
|
||||
await reportService.log('Analyzer stop');
|
||||
_serviceStateNotifier.value = AnalyzerState.stopped;
|
||||
}
|
||||
|
||||
|
|
|
@ -404,6 +404,12 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void didHaveMemoryPressure() {
|
||||
super.didHaveMemoryPressure();
|
||||
reportService.log('App memory pressure');
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeMetrics() => _updateCutoutInsets();
|
||||
|
||||
|
|
|
@ -366,6 +366,8 @@ void main() {
|
|||
FakeMediaStoreService.newImage('${FakeStorageService.removablePath}Marcus Aurelius', '1'),
|
||||
FakeMediaStoreService.newImage('${FakeStorageService.primaryPath}Pictures/Hannah Arendt', '1'),
|
||||
FakeMediaStoreService.newImage('${FakeStorageService.primaryPath}Pictures/Arendt', '1'),
|
||||
FakeMediaStoreService.newImage('${FakeStorageService.primaryPath}Pictures/Something', '1'),
|
||||
FakeMediaStoreService.newImage('${FakeStorageService.primaryPath}Movies/SomeThing', '1'),
|
||||
};
|
||||
|
||||
final source = await _initSource();
|
||||
|
@ -387,6 +389,8 @@ void main() {
|
|||
expect(source.getAlbumDisplayName(context, '${FakeStorageService.removablePath}Marcus Aurelius'), 'Marcus Aurelius');
|
||||
expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Hannah Arendt'), 'Hannah Arendt');
|
||||
expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Arendt'), 'Arendt');
|
||||
expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Something'), 'Pictures/Something');
|
||||
expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Movies/SomeThing'), 'Movies/SomeThing');
|
||||
return const Placeholder();
|
||||
},
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue