1
0
mirror of https://github.com/immich-app/immich.git synced 2025-07-16 07:24:40 +02:00

Customization options for asset grid (#498)

* Add settings options for number of assets per row and storage indicator

* Add attributes to enum to avoid duplicate code

* Also apply customizations to albums

* Minor Refactorings

* Three stage loading i18n fix
This commit is contained in:
Matthias Rupp
2022-08-20 23:19:40 +02:00
committed by GitHub
parent 07b58f46f9
commit 013a0f8324
13 changed files with 209 additions and 64 deletions

View File

@ -1,11 +1,16 @@
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/hive_box.dart';
enum AppSettingsEnum {
threeStageLoading, // true, false,
themeMode, // "light","dark","system"
enum AppSettingsEnum<T> {
threeStageLoading<bool>("threeStageLoading", false),
themeMode<String>("themeMode", "system"), // "light","dark","system"
tilesPerRow<int>("tilesPerRow", 4),
storageIndicator<bool>("storageIndicator", true);
const AppSettingsEnum(this.hiveKey, this.defaultValue);
final String hiveKey;
final T defaultValue;
}
class AppSettingsService {
@ -15,63 +20,26 @@ class AppSettingsService {
hiveBox = Hive.box(userSettingInfoBox);
}
T getSetting<T>(AppSettingsEnum settingType) {
var settingKey = _settingHiveBoxKeyLookup(settingType);
if (!hiveBox.containsKey(settingKey)) {
T defaultSetting = _setDefaultSetting(settingType);
return defaultSetting;
T getSetting<T>(AppSettingsEnum<T> settingType) {
if (!hiveBox.containsKey(settingType.hiveKey)) {
return _setDefault(settingType);
}
var result = hiveBox.get(settingKey);
var result = hiveBox.get(settingType.hiveKey);
if (result is T) {
return result;
} else {
debugPrint("Incorrect setting type");
throw TypeError();
if (result is! T) {
return _setDefault(settingType);
}
return result;
}
setSetting<T>(AppSettingsEnum settingType, T value) {
var settingKey = _settingHiveBoxKeyLookup(settingType);
if (hiveBox.containsKey(settingKey)) {
var result = hiveBox.get(settingKey);
if (result is! T) {
debugPrint("Incorrect setting type");
throw TypeError();
}
hiveBox.put(settingKey, value);
} else {
hiveBox.put(settingKey, value);
}
setSetting<T>(AppSettingsEnum<T> settingType, T value) {
hiveBox.put(settingType.hiveKey, value);
}
_setDefaultSetting(AppSettingsEnum settingType) {
var settingKey = _settingHiveBoxKeyLookup(settingType);
// Default value of threeStageLoading is false
if (settingType == AppSettingsEnum.threeStageLoading) {
hiveBox.put(settingKey, false);
return false;
}
// Default value of themeMode is "light"
if (settingType == AppSettingsEnum.themeMode) {
hiveBox.put(settingKey, "system");
return "system";
}
}
String _settingHiveBoxKeyLookup(AppSettingsEnum settingType) {
switch (settingType) {
case AppSettingsEnum.threeStageLoading:
return 'threeStageLoading';
case AppSettingsEnum.themeMode:
return 'themeMode';
}
T _setDefault<T>(AppSettingsEnum<T> settingType) {
hiveBox.put(settingType.hiveKey, settingType.defaultValue);
return settingType.defaultValue;
}
}

View File

@ -0,0 +1,33 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart';
import 'asset_list_tiles_per_row.dart';
class AssetListSettings extends StatelessWidget {
const AssetListSettings({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ExpansionTile(
textColor: Theme.of(context).primaryColor,
title: const Text(
'asset_list_settings_title',
style: TextStyle(
fontWeight: FontWeight.bold,
),
).tr(),
subtitle: const Text(
'asset_list_settings_subtitle',
style: TextStyle(
fontSize: 13,
),
).tr(),
children: const [
TilesPerRow(),
StorageIndicator(),
],
);
}
}

View File

@ -0,0 +1,48 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
import 'package:immich_mobile/shared/providers/asset.provider.dart';
class StorageIndicator extends HookConsumerWidget {
const StorageIndicator({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final appSettingService = ref.watch(appSettingsServiceProvider);
final showStorageIndicator = useState(true);
void switchChanged(bool value) {
appSettingService.setSetting(AppSettingsEnum.storageIndicator, value);
showStorageIndicator.value = value;
ref.invalidate(assetGroupByDateTimeProvider);
}
useEffect(
() {
showStorageIndicator.value = appSettingService.getSetting<bool>(AppSettingsEnum.storageIndicator);
return null;
},
[],
);
return SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
title: const Text(
"theme_setting_asset_list_storage_indicator_title",
style: TextStyle(
fontSize: 12,
),
).tr(),
onChanged: switchChanged,
value: showStorageIndicator.value,
);
}
}

View File

@ -0,0 +1,63 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
import 'package:immich_mobile/shared/providers/asset.provider.dart';
class TilesPerRow extends HookConsumerWidget {
const TilesPerRow({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final appSettingService = ref.watch(appSettingsServiceProvider);
final itemsValue = useState(4.0);
void sliderChanged(double value) {
appSettingService.setSetting(AppSettingsEnum.tilesPerRow, value.toInt());
itemsValue.value = value;
}
void sliderChangedEnd(double _) {
ref.invalidate(assetGroupByDateTimeProvider);
}
useEffect(
() {
int tilesPerRow =
appSettingService.getSetting(AppSettingsEnum.tilesPerRow);
itemsValue.value = tilesPerRow.toDouble();
return null;
},
[],
);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListTile(
title: const Text(
"theme_setting_asset_list_tiles_per_row_title",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
).tr(args: ["${itemsValue.value.toInt()}"]),
),
Slider(
onChangeEnd: sliderChangedEnd,
onChanged: sliderChanged,
value: itemsValue.value,
min: 2,
max: 6,
divisions: 4,
label: "${itemsValue.value.toInt()}",
),
],
);
}
}

View File

@ -36,6 +36,7 @@ class ThreeStageLoading extends HookConsumerWidget {
}
return SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
title: const Text(
"theme_setting_three_stage_loading_title",
style: TextStyle(

View File

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/settings/ui/asset_list_settings/asset_list_settings.dart';
import 'package:immich_mobile/modules/settings/ui/image_viewer_quality_setting/image_viewer_quality_setting.dart';
import 'package:immich_mobile/modules/settings/ui/theme_setting/theme_setting.dart';
@ -36,6 +37,7 @@ class SettingsPage extends HookConsumerWidget {
tiles: [
const ImageViewerQualitySetting(),
const ThemeSetting(),
const AssetListSettings()
],
).toList(),
],