settings: option to hide videos

This commit is contained in:
Thibault Deckers 2021-03-20 10:12:10 +09:00
parent 6159f5ec25
commit 81c9c8a757
9 changed files with 75 additions and 33 deletions

View file

@ -525,6 +525,11 @@
"settingsViewerShowShootingDetails": "Show shooting details",
"@settingsViewerShowShootingDetails": {},
"settingsSectionVideo": "Video",
"@settingsSectionVideo": {},
"settingsVideoShowVideos": "Show videos",
"@settingsVideoShowVideos": {},
"settingsSectionSearch": "Search",
"@settingsSectionSearch": {},
"settingsSaveSearchHistory": "Save search history",

View file

@ -245,6 +245,9 @@
"settingsViewerShowInformationSubtitle": "제목, 날짜, 장소 등 표시",
"settingsViewerShowShootingDetails": "촬영 정보 표시",
"settingsSectionVideo": "동영상",
"settingsVideoShowVideos": "미디어에 동영상 표시",
"settingsSectionSearch": "검색",
"settingsSaveSearchHistory": "검색기록",

View file

@ -14,6 +14,9 @@ class MimeFilter extends CollectionFilter {
String _label;
IconData _icon;
static final image = MimeFilter(MimeTypes.anyImage);
static final video = MimeFilter(MimeTypes.anyVideo);
MimeFilter(this.mime) {
var lowMime = mime.toLowerCase();
if (lowMime.endsWith('/*')) {

View file

@ -7,30 +7,35 @@ import 'package:flutter/widgets.dart';
class TypeFilter extends CollectionFilter {
static const type = 'type';
static const animated = 'animated'; // subset of `image/gif` and `image/webp`
static const geotiff = 'geotiff'; // subset of `image/tiff`
static const panorama = 'panorama'; // subset of images
static const sphericalVideo = 'spherical_video'; // subset of videos
static const _animated = 'animated'; // subset of `image/gif` and `image/webp`
static const _geotiff = 'geotiff'; // subset of `image/tiff`
static const _panorama = 'panorama'; // subset of images
static const _sphericalVideo = 'spherical_video'; // subset of videos
final String itemType;
EntryFilter _test;
IconData _icon;
TypeFilter(this.itemType) {
static final animated = TypeFilter._private(_animated);
static final geotiff = TypeFilter._private(_geotiff);
static final panorama = TypeFilter._private(_panorama);
static final sphericalVideo = TypeFilter._private(_sphericalVideo);
TypeFilter._private(this.itemType) {
switch (itemType) {
case animated:
case _animated:
_test = (entry) => entry.isAnimated;
_icon = AIcons.animated;
break;
case panorama:
case _panorama:
_test = (entry) => entry.isImage && entry.is360;
_icon = AIcons.threesixty;
break;
case sphericalVideo:
case _sphericalVideo:
_test = (entry) => entry.isVideo && entry.is360;
_icon = AIcons.threesixty;
break;
case geotiff:
case _geotiff:
_test = (entry) => entry.isGeotiff;
_icon = AIcons.geo;
break;
@ -38,7 +43,7 @@ class TypeFilter extends CollectionFilter {
}
TypeFilter.fromMap(Map<String, dynamic> json)
: this(
: this._private(
json['itemType'],
);
@ -57,13 +62,13 @@ class TypeFilter extends CollectionFilter {
@override
String getLabel(BuildContext context) {
switch (itemType) {
case animated:
case _animated:
return context.l10n.filterTypeAnimatedLabel;
case panorama:
case _panorama:
return context.l10n.filterTypePanoramaLabel;
case sphericalVideo:
case _sphericalVideo:
return context.l10n.filterTypeSphericalVideoLabel;
case geotiff:
case _geotiff:
return context.l10n.filterTypeGeotiffLabel;
default:
return itemType;

View file

@ -2,11 +2,11 @@ import 'dart:ui';
import 'package:aves/model/filters/favourite.dart';
import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/album.dart';
import 'package:aves/model/source/collection_source.dart';
import 'package:aves/model/source/location.dart';
import 'package:aves/model/source/tag.dart';
import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/services.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/utils/android_file_utils.dart';
@ -45,10 +45,12 @@ class _AppDrawerState extends State<AppDrawer> {
@override
Widget build(BuildContext context) {
final hiddenFilters = settings.hiddenFilters;
final showVideos = !hiddenFilters.contains(MimeFilter.video);
final drawerItems = <Widget>[
_buildHeader(context),
allCollectionTile,
videoTile,
if (showVideos) videoTile,
favouriteTile,
_buildSpecialAlbumSection(),
Divider(),
@ -153,7 +155,7 @@ class _AppDrawerState extends State<AppDrawer> {
Widget get videoTile => CollectionNavTile(
leading: Icon(AIcons.video),
title: context.l10n.drawerCollectionVideos,
filter: MimeFilter(MimeTypes.anyVideo),
filter: MimeFilter.video,
);
Widget get favouriteTile => CollectionNavTile(

View file

@ -31,13 +31,13 @@ class CollectionSearchDelegate {
static const searchHistoryCount = 10;
static final typeFilters = [
FavouriteFilter(),
MimeFilter(MimeTypes.anyImage),
MimeFilter(MimeTypes.anyVideo),
MimeFilter.image,
MimeFilter.video,
TypeFilter.animated,
TypeFilter.panorama,
TypeFilter.sphericalVideo,
TypeFilter.geotiff,
MimeFilter(MimeTypes.svg),
TypeFilter(TypeFilter.animated),
TypeFilter(TypeFilter.panorama),
TypeFilter(TypeFilter.sphericalVideo),
TypeFilter(TypeFilter.geotiff),
];
CollectionSearchDelegate({@required this.source, this.parentCollection});
@ -87,7 +87,14 @@ class CollectionSearchDelegate {
selector: (context, s) => s.hiddenFilters,
builder: (context, hiddenFilters, child) {
bool notHidden(CollectionFilter filter) => !hiddenFilters.contains(filter);
final visibleTypeFilters = typeFilters.where(notHidden).toList();
if (hiddenFilters.contains(MimeFilter.video)) {
[MimeFilter.image, TypeFilter.sphericalVideo].forEach(visibleTypeFilters.remove);
}
final history = settings.searchHistory.where(notHidden).toList();
return ListView(
padding: EdgeInsets.only(top: 8),
children: [
@ -95,7 +102,7 @@ class CollectionSearchDelegate {
context: context,
filters: [
queryFilter,
...typeFilters.where(notHidden),
...visibleTypeFilters,
].where((f) => f != null && containQuery(f.getLabel(context))).toList(),
// usually perform hero animation only on tapped chips,
// but we also need to animate the query chip when it is selected by submitting the search query

View file

@ -1,8 +1,10 @@
import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/settings/coordinate_format.dart';
import 'package:aves/model/settings/enums.dart';
import 'package:aves/model/settings/home_page.dart';
import 'package:aves/model/settings/screen_on.dart';
import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_source.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/extensions/build_context.dart';
@ -61,6 +63,7 @@ class _SettingsPageState extends State<SettingsPage> {
_buildDisplaySection(context),
_buildThumbnailsSection(context),
_buildViewerSection(context),
_buildVideoSection(context),
_buildSearchSection(context),
_buildPrivacySection(context),
],
@ -213,6 +216,22 @@ class _SettingsPageState extends State<SettingsPage> {
);
}
Widget _buildVideoSection(BuildContext context) {
final hiddenFilters = settings.hiddenFilters;
final showVideos = !hiddenFilters.contains(MimeFilter.video);
return AvesExpansionTile(
title: context.l10n.settingsSectionVideo,
expandedNotifier: _expandedNotifier,
children: [
SwitchListTile(
value: showVideos,
onChanged: (v) => context.read<CollectionSource>().changeFilterVisibility(MimeFilter.video, v),
title: Text(context.l10n.settingsVideoShowVideos),
),
],
);
}
Widget _buildSearchSection(BuildContext context) {
return AvesExpansionTile(
title: context.l10n.settingsSectionSearch,

View file

@ -7,7 +7,6 @@ import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/filters/tag.dart';
import 'package:aves/model/filters/type.dart';
import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/services.dart';
import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/file_utils.dart';
@ -78,11 +77,11 @@ class BasicSection extends StatelessWidget {
final album = entry.directory;
final filters = {
MimeFilter(entry.mimeType),
if (entry.isAnimated) TypeFilter(TypeFilter.animated),
if (entry.isGeotiff) TypeFilter(TypeFilter.geotiff),
if (entry.isImage && entry.is360) TypeFilter(TypeFilter.panorama),
if (entry.isVideo && entry.is360) TypeFilter(TypeFilter.sphericalVideo),
if (entry.isVideo && !entry.is360) MimeFilter(MimeTypes.anyVideo),
if (entry.isAnimated) TypeFilter.animated,
if (entry.isGeotiff) TypeFilter.geotiff,
if (entry.isImage && entry.is360) TypeFilter.panorama,
if (entry.isVideo && entry.is360) TypeFilter.sphericalVideo,
if (entry.isVideo && !entry.is360) MimeFilter.video,
if (album != null) AlbumFilter(album, collection?.source?.getUniqueAlbumName(context, album)),
...tags.map((tag) => TagFilter(tag)),
};

View file

@ -6,7 +6,6 @@ import 'package:aves/model/filters/mime.dart';
import 'package:aves/model/filters/query.dart';
import 'package:aves/model/filters/tag.dart';
import 'package:aves/model/filters/type.dart';
import 'package:aves/ref/mime_types.dart';
import 'package:test/test.dart';
void main() {
@ -22,10 +21,10 @@ void main() {
final location = LocationFilter(LocationLevel.country, 'France${LocationFilter.locationSeparator}FR');
expect(location, jsonRoundTrip(location));
final type = TypeFilter(TypeFilter.sphericalVideo);
final type = TypeFilter.sphericalVideo;
expect(type, jsonRoundTrip(type));
final mime = MimeFilter(MimeTypes.anyVideo);
final mime = MimeFilter.video;
expect(mime, jsonRoundTrip(mime));
final query = QueryFilter('some query');