#72 fixed hiding root album of hidden path

This commit is contained in:
Thibault Deckers 2021-09-30 17:27:16 +09:00
parent b60e0f5e45
commit b605cb62c7
3 changed files with 50 additions and 5 deletions

View file

@ -160,6 +160,7 @@ class AvesEntry {
String? get path => _path; String? get path => _path;
// directory path, without the trailing separator
String? get directory { String? get directory {
_directory ??= path != null ? pContext.dirname(path!) : null; _directory ??= path != null ? pContext.dirname(path!) : null;
return _directory; return _directory;
@ -170,6 +171,7 @@ class AvesEntry {
return _filename; return _filename;
} }
// file extension, including the `.`
String? get extension { String? get extension {
_extension ??= path != null ? pContext.extension(path!) : null; _extension ??= path != null ? pContext.extension(path!) : null;
return _extension; return _extension;

View file

@ -1,14 +1,19 @@
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/services/common/services.dart';
class PathFilter extends CollectionFilter { class PathFilter extends CollectionFilter {
static const type = 'path'; static const type = 'path';
// including trailing separator
final String path; final String path;
// without trailing separator
final String _rootAlbum;
@override @override
List<Object?> get props => [path]; List<Object?> get props => [path];
const PathFilter(this.path); PathFilter(this.path) : _rootAlbum = path.substring(0, path.length - 1);
PathFilter.fromMap(Map<String, dynamic> json) PathFilter.fromMap(Map<String, dynamic> json)
: this( : this(
@ -22,7 +27,12 @@ class PathFilter extends CollectionFilter {
}; };
@override @override
EntryFilter get test => (entry) => entry.directory?.startsWith(path) ?? false; EntryFilter get test => (entry) {
final dir = entry.directory;
if (dir == null) return false;
// avoid string building in most cases
return dir.startsWith(_rootAlbum) && '$dir${pContext.separator}'.startsWith(path);
};
@override @override
String get universalLabel => path; String get universalLabel => path;

View file

@ -3,12 +3,27 @@ import 'package:aves/model/filters/favourite.dart';
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/filters/location.dart'; import 'package:aves/model/filters/location.dart';
import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/filters/path.dart';
import 'package:aves/model/filters/query.dart'; import 'package:aves/model/filters/query.dart';
import 'package:aves/model/filters/tag.dart'; import 'package:aves/model/filters/tag.dart';
import 'package:aves/model/filters/type.dart'; import 'package:aves/model/filters/type.dart';
import 'package:aves/services/common/services.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../fake/media_store_service.dart';
import '../fake/storage_service.dart';
void main() { void main() {
setUp(() async {
// specify Posix style path context for consistent behaviour when running tests on Windows
getIt.registerLazySingleton<p.Context>(() => p.Context(style: p.Style.posix));
});
tearDown(() async {
await getIt.reset();
});
test('Filter serialization', () { test('Filter serialization', () {
CollectionFilter? jsonRoundTrip(filter) => CollectionFilter.fromJson(filter.toJson()); CollectionFilter? jsonRoundTrip(filter) => CollectionFilter.fromJson(filter.toJson());
@ -21,16 +36,34 @@ void main() {
final location = LocationFilter(LocationLevel.country, 'France${LocationFilter.locationSeparator}FR'); final location = LocationFilter(LocationLevel.country, 'France${LocationFilter.locationSeparator}FR');
expect(location, jsonRoundTrip(location)); expect(location, jsonRoundTrip(location));
final type = TypeFilter.sphericalVideo;
expect(type, jsonRoundTrip(type));
final mime = MimeFilter.video; final mime = MimeFilter.video;
expect(mime, jsonRoundTrip(mime)); expect(mime, jsonRoundTrip(mime));
final path = PathFilter('/some/path/');
expect(path, jsonRoundTrip(path));
final query = QueryFilter('some query'); final query = QueryFilter('some query');
expect(query, jsonRoundTrip(query)); expect(query, jsonRoundTrip(query));
final tag = TagFilter('some tag'); final tag = TagFilter('some tag');
expect(tag, jsonRoundTrip(tag)); expect(tag, jsonRoundTrip(tag));
final type = TypeFilter.sphericalVideo;
expect(type, jsonRoundTrip(type));
});
test('Path filter', () {
const rootAlbum = '${FakeStorageService.primaryPath}Pictures/test';
const subAlbum = '${FakeStorageService.primaryPath}Pictures/test/sub';
const siblingAlbum = '${FakeStorageService.primaryPath}Pictures/test sibling';
final rootImage = FakeMediaStoreService.newImage(rootAlbum, 'image1');
final subImage = FakeMediaStoreService.newImage(subAlbum, 'image1');
final siblingImage = FakeMediaStoreService.newImage(siblingAlbum, 'image1');
final path = PathFilter('$rootAlbum/');
expect(path.test(rootImage), true);
expect(path.test(subImage), true);
expect(path.test(siblingImage), false);
}); });
} }