minor fixes
This commit is contained in:
parent
b3500edd10
commit
fcca4776c6
12 changed files with 248 additions and 266 deletions
|
@ -505,6 +505,17 @@
|
|||
"@aboutCreditsWorldAtlas2": {},
|
||||
"aboutCreditsTranslators": "Translators:",
|
||||
"@aboutCreditsTranslators": {},
|
||||
"aboutCreditsTranslatorLine": "{language}: {names}",
|
||||
"@aboutCreditsTranslatorLine": {
|
||||
"placeholders": {
|
||||
"language": {
|
||||
"type": "String"
|
||||
},
|
||||
"names": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"aboutLicenses": "Open-Source Licenses",
|
||||
"@aboutLicenses": {},
|
||||
|
@ -893,8 +904,11 @@
|
|||
"settingsSaveSearchHistory": "Save search history",
|
||||
"@settingsSaveSearchHistory": {},
|
||||
|
||||
"settingsHiddenFiltersTile": "Hidden filters",
|
||||
"@settingsHiddenFiltersTile": {},
|
||||
"settingsHiddenItemsTile": "Hidden items",
|
||||
"@settingsHiddenItemsTile": {},
|
||||
"settingsHiddenItemsTitle": "Hidden Items",
|
||||
"@settingsHiddenItemsTitle": {},
|
||||
|
||||
"settingsHiddenFiltersTitle": "Hidden Filters",
|
||||
"@settingsHiddenFiltersTitle": {},
|
||||
"settingsHiddenFiltersBanner": "Photos and videos matching hidden filters will not appear in your collection.",
|
||||
|
@ -902,14 +916,10 @@
|
|||
"settingsHiddenFiltersEmpty": "No hidden filters",
|
||||
"@settingsHiddenFiltersEmpty": {},
|
||||
|
||||
"settingsHiddenPathsTile": "Hidden paths",
|
||||
"@settingsHiddenPathsTile": {},
|
||||
"settingsHiddenPathsTitle": "Hidden Paths",
|
||||
"@settingsHiddenPathsTitle": {},
|
||||
"settingsHiddenPathsBanner": "Photos and videos in these folders, or any of their subfolders, will not appear in your collection.",
|
||||
"@settingsHiddenPathsBanner": {},
|
||||
"settingsHiddenPathsEmpty": "No hidden paths",
|
||||
"@settingsHiddenPathsEmpty": {},
|
||||
"addPathTooltip": "Add path",
|
||||
"@addPathTooltip": {},
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
"removeTooltip": "Supprimer",
|
||||
"resetButtonTooltip": "Réinitialiser",
|
||||
|
||||
"doubleBackExitMessage": "Presser «\u00A0retour\u00A0» à nouveau pour quitter.",
|
||||
"doubleBackExitMessage": "Pressez «\u00A0retour\u00A0» à nouveau pour quitter.",
|
||||
|
||||
"sourceStateLoading": "Chargement",
|
||||
"sourceStateCataloguing": "Classification",
|
||||
|
@ -234,6 +234,7 @@
|
|||
"aboutCreditsWorldAtlas1": "Cette app utilise un fichier TopoJSON de ",
|
||||
"aboutCreditsWorldAtlas2": "sous licence ISC.",
|
||||
"aboutCreditsTranslators": "Traducteurs :",
|
||||
"aboutCreditsTranslatorLine": "{language} : {names}",
|
||||
|
||||
"aboutLicenses": "Licences open-source",
|
||||
"aboutLicensesBanner": "Cette app utilise ces librairies et packages open-source.",
|
||||
|
@ -426,15 +427,15 @@
|
|||
"settingsAllowErrorReporting": "Autoriser l’envoi de rapports d’erreur",
|
||||
"settingsSaveSearchHistory": "Maintenir un historique des recherches",
|
||||
|
||||
"settingsHiddenFiltersTile": "Filtres masqués",
|
||||
"settingsHiddenItemsTile": "Éléments masqués",
|
||||
"settingsHiddenItemsTitle": "Éléments masqués",
|
||||
|
||||
"settingsHiddenFiltersTitle": "Filtres masqués",
|
||||
"settingsHiddenFiltersBanner": "Les images et vidéos correspondantes aux filtres masqués n’apparaîtront pas dans votre collection.",
|
||||
"settingsHiddenFiltersEmpty": "Aucun filtre masqué",
|
||||
|
||||
"settingsHiddenPathsTile": "Chemins masqués",
|
||||
"settingsHiddenPathsTitle": "Chemins masqués",
|
||||
"settingsHiddenPathsBanner": "Les images et vidéos dans ces dossiers, ou leurs sous-dossiers, n’apparaîtront pas dans votre collection.",
|
||||
"settingsHiddenPathsEmpty": "Aucun chemin masqué",
|
||||
"addPathTooltip": "Ajouter un chemin",
|
||||
|
||||
"settingsStorageAccessTile": "Accès au stockage",
|
||||
|
|
|
@ -233,6 +233,7 @@
|
|||
"aboutCreditsWorldAtlas1": "이 앱은",
|
||||
"aboutCreditsWorldAtlas2": "의 TopoJSON 파일(ISC 라이선스)을 이용합니다.",
|
||||
"aboutCreditsTranslators": "번역가:",
|
||||
"aboutCreditsTranslatorLine": "{language}: {names}",
|
||||
|
||||
"aboutLicenses": "오픈 소스 라이선스",
|
||||
"aboutLicensesBanner": "이 앱은 다음의 오픈 소스 패키지와 라이브러리를 이용합니다.",
|
||||
|
@ -425,15 +426,15 @@
|
|||
"settingsAllowErrorReporting": "오류 보고서 보내기",
|
||||
"settingsSaveSearchHistory": "검색기록",
|
||||
|
||||
"settingsHiddenFiltersTile": "숨겨진 필터",
|
||||
"settingsHiddenItemsTile": "숨겨진 항목",
|
||||
"settingsHiddenItemsTitle": "숨겨진 항목",
|
||||
|
||||
"settingsHiddenFiltersTitle": "숨겨진 필터",
|
||||
"settingsHiddenFiltersBanner": "이 필터에 맞는 사진과 동영상이 숨겨지고 있으며 이 앱에서 보여지지 않을 것입니다.",
|
||||
"settingsHiddenFiltersEmpty": "숨겨진 필터가 없습니다",
|
||||
|
||||
"settingsHiddenPathsTile": "숨겨진 경로",
|
||||
"settingsHiddenPathsTitle": "숨겨진 경로",
|
||||
"settingsHiddenPathsBanner": "이 경로에 있는 사진과 동영상이 숨겨지고 있으며 이 앱에서 보여지지 않을 것입니다.",
|
||||
"settingsHiddenPathsEmpty": "숨겨진 경로가 없습니다",
|
||||
"addPathTooltip": "경로 추가",
|
||||
|
||||
"settingsStorageAccessTile": "저장공간 접근",
|
||||
|
|
|
@ -232,6 +232,7 @@
|
|||
"aboutCreditsWorldAtlas1": "Это приложение использует файл TopoJSON из",
|
||||
"aboutCreditsWorldAtlas2": "под лицензией ISC.",
|
||||
"aboutCreditsTranslators": "Переводчики:",
|
||||
"aboutCreditsTranslatorLine": "{language}: {names}",
|
||||
|
||||
"aboutLicenses": "Лицензии с открытым исходным кодом",
|
||||
"aboutLicensesBanner": "Это приложение использует следующие пакеты и библиотеки с открытым исходным кодом.",
|
||||
|
@ -423,15 +424,12 @@
|
|||
"settingsAllowErrorReporting": "Разрешить анонимную отправку логов",
|
||||
"settingsSaveSearchHistory": "Сохранять историю поиска",
|
||||
|
||||
"settingsHiddenFiltersTile": "Скрытые фильтры",
|
||||
"settingsHiddenFiltersTitle": "Скрытые фильтры",
|
||||
"settingsHiddenFiltersBanner": "Фотографии и видео, соответствующие скрытым фильтрам, не появятся в вашей коллекции.",
|
||||
"settingsHiddenFiltersEmpty": "Нет скрытых фильтров",
|
||||
|
||||
"settingsHiddenPathsTile": "Скрытые каталоги",
|
||||
"settingsHiddenPathsTitle": "Скрытые каталоги",
|
||||
"settingsHiddenPathsBanner": "Фотографии и видео в этих каталогах или любых их вложенных каталогах не будут отображаться в вашей коллекции.",
|
||||
"settingsHiddenPathsEmpty": "Нет скрытых каталогов",
|
||||
"addPathTooltip": "Добавить каталог",
|
||||
|
||||
"settingsStorageAccessTile": "Доступ к хранилищу",
|
||||
|
|
|
@ -8,12 +8,13 @@ import 'package:flutter/material.dart';
|
|||
class AboutCredits extends StatelessWidget {
|
||||
const AboutCredits({Key? key}) : super(key: key);
|
||||
|
||||
static const translations = [
|
||||
'Русский: D3ZOXY',
|
||||
];
|
||||
static const translators = {
|
||||
'Русский': 'D3ZOXY',
|
||||
};
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
|
@ -23,13 +24,13 @@ class AboutCredits extends StatelessWidget {
|
|||
constraints: const BoxConstraints(minHeight: 48),
|
||||
child: Align(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
child: Text(context.l10n.aboutCredits, style: Constants.titleTextStyle),
|
||||
child: Text(l10n.aboutCredits, style: Constants.titleTextStyle),
|
||||
),
|
||||
),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(text: context.l10n.aboutCreditsWorldAtlas1),
|
||||
TextSpan(text: l10n.aboutCreditsWorldAtlas1),
|
||||
const WidgetSpan(
|
||||
child: LinkChip(
|
||||
text: 'World Atlas',
|
||||
|
@ -38,17 +39,19 @@ class AboutCredits extends StatelessWidget {
|
|||
),
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
),
|
||||
TextSpan(text: context.l10n.aboutCreditsWorldAtlas2),
|
||||
TextSpan(text: l10n.aboutCreditsWorldAtlas2),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(context.l10n.aboutCreditsTranslators),
|
||||
...translations.map(
|
||||
(line) => Padding(
|
||||
Text(l10n.aboutCreditsTranslators),
|
||||
...translators.entries.map(
|
||||
(kv) {
|
||||
return Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 8, top: 8),
|
||||
child: Text(line),
|
||||
),
|
||||
child: Text(l10n.aboutCreditsTranslatorLine(kv.key, kv.value)),
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
|
|
@ -154,7 +154,7 @@ class _TagEditorPageState extends State<TagEditorPage> {
|
|||
duration: Durations.tagEditorTransition,
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
const Divider(height: 0),
|
||||
_FilterRow(
|
||||
title: l10n.tagEditorSectionRecent,
|
||||
filters: recentFilters,
|
||||
|
|
|
@ -145,7 +145,7 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
|||
child: ListView(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(AIcons.info),
|
||||
|
@ -154,9 +154,9 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
|||
],
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
const Divider(height: 0),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.only(left: 16, top: 16, right: 16),
|
||||
child: Text(
|
||||
context.l10n.settingsViewerQuickActionEditorDisplayedButtons,
|
||||
style: Constants.titleTextStyle,
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
import 'package:aves/model/filters/filters.dart';
|
||||
import 'package:aves/model/filters/path.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/model/source/collection_source.dart';
|
||||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||
import 'package:aves/widgets/common/identity/empty.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class HiddenFilterTile extends StatelessWidget {
|
||||
const HiddenFilterTile({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
title: Text(context.l10n.settingsHiddenFiltersTile),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
settings: const RouteSettings(name: HiddenFilterPage.routeName),
|
||||
builder: (context) => const HiddenFilterPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HiddenFilterPage extends StatelessWidget {
|
||||
static const routeName = '/settings/hidden_filters';
|
||||
|
||||
const HiddenFilterPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(context.l10n.settingsHiddenFiltersTitle),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Selector<Settings, Set<CollectionFilter>>(
|
||||
selector: (context, s) => settings.hiddenFilters.where((v) => v is! PathFilter).toSet(),
|
||||
builder: (context, hiddenFilters, child) {
|
||||
if (hiddenFilters.isEmpty) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const _Header(),
|
||||
const Divider(),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: EmptyContent(
|
||||
icon: AIcons.hide,
|
||||
text: context.l10n.settingsHiddenFiltersEmpty,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
final filterList = hiddenFilters.toList()..sort();
|
||||
return ListView(
|
||||
children: [
|
||||
const _Header(),
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: filterList
|
||||
.map((filter) => AvesFilterChip(
|
||||
filter: filter,
|
||||
removable: true,
|
||||
onTap: (filter) => context.read<CollectionSource>().changeFilterVisibility({filter}, true),
|
||||
onLongPress: null,
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Header extends StatelessWidget {
|
||||
const _Header({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(AIcons.info),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(child: Text(context.l10n.settingsHiddenFiltersBanner)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
198
lib/widgets/settings/privacy/hidden_items.dart
Normal file
198
lib/widgets/settings/privacy/hidden_items.dart
Normal file
|
@ -0,0 +1,198 @@
|
|||
import 'package:aves/model/filters/filters.dart';
|
||||
import 'package:aves/model/filters/path.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/model/source/collection_source.dart';
|
||||
import 'package:aves/services/common/services.dart';
|
||||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||
import 'package:aves/widgets/common/identity/buttons.dart';
|
||||
import 'package:aves/widgets/common/identity/empty.dart';
|
||||
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class HiddenItemsTile extends StatelessWidget {
|
||||
const HiddenItemsTile({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
title: Text(context.l10n.settingsHiddenItemsTile),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
settings: const RouteSettings(name: HiddenItemsPage.routeName),
|
||||
builder: (context) => const HiddenItemsPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HiddenItemsPage extends StatelessWidget {
|
||||
static const routeName = '/settings/hidden_items';
|
||||
|
||||
const HiddenItemsPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
final tabs = <Tuple2<Tab, Widget>>[
|
||||
Tuple2(
|
||||
Tab(text: l10n.settingsHiddenFiltersTitle),
|
||||
const _HiddenFilters(),
|
||||
),
|
||||
Tuple2(
|
||||
Tab(text: l10n.settingsHiddenPathsTitle),
|
||||
const _HiddenPaths(),
|
||||
),
|
||||
];
|
||||
|
||||
return MediaQueryDataProvider(
|
||||
child: DefaultTabController(
|
||||
length: tabs.length,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(l10n.settingsHiddenItemsTitle),
|
||||
bottom: TabBar(
|
||||
tabs: tabs.map((t) => t.item1).toList(),
|
||||
),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: TabBarView(
|
||||
children: tabs.map((t) => t.item2).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _HiddenFilters extends StatelessWidget {
|
||||
const _HiddenFilters({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Selector<Settings, Set<CollectionFilter>>(
|
||||
selector: (context, s) => settings.hiddenFilters.where((v) => v is! PathFilter).toSet(),
|
||||
builder: (context, hiddenFilters, child) {
|
||||
if (hiddenFilters.isEmpty) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_Banner(bannerText: context.l10n.settingsHiddenFiltersBanner),
|
||||
const Divider(height: 0),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: EmptyContent(
|
||||
icon: AIcons.hide,
|
||||
text: context.l10n.settingsHiddenFiltersEmpty,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
final filterList = hiddenFilters.toList()..sort();
|
||||
return ListView(
|
||||
children: [
|
||||
_Banner(bannerText: context.l10n.settingsHiddenFiltersBanner),
|
||||
const Divider(height: 0),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: filterList
|
||||
.map((filter) => AvesFilterChip(
|
||||
filter: filter,
|
||||
removable: true,
|
||||
onTap: (filter) => context.read<CollectionSource>().changeFilterVisibility({filter}, true),
|
||||
onLongPress: null,
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _HiddenPaths extends StatelessWidget {
|
||||
const _HiddenPaths({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Selector<Settings, Set<PathFilter>>(
|
||||
selector: (context, s) => settings.hiddenFilters.whereType<PathFilter>().toSet(),
|
||||
builder: (context, hiddenPaths, child) {
|
||||
final pathList = hiddenPaths.toList()..sort();
|
||||
return Column(
|
||||
children: [
|
||||
_Banner(bannerText: context.l10n.settingsHiddenPathsBanner),
|
||||
const Divider(height: 0),
|
||||
Flexible(
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
...pathList.map((pathFilter) => ListTile(
|
||||
title: Text(pathFilter.path),
|
||||
dense: true,
|
||||
trailing: IconButton(
|
||||
icon: const Icon(AIcons.clear),
|
||||
onPressed: () {
|
||||
context.read<CollectionSource>().changeFilterVisibility({pathFilter}, true);
|
||||
},
|
||||
tooltip: context.l10n.removeTooltip,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(height: 0),
|
||||
const SizedBox(height: 8),
|
||||
AvesOutlinedButton(
|
||||
icon: const Icon(AIcons.add),
|
||||
label: context.l10n.addPathTooltip,
|
||||
onPressed: () async {
|
||||
final path = await storageService.selectDirectory();
|
||||
if (path != null && path.isNotEmpty) {
|
||||
context.read<CollectionSource>().changeFilterVisibility({PathFilter(path)}, false);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Banner extends StatelessWidget {
|
||||
final String bannerText;
|
||||
|
||||
const _Banner({Key? key, required this.bannerText}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(AIcons.info),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(child: Text(bannerText)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
import 'package:aves/model/filters/path.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/model/source/collection_source.dart';
|
||||
import 'package:aves/services/common/services.dart';
|
||||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/common/identity/empty.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class HiddenPathTile extends StatelessWidget {
|
||||
const HiddenPathTile({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
title: Text(context.l10n.settingsHiddenPathsTile),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
settings: const RouteSettings(name: HiddenPathPage.routeName),
|
||||
builder: (context) => const HiddenPathPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HiddenPathPage extends StatelessWidget {
|
||||
static const routeName = '/settings/hidden_paths';
|
||||
|
||||
const HiddenPathPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(context.l10n.settingsHiddenPathsTitle),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(AIcons.add),
|
||||
onPressed: () async {
|
||||
final path = await storageService.selectDirectory();
|
||||
if (path != null && path.isNotEmpty) {
|
||||
context.read<CollectionSource>().changeFilterVisibility({PathFilter(path)}, false);
|
||||
}
|
||||
},
|
||||
tooltip: context.l10n.addPathTooltip,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Selector<Settings, Set<PathFilter>>(
|
||||
selector: (context, s) => settings.hiddenFilters.whereType<PathFilter>().toSet(),
|
||||
builder: (context, hiddenPaths, child) {
|
||||
if (hiddenPaths.isEmpty) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const _Header(),
|
||||
const Divider(),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: EmptyContent(
|
||||
icon: AIcons.hide,
|
||||
text: context.l10n.settingsHiddenPathsEmpty,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
final pathList = hiddenPaths.toList()..sort();
|
||||
return ListView(
|
||||
children: [
|
||||
const _Header(),
|
||||
const Divider(),
|
||||
...pathList.map((pathFilter) => ListTile(
|
||||
title: Text(pathFilter.path),
|
||||
dense: true,
|
||||
trailing: IconButton(
|
||||
icon: const Icon(AIcons.clear),
|
||||
onPressed: () {
|
||||
context.read<CollectionSource>().changeFilterVisibility({pathFilter}, true);
|
||||
},
|
||||
tooltip: context.l10n.removeTooltip,
|
||||
),
|
||||
)),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Header extends StatelessWidget {
|
||||
const _Header({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(AIcons.info),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(child: Text(context.l10n.settingsHiddenPathsBanner)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -6,8 +6,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
|
|||
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
|
||||
import 'package:aves/widgets/settings/common/tile_leading.dart';
|
||||
import 'package:aves/widgets/settings/privacy/access_grants.dart';
|
||||
import 'package:aves/widgets/settings/privacy/hidden_filters.dart';
|
||||
import 'package:aves/widgets/settings/privacy/hidden_paths.dart';
|
||||
import 'package:aves/widgets/settings/privacy/hidden_items.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
@ -63,8 +62,7 @@ class PrivacySection extends StatelessWidget {
|
|||
title: Text(context.l10n.settingsSaveSearchHistory),
|
||||
),
|
||||
),
|
||||
const HiddenFilterTile(),
|
||||
const HiddenPathTile(),
|
||||
const HiddenItemsTile(),
|
||||
const StorageAccessTile(),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
"resetButtonTooltip",
|
||||
"entryInfoActionEditTags",
|
||||
"settingsViewerMaximumBrightness",
|
||||
"settingsHiddenItemsTile",
|
||||
"settingsHiddenItemsTitle",
|
||||
"tagEditorPageTitle",
|
||||
"tagEditorPageNewTagFieldLabel",
|
||||
"tagEditorPageAddTagTooltip"
|
||||
|
|
Loading…
Reference in a new issue