You've already forked immich
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:
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
@ -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()}",
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -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(
|
||||
|
@ -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(),
|
||||
],
|
||||
|
Reference in New Issue
Block a user