Optimize pref streams where the first value should be ignored

This commit is contained in:
Ming Ming 2024-02-25 12:09:57 +08:00
parent c588ab9c6d
commit def24946e2
36 changed files with 550 additions and 152 deletions

View file

@ -219,7 +219,7 @@ class HomeSearchSuggestionBloc
} }
try { try {
final persons = await ListPerson(_c)( final persons = await ListPerson(_c)(
account, accountPrefController.personProvider.value) account, accountPrefController.personProviderValue)
.last; .last;
product.addAll(persons.map((t) => _PersonSearcheable(t))); product.addAll(persons.map((t) => _PersonSearcheable(t)));
_log.info("[_onEventPreloadData] Loaded ${persons.length} people"); _log.info("[_onEventPreloadData] Loaded ${persons.length} people");

View file

@ -8,6 +8,7 @@ import 'package:rxdart/rxdart.dart';
part 'account_pref_controller.g.dart'; part 'account_pref_controller.g.dart';
@npLog @npLog
@npSubjectAccessor
class AccountPrefController { class AccountPrefController {
AccountPrefController({ AccountPrefController({
required this.account, required this.account,
@ -20,34 +21,24 @@ class AccountPrefController {
_isEnableMemoryAlbumController.close(); _isEnableMemoryAlbumController.close();
} }
ValueStream<String> get shareFolder => _shareFolderController.stream;
Future<void> setShareFolder(String value) => _set<String>( Future<void> setShareFolder(String value) => _set<String>(
controller: _shareFolderController, controller: _shareFolderController,
setter: (pref, value) => pref.setShareFolder(value), setter: (pref, value) => pref.setShareFolder(value),
value: value, value: value,
); );
ValueStream<String?> get accountLabel => _accountLabelController.stream;
Future<void> setAccountLabel(String? value) => _set<String?>( Future<void> setAccountLabel(String? value) => _set<String?>(
controller: _accountLabelController, controller: _accountLabelController,
setter: (pref, value) => pref.setAccountLabel(value), setter: (pref, value) => pref.setAccountLabel(value),
value: value, value: value,
); );
ValueStream<PersonProvider> get personProvider =>
_personProviderController.stream;
Future<void> setPersonProvider(PersonProvider value) => _set<PersonProvider>( Future<void> setPersonProvider(PersonProvider value) => _set<PersonProvider>(
controller: _personProviderController, controller: _personProviderController,
setter: (pref, value) => pref.setPersonProvider(value.index), setter: (pref, value) => pref.setPersonProvider(value.index),
value: value, value: value,
); );
ValueStream<bool> get isEnableMemoryAlbum =>
_isEnableMemoryAlbumController.stream;
Future<void> setEnableMemoryAlbum(bool value) => _set<bool>( Future<void> setEnableMemoryAlbum(bool value) => _set<bool>(
controller: _isEnableMemoryAlbumController, controller: _isEnableMemoryAlbumController,
setter: (pref, value) => pref.setEnableMemoryAlbum(value), setter: (pref, value) => pref.setEnableMemoryAlbum(value),
@ -76,12 +67,16 @@ class AccountPrefController {
final Account account; final Account account;
final AccountPref _accountPref; final AccountPref _accountPref;
@npSubjectAccessor
late final _shareFolderController = late final _shareFolderController =
BehaviorSubject.seeded(_accountPref.getShareFolderOr("")); BehaviorSubject.seeded(_accountPref.getShareFolderOr(""));
@npSubjectAccessor
late final _accountLabelController = late final _accountLabelController =
BehaviorSubject.seeded(_accountPref.getAccountLabel()); BehaviorSubject.seeded(_accountPref.getAccountLabel());
@npSubjectAccessor
late final _personProviderController = BehaviorSubject.seeded( late final _personProviderController = BehaviorSubject.seeded(
PersonProvider.fromValue(_accountPref.getPersonProviderOr())); PersonProvider.fromValue(_accountPref.getPersonProviderOr()));
@npSubjectAccessor
late final _isEnableMemoryAlbumController = late final _isEnableMemoryAlbumController =
BehaviorSubject.seeded(_accountPref.isEnableMemoryAlbumOr(true)); BehaviorSubject.seeded(_accountPref.isEnableMemoryAlbumOr(true));
} }

View file

@ -13,3 +13,34 @@ extension _$AccountPrefControllerNpLog on AccountPrefController {
static final log = static final log =
Logger("controller.account_pref_controller.AccountPrefController"); Logger("controller.account_pref_controller.AccountPrefController");
} }
// **************************************************************************
// NpSubjectAccessorGenerator
// **************************************************************************
extension $AccountPrefControllerNpSubjectAccessor on AccountPrefController {
// _shareFolderController
ValueStream<String> get shareFolder => _shareFolderController.stream;
Stream<String> get shareFolderNew => shareFolder.skip(1);
Stream<String> get shareFolderChange => shareFolder.distinct().skip(1);
String get shareFolderValue => _shareFolderController.value;
// _accountLabelController
ValueStream<String?> get accountLabel => _accountLabelController.stream;
Stream<String?> get accountLabelNew => accountLabel.skip(1);
Stream<String?> get accountLabelChange => accountLabel.distinct().skip(1);
String? get accountLabelValue => _accountLabelController.value;
// _personProviderController
ValueStream<PersonProvider> get personProvider =>
_personProviderController.stream;
Stream<PersonProvider> get personProviderNew => personProvider.skip(1);
Stream<PersonProvider> get personProviderChange =>
personProvider.distinct().skip(1);
PersonProvider get personProviderValue => _personProviderController.value;
// _isEnableMemoryAlbumController
ValueStream<bool> get isEnableMemoryAlbum =>
_isEnableMemoryAlbumController.stream;
Stream<bool> get isEnableMemoryAlbumNew => isEnableMemoryAlbum.skip(1);
Stream<bool> get isEnableMemoryAlbumChange =>
isEnableMemoryAlbum.distinct().skip(1);
bool get isEnableMemoryAlbumValue => _isEnableMemoryAlbumController.value;
}

View file

@ -43,7 +43,7 @@ class FilesController {
required this.account, required this.account,
required this.accountPrefController, required this.accountPrefController,
}) { }) {
_subscriptions.add(accountPrefController.shareFolder.listen((event) { _subscriptions.add(accountPrefController.shareFolderChange.listen((event) {
// sync remote if share folder is modified // sync remote if share folder is modified
if (_isDataStreamInited) { if (_isDataStreamInited) {
syncRemote(); syncRemote();
@ -84,7 +84,7 @@ class FilesController {
try { try {
final shareDir = File( final shareDir = File(
path: file_util.unstripPath( path: file_util.unstripPath(
account, accountPrefController.shareFolder.value), account, accountPrefController.shareFolderValue),
); );
var isShareDirIncluded = false; var isShareDirIncluded = false;
@ -320,7 +320,7 @@ class FilesController {
final completer = Completer(); final completer = Completer();
ListFile(_c)( ListFile(_c)(
account, account,
file_util.unstripPath(account, accountPrefController.shareFolder.value), file_util.unstripPath(account, accountPrefController.shareFolderValue),
).listen( ).listen(
(ev) { (ev) {
lastData = _convertListResultsToEvent(ev, hasNext: true); lastData = _convertListResultsToEvent(ev, hasNext: true);
@ -338,7 +338,7 @@ class FilesController {
final completer = Completer(); final completer = Completer();
ListFile(_c)( ListFile(_c)(
account, account,
file_util.unstripPath(account, accountPrefController.shareFolder.value), file_util.unstripPath(account, accountPrefController.shareFolderValue),
).listen( ).listen(
(ev) { (ev) {
results = ev; results = ev;

View file

@ -22,7 +22,8 @@ class MetadataController {
required this.prefController, required this.prefController,
}) { }) {
_subscriptions.add(filesController.stream.listen(_onFilesEvent)); _subscriptions.add(filesController.stream.listen(_onFilesEvent));
_subscriptions.add(prefController.isEnableExif.listen(_onSetEnableExif)); _subscriptions
.add(prefController.isEnableExifChange.listen(_onSetEnableExif));
} }
void dispose() { void dispose() {
@ -39,7 +40,7 @@ class MetadataController {
Future<void> _onFilesEvent(FilesStreamEvent ev) async { Future<void> _onFilesEvent(FilesStreamEvent ev) async {
_log.info("[_onFilesEvent]"); _log.info("[_onFilesEvent]");
if (!prefController.isEnableExif.value) { if (!prefController.isEnableExifValue) {
// disabled // disabled
return; return;
} }

View file

@ -71,7 +71,7 @@ class PersonsController {
_personStreamContorller.add(lastData); _personStreamContorller.add(lastData);
final completer = Completer(); final completer = Completer();
ListPerson(_c.withLocalRepo())( ListPerson(_c.withLocalRepo())(
account, accountPrefController.personProvider.value) account, accountPrefController.personProviderValue)
.listen( .listen(
(results) { (results) {
lastData = PersonStreamEvent( lastData = PersonStreamEvent(

View file

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/di_container.dart';
import 'package:nc_photos/entity/pref.dart'; import 'package:nc_photos/entity/pref.dart';
import 'package:nc_photos/language_util.dart' as language_util; import 'package:nc_photos/language_util.dart';
import 'package:nc_photos/object_extension.dart'; import 'package:nc_photos/object_extension.dart';
import 'package:nc_photos/size.dart'; import 'package:nc_photos/size.dart';
import 'package:np_codegen/np_codegen.dart'; import 'package:np_codegen/np_codegen.dart';
@ -14,134 +14,94 @@ import 'package:rxdart/rxdart.dart';
part 'pref_controller.g.dart'; part 'pref_controller.g.dart';
@npLog @npLog
@npSubjectAccessor
class PrefController { class PrefController {
PrefController(this._c); PrefController(this._c);
ValueStream<language_util.AppLanguage> get language => Future<void> setAppLanguage(AppLanguage value) => _set<AppLanguage>(
_languageController.stream;
Future<void> setAppLanguage(language_util.AppLanguage value) =>
_set<language_util.AppLanguage>(
controller: _languageController, controller: _languageController,
setter: (pref, value) => pref.setLanguage(value.langId), setter: (pref, value) => pref.setLanguage(value.langId),
value: value, value: value,
); );
ValueStream<int> get homePhotosZoomLevel =>
_homePhotosZoomLevelController.stream;
Future<void> setHomePhotosZoomLevel(int value) => _set<int>( Future<void> setHomePhotosZoomLevel(int value) => _set<int>(
controller: _homePhotosZoomLevelController, controller: _homePhotosZoomLevelController,
setter: (pref, value) => pref.setHomePhotosZoomLevel(value), setter: (pref, value) => pref.setHomePhotosZoomLevel(value),
value: value, value: value,
); );
ValueStream<int> get albumBrowserZoomLevel =>
_albumBrowserZoomLevelController.stream;
Future<void> setAlbumBrowserZoomLevel(int value) => _set<int>( Future<void> setAlbumBrowserZoomLevel(int value) => _set<int>(
controller: _albumBrowserZoomLevelController, controller: _albumBrowserZoomLevelController,
setter: (pref, value) => pref.setAlbumBrowserZoomLevel(value), setter: (pref, value) => pref.setAlbumBrowserZoomLevel(value),
value: value, value: value,
); );
ValueStream<int> get homeAlbumsSort => _homeAlbumsSortController.stream;
Future<void> setHomeAlbumsSort(int value) => _set<int>( Future<void> setHomeAlbumsSort(int value) => _set<int>(
controller: _homeAlbumsSortController, controller: _homeAlbumsSortController,
setter: (pref, value) => pref.setHomeAlbumsSort(value), setter: (pref, value) => pref.setHomeAlbumsSort(value),
value: value, value: value,
); );
ValueStream<bool> get isEnableExif => _isEnableExifController.stream;
Future<void> setEnableExif(bool value) => _set<bool>( Future<void> setEnableExif(bool value) => _set<bool>(
controller: _isEnableExifController, controller: _isEnableExifController,
setter: (pref, value) => pref.setEnableExif(value), setter: (pref, value) => pref.setEnableExif(value),
value: value, value: value,
); );
ValueStream<bool> get shouldProcessExifWifiOnly =>
_shouldProcessExifWifiOnlyController.stream;
Future<void> setProcessExifWifiOnly(bool value) => _set<bool>( Future<void> setProcessExifWifiOnly(bool value) => _set<bool>(
controller: _shouldProcessExifWifiOnlyController, controller: _shouldProcessExifWifiOnlyController,
setter: (pref, value) => pref.setProcessExifWifiOnly(value), setter: (pref, value) => pref.setProcessExifWifiOnly(value),
value: value, value: value,
); );
ValueStream<int> get memoriesRange => _memoriesRangeController.stream;
Future<void> setMemoriesRange(int value) => _set<int>( Future<void> setMemoriesRange(int value) => _set<int>(
controller: _memoriesRangeController, controller: _memoriesRangeController,
setter: (pref, value) => pref.setMemoriesRange(value), setter: (pref, value) => pref.setMemoriesRange(value),
value: value, value: value,
); );
ValueStream<bool> get isPhotosTabSortByName =>
_isPhotosTabSortByNameController.stream;
Future<void> setPhotosTabSortByName(bool value) => _set<bool>( Future<void> setPhotosTabSortByName(bool value) => _set<bool>(
controller: _isPhotosTabSortByNameController, controller: _isPhotosTabSortByNameController,
setter: (pref, value) => pref.setPhotosTabSortByName(value), setter: (pref, value) => pref.setPhotosTabSortByName(value),
value: value, value: value,
); );
ValueStream<int> get viewerScreenBrightness =>
_viewerScreenBrightnessController.stream;
Future<void> setViewerScreenBrightness(int value) => _set<int>( Future<void> setViewerScreenBrightness(int value) => _set<int>(
controller: _viewerScreenBrightnessController, controller: _viewerScreenBrightnessController,
setter: (pref, value) => pref.setViewerScreenBrightness(value), setter: (pref, value) => pref.setViewerScreenBrightness(value),
value: value, value: value,
); );
ValueStream<bool> get isViewerForceRotation =>
_isViewerForceRotationController.stream;
Future<void> setViewerForceRotation(bool value) => _set<bool>( Future<void> setViewerForceRotation(bool value) => _set<bool>(
controller: _isViewerForceRotationController, controller: _isViewerForceRotationController,
setter: (pref, value) => pref.setViewerForceRotation(value), setter: (pref, value) => pref.setViewerForceRotation(value),
value: value, value: value,
); );
ValueStream<GpsMapProvider> get gpsMapProvider =>
_gpsMapProviderController.stream;
Future<void> setGpsMapProvider(GpsMapProvider value) => _set<GpsMapProvider>( Future<void> setGpsMapProvider(GpsMapProvider value) => _set<GpsMapProvider>(
controller: _gpsMapProviderController, controller: _gpsMapProviderController,
setter: (pref, value) => pref.setGpsMapProvider(value.index), setter: (pref, value) => pref.setGpsMapProvider(value.index),
value: value, value: value,
); );
ValueStream<bool> get isAlbumBrowserShowDate =>
_isAlbumBrowserShowDateController.stream;
Future<void> setAlbumBrowserShowDate(bool value) => _set<bool>( Future<void> setAlbumBrowserShowDate(bool value) => _set<bool>(
controller: _isAlbumBrowserShowDateController, controller: _isAlbumBrowserShowDateController,
setter: (pref, value) => pref.setAlbumBrowserShowDate(value), setter: (pref, value) => pref.setAlbumBrowserShowDate(value),
value: value, value: value,
); );
ValueStream<bool> get isDoubleTapExit => _isDoubleTapExitController.stream;
Future<void> setDoubleTapExit(bool value) => _set<bool>( Future<void> setDoubleTapExit(bool value) => _set<bool>(
controller: _isDoubleTapExitController, controller: _isDoubleTapExitController,
setter: (pref, value) => pref.setDoubleTapExit(value), setter: (pref, value) => pref.setDoubleTapExit(value),
value: value, value: value,
); );
ValueStream<bool> get isSaveEditResultToServer =>
_isSaveEditResultToServerController.stream;
Future<void> setSaveEditResultToServer(bool value) => _set<bool>( Future<void> setSaveEditResultToServer(bool value) => _set<bool>(
controller: _isSaveEditResultToServerController, controller: _isSaveEditResultToServerController,
setter: (pref, value) => pref.setSaveEditResultToServer(value), setter: (pref, value) => pref.setSaveEditResultToServer(value),
value: value, value: value,
); );
ValueStream<SizeInt> get enhanceMaxSize => _enhanceMaxSizeController.stream;
Future<void> setEnhanceMaxSize(SizeInt value) => _set<SizeInt>( Future<void> setEnhanceMaxSize(SizeInt value) => _set<SizeInt>(
controller: _enhanceMaxSizeController, controller: _enhanceMaxSizeController,
setter: (pref, value) async { setter: (pref, value) async {
@ -154,34 +114,24 @@ class PrefController {
value: value, value: value,
); );
ValueStream<bool> get isDarkTheme => _isDarkThemeController.stream;
Future<void> setDarkTheme(bool value) => _set<bool>( Future<void> setDarkTheme(bool value) => _set<bool>(
controller: _isDarkThemeController, controller: _isDarkThemeController,
setter: (pref, value) => pref.setDarkTheme(value), setter: (pref, value) => pref.setDarkTheme(value),
value: value, value: value,
); );
ValueStream<bool> get isFollowSystemTheme =>
_isFollowSystemThemeController.stream;
Future<void> setFollowSystemTheme(bool value) => _set<bool>( Future<void> setFollowSystemTheme(bool value) => _set<bool>(
controller: _isFollowSystemThemeController, controller: _isFollowSystemThemeController,
setter: (pref, value) => pref.setFollowSystemTheme(value), setter: (pref, value) => pref.setFollowSystemTheme(value),
value: value, value: value,
); );
ValueStream<bool> get isUseBlackInDarkTheme =>
_isUseBlackInDarkThemeController.stream;
Future<void> setUseBlackInDarkTheme(bool value) => _set<bool>( Future<void> setUseBlackInDarkTheme(bool value) => _set<bool>(
controller: _isUseBlackInDarkThemeController, controller: _isUseBlackInDarkThemeController,
setter: (pref, value) => pref.setUseBlackInDarkTheme(value), setter: (pref, value) => pref.setUseBlackInDarkTheme(value),
value: value, value: value,
); );
ValueStream<Color?> get seedColor => _seedColorController.stream;
Future<void> setSeedColor(Color? value) => _setOrRemove<Color>( Future<void> setSeedColor(Color? value) => _setOrRemove<Color>(
controller: _seedColorController, controller: _seedColorController,
setter: (pref, value) => pref.setSeedColor(value.withAlpha(0xFF).value), setter: (pref, value) => pref.setSeedColor(value.withAlpha(0xFF).value),
@ -235,51 +185,70 @@ class PrefController {
} }
} }
static language_util.AppLanguage _langIdToAppLanguage(int langId) { static AppLanguage _langIdToAppLanguage(int langId) {
try { try {
return language_util.supportedLanguages[langId]!; return supportedLanguages[langId]!;
} catch (_) { } catch (_) {
return language_util.supportedLanguages[0]!; return supportedLanguages[0]!;
} }
} }
final DiContainer _c; final DiContainer _c;
@npSubjectAccessor
late final _languageController = late final _languageController =
BehaviorSubject.seeded(_langIdToAppLanguage(_c.pref.getLanguageOr(0))); BehaviorSubject.seeded(_langIdToAppLanguage(_c.pref.getLanguageOr(0)));
@npSubjectAccessor
late final _homePhotosZoomLevelController = late final _homePhotosZoomLevelController =
BehaviorSubject.seeded(_c.pref.getHomePhotosZoomLevelOr(0)); BehaviorSubject.seeded(_c.pref.getHomePhotosZoomLevelOr(0));
@npSubjectAccessor
late final _albumBrowserZoomLevelController = late final _albumBrowserZoomLevelController =
BehaviorSubject.seeded(_c.pref.getAlbumBrowserZoomLevelOr(0)); BehaviorSubject.seeded(_c.pref.getAlbumBrowserZoomLevelOr(0));
@npSubjectAccessor
late final _homeAlbumsSortController = late final _homeAlbumsSortController =
BehaviorSubject.seeded(_c.pref.getHomeAlbumsSortOr(0)); BehaviorSubject.seeded(_c.pref.getHomeAlbumsSortOr(0));
@npSubjectAccessor
late final _isEnableExifController = late final _isEnableExifController =
BehaviorSubject.seeded(_c.pref.isEnableExifOr(true)); BehaviorSubject.seeded(_c.pref.isEnableExifOr(true));
@npSubjectAccessor
late final _shouldProcessExifWifiOnlyController = late final _shouldProcessExifWifiOnlyController =
BehaviorSubject.seeded(_c.pref.shouldProcessExifWifiOnlyOr(true)); BehaviorSubject.seeded(_c.pref.shouldProcessExifWifiOnlyOr(true));
@npSubjectAccessor
late final _memoriesRangeController = late final _memoriesRangeController =
BehaviorSubject.seeded(_c.pref.getMemoriesRangeOr(2)); BehaviorSubject.seeded(_c.pref.getMemoriesRangeOr(2));
@npSubjectAccessor
late final _isPhotosTabSortByNameController = late final _isPhotosTabSortByNameController =
BehaviorSubject.seeded(_c.pref.isPhotosTabSortByNameOr(false)); BehaviorSubject.seeded(_c.pref.isPhotosTabSortByNameOr(false));
@npSubjectAccessor
late final _viewerScreenBrightnessController = late final _viewerScreenBrightnessController =
BehaviorSubject.seeded(_c.pref.getViewerScreenBrightnessOr(-1)); BehaviorSubject.seeded(_c.pref.getViewerScreenBrightnessOr(-1));
@npSubjectAccessor
late final _isViewerForceRotationController = late final _isViewerForceRotationController =
BehaviorSubject.seeded(_c.pref.isViewerForceRotationOr(false)); BehaviorSubject.seeded(_c.pref.isViewerForceRotationOr(false));
@npSubjectAccessor
late final _gpsMapProviderController = BehaviorSubject.seeded( late final _gpsMapProviderController = BehaviorSubject.seeded(
GpsMapProvider.values[_c.pref.getGpsMapProviderOr(0)]); GpsMapProvider.values[_c.pref.getGpsMapProviderOr(0)]);
@npSubjectAccessor
late final _isAlbumBrowserShowDateController = late final _isAlbumBrowserShowDateController =
BehaviorSubject.seeded(_c.pref.isAlbumBrowserShowDateOr(false)); BehaviorSubject.seeded(_c.pref.isAlbumBrowserShowDateOr(false));
@npSubjectAccessor
late final _isDoubleTapExitController = late final _isDoubleTapExitController =
BehaviorSubject.seeded(_c.pref.isDoubleTapExitOr(false)); BehaviorSubject.seeded(_c.pref.isDoubleTapExitOr(false));
@npSubjectAccessor
late final _isSaveEditResultToServerController = late final _isSaveEditResultToServerController =
BehaviorSubject.seeded(_c.pref.isSaveEditResultToServerOr(true)); BehaviorSubject.seeded(_c.pref.isSaveEditResultToServerOr(true));
@npSubjectAccessor
late final _enhanceMaxSizeController = BehaviorSubject.seeded( late final _enhanceMaxSizeController = BehaviorSubject.seeded(
SizeInt(_c.pref.getEnhanceMaxWidthOr(), _c.pref.getEnhanceMaxHeightOr())); SizeInt(_c.pref.getEnhanceMaxWidthOr(), _c.pref.getEnhanceMaxHeightOr()));
@npSubjectAccessor
late final _isDarkThemeController = late final _isDarkThemeController =
BehaviorSubject.seeded(_c.pref.isDarkThemeOr(false)); BehaviorSubject.seeded(_c.pref.isDarkThemeOr(false));
@npSubjectAccessor
late final _isFollowSystemThemeController = late final _isFollowSystemThemeController =
BehaviorSubject.seeded(_c.pref.isFollowSystemThemeOr(false)); BehaviorSubject.seeded(_c.pref.isFollowSystemThemeOr(false));
@npSubjectAccessor
late final _isUseBlackInDarkThemeController = late final _isUseBlackInDarkThemeController =
BehaviorSubject.seeded(_c.pref.isUseBlackInDarkThemeOr(false)); BehaviorSubject.seeded(_c.pref.isUseBlackInDarkThemeOr(false));
@NpSubjectAccessor(type: "Color?")
late final _seedColorController = late final _seedColorController =
BehaviorSubject<Color?>.seeded(_c.pref.getSeedColor()?.run(Color.new)); BehaviorSubject<Color?>.seeded(_c.pref.getSeedColor()?.run(Color.new));
} }

View file

@ -12,3 +12,133 @@ extension _$PrefControllerNpLog on PrefController {
static final log = Logger("controller.pref_controller.PrefController"); static final log = Logger("controller.pref_controller.PrefController");
} }
// **************************************************************************
// NpSubjectAccessorGenerator
// **************************************************************************
extension $PrefControllerNpSubjectAccessor on PrefController {
// _languageController
ValueStream<AppLanguage> get language => _languageController.stream;
Stream<AppLanguage> get languageNew => language.skip(1);
Stream<AppLanguage> get languageChange => language.distinct().skip(1);
AppLanguage get languageValue => _languageController.value;
// _homePhotosZoomLevelController
ValueStream<int> get homePhotosZoomLevel =>
_homePhotosZoomLevelController.stream;
Stream<int> get homePhotosZoomLevelNew => homePhotosZoomLevel.skip(1);
Stream<int> get homePhotosZoomLevelChange =>
homePhotosZoomLevel.distinct().skip(1);
int get homePhotosZoomLevelValue => _homePhotosZoomLevelController.value;
// _albumBrowserZoomLevelController
ValueStream<int> get albumBrowserZoomLevel =>
_albumBrowserZoomLevelController.stream;
Stream<int> get albumBrowserZoomLevelNew => albumBrowserZoomLevel.skip(1);
Stream<int> get albumBrowserZoomLevelChange =>
albumBrowserZoomLevel.distinct().skip(1);
int get albumBrowserZoomLevelValue => _albumBrowserZoomLevelController.value;
// _homeAlbumsSortController
ValueStream<int> get homeAlbumsSort => _homeAlbumsSortController.stream;
Stream<int> get homeAlbumsSortNew => homeAlbumsSort.skip(1);
Stream<int> get homeAlbumsSortChange => homeAlbumsSort.distinct().skip(1);
int get homeAlbumsSortValue => _homeAlbumsSortController.value;
// _isEnableExifController
ValueStream<bool> get isEnableExif => _isEnableExifController.stream;
Stream<bool> get isEnableExifNew => isEnableExif.skip(1);
Stream<bool> get isEnableExifChange => isEnableExif.distinct().skip(1);
bool get isEnableExifValue => _isEnableExifController.value;
// _shouldProcessExifWifiOnlyController
ValueStream<bool> get shouldProcessExifWifiOnly =>
_shouldProcessExifWifiOnlyController.stream;
Stream<bool> get shouldProcessExifWifiOnlyNew =>
shouldProcessExifWifiOnly.skip(1);
Stream<bool> get shouldProcessExifWifiOnlyChange =>
shouldProcessExifWifiOnly.distinct().skip(1);
bool get shouldProcessExifWifiOnlyValue =>
_shouldProcessExifWifiOnlyController.value;
// _memoriesRangeController
ValueStream<int> get memoriesRange => _memoriesRangeController.stream;
Stream<int> get memoriesRangeNew => memoriesRange.skip(1);
Stream<int> get memoriesRangeChange => memoriesRange.distinct().skip(1);
int get memoriesRangeValue => _memoriesRangeController.value;
// _isPhotosTabSortByNameController
ValueStream<bool> get isPhotosTabSortByName =>
_isPhotosTabSortByNameController.stream;
Stream<bool> get isPhotosTabSortByNameNew => isPhotosTabSortByName.skip(1);
Stream<bool> get isPhotosTabSortByNameChange =>
isPhotosTabSortByName.distinct().skip(1);
bool get isPhotosTabSortByNameValue => _isPhotosTabSortByNameController.value;
// _viewerScreenBrightnessController
ValueStream<int> get viewerScreenBrightness =>
_viewerScreenBrightnessController.stream;
Stream<int> get viewerScreenBrightnessNew => viewerScreenBrightness.skip(1);
Stream<int> get viewerScreenBrightnessChange =>
viewerScreenBrightness.distinct().skip(1);
int get viewerScreenBrightnessValue =>
_viewerScreenBrightnessController.value;
// _isViewerForceRotationController
ValueStream<bool> get isViewerForceRotation =>
_isViewerForceRotationController.stream;
Stream<bool> get isViewerForceRotationNew => isViewerForceRotation.skip(1);
Stream<bool> get isViewerForceRotationChange =>
isViewerForceRotation.distinct().skip(1);
bool get isViewerForceRotationValue => _isViewerForceRotationController.value;
// _gpsMapProviderController
ValueStream<GpsMapProvider> get gpsMapProvider =>
_gpsMapProviderController.stream;
Stream<GpsMapProvider> get gpsMapProviderNew => gpsMapProvider.skip(1);
Stream<GpsMapProvider> get gpsMapProviderChange =>
gpsMapProvider.distinct().skip(1);
GpsMapProvider get gpsMapProviderValue => _gpsMapProviderController.value;
// _isAlbumBrowserShowDateController
ValueStream<bool> get isAlbumBrowserShowDate =>
_isAlbumBrowserShowDateController.stream;
Stream<bool> get isAlbumBrowserShowDateNew => isAlbumBrowserShowDate.skip(1);
Stream<bool> get isAlbumBrowserShowDateChange =>
isAlbumBrowserShowDate.distinct().skip(1);
bool get isAlbumBrowserShowDateValue =>
_isAlbumBrowserShowDateController.value;
// _isDoubleTapExitController
ValueStream<bool> get isDoubleTapExit => _isDoubleTapExitController.stream;
Stream<bool> get isDoubleTapExitNew => isDoubleTapExit.skip(1);
Stream<bool> get isDoubleTapExitChange => isDoubleTapExit.distinct().skip(1);
bool get isDoubleTapExitValue => _isDoubleTapExitController.value;
// _isSaveEditResultToServerController
ValueStream<bool> get isSaveEditResultToServer =>
_isSaveEditResultToServerController.stream;
Stream<bool> get isSaveEditResultToServerNew =>
isSaveEditResultToServer.skip(1);
Stream<bool> get isSaveEditResultToServerChange =>
isSaveEditResultToServer.distinct().skip(1);
bool get isSaveEditResultToServerValue =>
_isSaveEditResultToServerController.value;
// _enhanceMaxSizeController
ValueStream<SizeInt> get enhanceMaxSize => _enhanceMaxSizeController.stream;
Stream<SizeInt> get enhanceMaxSizeNew => enhanceMaxSize.skip(1);
Stream<SizeInt> get enhanceMaxSizeChange => enhanceMaxSize.distinct().skip(1);
SizeInt get enhanceMaxSizeValue => _enhanceMaxSizeController.value;
// _isDarkThemeController
ValueStream<bool> get isDarkTheme => _isDarkThemeController.stream;
Stream<bool> get isDarkThemeNew => isDarkTheme.skip(1);
Stream<bool> get isDarkThemeChange => isDarkTheme.distinct().skip(1);
bool get isDarkThemeValue => _isDarkThemeController.value;
// _isFollowSystemThemeController
ValueStream<bool> get isFollowSystemTheme =>
_isFollowSystemThemeController.stream;
Stream<bool> get isFollowSystemThemeNew => isFollowSystemTheme.skip(1);
Stream<bool> get isFollowSystemThemeChange =>
isFollowSystemTheme.distinct().skip(1);
bool get isFollowSystemThemeValue => _isFollowSystemThemeController.value;
// _isUseBlackInDarkThemeController
ValueStream<bool> get isUseBlackInDarkTheme =>
_isUseBlackInDarkThemeController.stream;
Stream<bool> get isUseBlackInDarkThemeNew => isUseBlackInDarkTheme.skip(1);
Stream<bool> get isUseBlackInDarkThemeChange =>
isUseBlackInDarkTheme.distinct().skip(1);
bool get isUseBlackInDarkThemeValue => _isUseBlackInDarkThemeController.value;
// _seedColorController
ValueStream<Color?> get seedColor => _seedColorController.stream;
Stream<Color?> get seedColorNew => seedColor.skip(1);
Stream<Color?> get seedColorChange => seedColor.distinct().skip(1);
Color? get seedColorValue => _seedColorController.value;
}

View file

@ -112,7 +112,7 @@ ThemeData buildDarkTheme(BuildContext context, [ColorScheme? dynamicScheme]) {
} }
Color? getSeedColor(BuildContext context) { Color? getSeedColor(BuildContext context) {
return context.read<PrefController>().seedColor.value; return context.read<PrefController>().seedColorValue;
} }
ColorScheme _getColorScheme( ColorScheme _getColorScheme(

View file

@ -7,7 +7,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
required this.controller, required this.controller,
required this.prefController, required this.prefController,
}) : super(_State.init( }) : super(_State.init(
zoom: prefController.albumBrowserZoomLevel.value, zoom: prefController.albumBrowserZoomLevelValue,
)) { )) {
on<_LoadItems>(_onLoad); on<_LoadItems>(_onLoad);
on<_TransformItems>(_onTransformItems); on<_TransformItems>(_onTransformItems);

View file

@ -15,7 +15,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
super(_State.init( super(_State.init(
collection: collection, collection: collection,
coverUrl: _getCoverUrl(collection), coverUrl: _getCoverUrl(collection),
zoom: prefController.albumBrowserZoomLevel.value, zoom: prefController.albumBrowserZoomLevelValue,
)) { )) {
_initItemController(collection); _initItemController(collection);

View file

@ -102,8 +102,8 @@ class _EditContentList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder<int>( return StreamBuilder<int>(
stream: context.read<PrefController>().albumBrowserZoomLevel, stream: context.read<PrefController>().albumBrowserZoomLevelChange,
initialData: context.read<PrefController>().albumBrowserZoomLevel.value, initialData: context.read<PrefController>().albumBrowserZoomLevelValue,
builder: (_, zoomLevel) { builder: (_, zoomLevel) {
if (zoomLevel.hasError) { if (zoomLevel.hasError) {
context.addEvent( context.addEvent(
@ -159,9 +159,9 @@ class _UnmodifiableEditContentList extends StatelessWidget {
sliver: SliverOpacity( sliver: SliverOpacity(
opacity: .25, opacity: .25,
sliver: StreamBuilder<int>( sliver: StreamBuilder<int>(
stream: context.read<PrefController>().albumBrowserZoomLevel, stream: context.read<PrefController>().albumBrowserZoomLevelChange,
initialData: initialData:
context.read<PrefController>().albumBrowserZoomLevel.value, context.read<PrefController>().albumBrowserZoomLevelValue,
builder: (_, zoomLevel) { builder: (_, zoomLevel) {
if (zoomLevel.hasError) { if (zoomLevel.hasError) {
context.addEvent(_SetMessage( context.addEvent(_SetMessage(

View file

@ -8,6 +8,7 @@ import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/controller/account_controller.dart'; import 'package:nc_photos/controller/account_controller.dart';
import 'package:nc_photos/controller/account_pref_controller.dart';
import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/di_container.dart';
import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/data_source.dart'; import 'package:nc_photos/entity/album/data_source.dart';
@ -187,8 +188,7 @@ class _HomeState extends State<Home> with TickerProviderStateMixin {
context context
.read<AccountController>() .read<AccountController>()
.accountPrefController .accountPrefController
.shareFolder .shareFolderValue,
.value,
); );
} catch (e, stacktrace) { } catch (e, stacktrace) {
_log.shout( _log.shout(

View file

@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util; import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/controller/account_controller.dart'; import 'package:nc_photos/controller/account_controller.dart';
import 'package:nc_photos/controller/account_pref_controller.dart';
import 'package:nc_photos/stream_util.dart'; import 'package:nc_photos/stream_util.dart';
import 'package:nc_photos/theme.dart'; import 'package:nc_photos/theme.dart';
import 'package:nc_photos/widget/account_picker_dialog.dart'; import 'package:nc_photos/widget/account_picker_dialog.dart';

View file

@ -20,7 +20,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
on<_SetError>(_onSetError); on<_SetError>(_onSetError);
_subscriptions.add(prefController.homeAlbumsSort.distinct().listen((event) { _subscriptions.add(prefController.homeAlbumsSortChange.listen((event) {
add(_UpdateCollectionSort(collection_util.CollectionSort.values[event])); add(_UpdateCollectionSort(collection_util.CollectionSort.values[event]));
})); }));
_subscriptions.add(controller.stream.listen((event) { _subscriptions.add(controller.stream.listen((event) {

View file

@ -13,9 +13,9 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
required this.personsController, required this.personsController,
required this.metadataController, required this.metadataController,
}) : super(_State.init( }) : super(_State.init(
zoom: prefController.homePhotosZoomLevel.value, zoom: prefController.homePhotosZoomLevelValue,
isEnableMemoryCollection: isEnableMemoryCollection:
accountPrefController.isEnableMemoryAlbum.value, accountPrefController.isEnableMemoryAlbumValue,
)) { )) {
on<_LoadItems>(_onLoad); on<_LoadItems>(_onLoad);
on<_RequestRefresh>(_onRequestRefresh); on<_RequestRefresh>(_onRequestRefresh);
@ -46,13 +46,14 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
on<_SetError>(_onSetError); on<_SetError>(_onSetError);
_subscriptions _subscriptions
.add(accountPrefController.isEnableMemoryAlbum.listen((event) { .add(accountPrefController.isEnableMemoryAlbumChange.listen((event) {
add(_SetEnableMemoryCollection(event)); add(_SetEnableMemoryCollection(event));
})); }));
_subscriptions.add(prefController.isPhotosTabSortByName.listen((event) { _subscriptions
.add(prefController.isPhotosTabSortByNameChange.listen((event) {
add(_SetSortByName(event)); add(_SetSortByName(event));
})); }));
_subscriptions.add(prefController.memoriesRange.listen((event) { _subscriptions.add(prefController.memoriesRangeChange.listen((event) {
add(_SetMemoriesRange(event)); add(_SetMemoriesRange(event));
})); }));
} }
@ -138,7 +139,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
account: account, account: account,
filesController: controller, filesController: controller,
personsController: personsController, personsController: personsController,
personProvider: accountPrefController.personProvider.value, personProvider: accountPrefController.personProviderValue,
); );
} }
@ -303,11 +304,11 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_ItemTransformerArgument( _ItemTransformerArgument(
account: account, account: account,
files: files, files: files,
sort: prefController.isPhotosTabSortByName.value sort: prefController.isPhotosTabSortByNameValue
? _ItemSort.filename ? _ItemSort.filename
: _ItemSort.dateTime, : _ItemSort.dateTime,
isGroupByDay: prefController.homePhotosZoomLevel.value >= 0, isGroupByDay: prefController.homePhotosZoomLevelValue >= 0,
memoriesDayRange: prefController.memoriesRange.value, memoriesDayRange: prefController.memoriesRangeValue,
locale: language_util.getSelectedLocale() ?? locale: language_util.getSelectedLocale() ??
PlatformDispatcher.instance.locale, PlatformDispatcher.instance.locale,
), ),

View file

@ -5,11 +5,11 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
language: prefController.language.value, language: prefController.languageValue,
isDarkTheme: prefController.isDarkTheme.value, isDarkTheme: prefController.isDarkThemeValue,
isFollowSystemTheme: prefController.isFollowSystemTheme.value, isFollowSystemTheme: prefController.isFollowSystemThemeValue,
isUseBlackInDarkTheme: prefController.isUseBlackInDarkTheme.value, isUseBlackInDarkTheme: prefController.isUseBlackInDarkThemeValue,
seedColor: prefController.seedColor.value?.value, seedColor: prefController.seedColorValue?.value,
)) { )) {
on<_Init>(_onInit); on<_Init>(_onInit);
} }
@ -21,23 +21,23 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEachIgnoreError<language_util.AppLanguage>( emit.forEachIgnoreError<language_util.AppLanguage>(
prefController.language, prefController.languageChange,
onData: (data) => state.copyWith(language: data), onData: (data) => state.copyWith(language: data),
), ),
emit.forEachIgnoreError<bool>( emit.forEachIgnoreError<bool>(
prefController.isDarkTheme, prefController.isDarkThemeChange,
onData: (data) => state.copyWith(isDarkTheme: data), onData: (data) => state.copyWith(isDarkTheme: data),
), ),
emit.forEachIgnoreError<bool>( emit.forEachIgnoreError<bool>(
prefController.isFollowSystemTheme, prefController.isFollowSystemThemeChange,
onData: (data) => state.copyWith(isFollowSystemTheme: data), onData: (data) => state.copyWith(isFollowSystemTheme: data),
), ),
emit.forEachIgnoreError<bool>( emit.forEachIgnoreError<bool>(
prefController.isUseBlackInDarkTheme, prefController.isUseBlackInDarkThemeChange,
onData: (data) => state.copyWith(isUseBlackInDarkTheme: data), onData: (data) => state.copyWith(isUseBlackInDarkTheme: data),
), ),
emit.forEachIgnoreError<Color?>( emit.forEachIgnoreError<Color?>(
prefController.seedColor, prefController.seedColorChange,
onData: (data) => state.copyWith(seedColor: data?.value), onData: (data) => state.copyWith(seedColor: data?.value),
), ),
]); ]);

View file

@ -9,6 +9,7 @@ import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc_util.dart'; import 'package:nc_photos/bloc_util.dart';
import 'package:nc_photos/controller/account_controller.dart'; import 'package:nc_photos/controller/account_controller.dart';
import 'package:nc_photos/controller/account_pref_controller.dart';
import 'package:nc_photos/controller/persons_controller.dart'; import 'package:nc_photos/controller/persons_controller.dart';
import 'package:nc_photos/controller/places_controller.dart'; import 'package:nc_photos/controller/places_controller.dart';
import 'package:nc_photos/entity/collection/builder.dart'; import 'package:nc_photos/entity/collection/builder.dart';

View file

@ -10,13 +10,13 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}) : _c = container, }) : _c = container,
super(_State.init( super(_State.init(
account: account, account: account,
label: accountPrefController.accountLabel.value, label: accountPrefController.accountLabelValue,
shareFolder: accountPrefController.shareFolder.value, shareFolder: accountPrefController.shareFolderValue,
personProvider: accountPrefController.personProvider.value, personProvider: accountPrefController.personProviderValue,
)) { )) {
on<_SetLabel>(_onSetLabel); on<_SetLabel>(_onSetLabel);
on<_OnUpdateLabel>(_onOnUpdateLabel); on<_OnUpdateLabel>(_onOnUpdateLabel);
_subscriptions.add(accountPrefController.accountLabel.listen( _subscriptions.add(accountPrefController.accountLabelChange.listen(
(event) { (event) {
add(_OnUpdateLabel(event)); add(_OnUpdateLabel(event));
}, },
@ -30,7 +30,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
on<_SetShareFolder>(_onSetShareFolder); on<_SetShareFolder>(_onSetShareFolder);
on<_OnUpdateShareFolder>(_onOnUpdateShareFolder); on<_OnUpdateShareFolder>(_onOnUpdateShareFolder);
_subscriptions.add(accountPrefController.shareFolder.listen( _subscriptions.add(accountPrefController.shareFolderChange.listen(
(event) { (event) {
add(_OnUpdateShareFolder(event)); add(_OnUpdateShareFolder(event));
}, },
@ -41,7 +41,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
on<_SetPersonProvider>(_onSetPersonProvider); on<_SetPersonProvider>(_onSetPersonProvider);
on<_OnUpdatePersonProvider>(_onOnUpdatePersonProvider); on<_OnUpdatePersonProvider>(_onOnUpdatePersonProvider);
_subscriptions.add(accountPrefController.personProvider.listen( _subscriptions.add(accountPrefController.personProviderChange.listen(
(event) { (event) {
add(_OnUpdatePersonProvider(event)); add(_OnUpdatePersonProvider(event));
}, },

View file

@ -5,7 +5,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
isBrowserShowDate: prefController.isAlbumBrowserShowDate.value, isBrowserShowDate: prefController.isAlbumBrowserShowDateValue,
)) { )) {
on<_Init>(_onInit); on<_Init>(_onInit);
on<_SetBrowserShowDate>(_onSetBrowserShowDate); on<_SetBrowserShowDate>(_onSetBrowserShowDate);
@ -17,7 +17,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) async { Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
return emit.forEach<bool>( return emit.forEach<bool>(
prefController.isAlbumBrowserShowDate, prefController.isAlbumBrowserShowDateChange,
onData: (data) => state.copyWith(isBrowserShowDate: data), onData: (data) => state.copyWith(isBrowserShowDate: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);

View file

@ -6,8 +6,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
isSaveEditResultToServer: isSaveEditResultToServer:
prefController.isSaveEditResultToServer.value, prefController.isSaveEditResultToServerValue,
maxSize: prefController.enhanceMaxSize.value, maxSize: prefController.enhanceMaxSizeValue,
)) { )) {
on<_Init>(_onInit); on<_Init>(_onInit);
on<_SetSaveEditResultToServer>(_onSetSaveEditResultToServer); on<_SetSaveEditResultToServer>(_onSetSaveEditResultToServer);
@ -21,7 +21,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( emit.forEach<bool>(
prefController.isSaveEditResultToServer, prefController.isSaveEditResultToServerChange,
onData: (data) => state.copyWith(isSaveEditResultToServer: data), onData: (data) => state.copyWith(isSaveEditResultToServer: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
@ -29,7 +29,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}, },
), ),
emit.forEach<SizeInt>( emit.forEach<SizeInt>(
prefController.enhanceMaxSize, prefController.enhanceMaxSizeChange,
onData: (data) => state.copyWith(maxSize: data), onData: (data) => state.copyWith(maxSize: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);

View file

@ -5,7 +5,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State.init( }) : super(_State.init(
selected: prefController.language.value, selected: prefController.languageValue,
)) { )) {
on<_Init>(_onInit); on<_Init>(_onInit);
on<_SelectLanguage>(_onSelectLanguage); on<_SelectLanguage>(_onSelectLanguage);
@ -31,10 +31,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) { Future<void> _onInit(_Init ev, Emitter<_State> emit) {
_log.info(ev); _log.info(ev);
return emit.forEach<language_util.AppLanguage>( return emit.forEach<language_util.AppLanguage>(
prefController.language, prefController.languageChange,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(selected: data),
selected: data,
),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
return state.copyWith( return state.copyWith(

View file

@ -5,8 +5,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
isEnable: prefController.isEnableExif.value, isEnable: prefController.isEnableExifValue,
isWifiOnly: prefController.shouldProcessExifWifiOnly.value, isWifiOnly: prefController.shouldProcessExifWifiOnlyValue,
)) { )) {
on<_Init>(_onInit); on<_Init>(_onInit);
on<_SetEnable>(_onSetEnable); on<_SetEnable>(_onSetEnable);
@ -20,7 +20,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( emit.forEach<bool>(
prefController.isEnableExif, prefController.isEnableExifChange,
onData: (data) => state.copyWith(isEnable: data), onData: (data) => state.copyWith(isEnable: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
@ -28,7 +28,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}, },
), ),
emit.forEach<bool>( emit.forEach<bool>(
prefController.shouldProcessExifWifiOnly, prefController.shouldProcessExifWifiOnlyChange,
onData: (data) => state.copyWith(isWifiOnly: data), onData: (data) => state.copyWith(isWifiOnly: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);

View file

@ -5,8 +5,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
isPhotosTabSortByName: prefController.isPhotosTabSortByName.value, isPhotosTabSortByName: prefController.isPhotosTabSortByNameValue,
isDoubleTapExit: prefController.isDoubleTapExit.value, isDoubleTapExit: prefController.isDoubleTapExitValue,
)) { )) {
on<_Init>(_onInit); on<_Init>(_onInit);
on<_SetPhotosTabSortByName>(_onSetPhotosTabSortByName); on<_SetPhotosTabSortByName>(_onSetPhotosTabSortByName);
@ -20,7 +20,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( emit.forEach<bool>(
prefController.isPhotosTabSortByName, prefController.isPhotosTabSortByNameChange,
onData: (data) => state.copyWith(isPhotosTabSortByName: data), onData: (data) => state.copyWith(isPhotosTabSortByName: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
@ -28,7 +28,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}, },
), ),
emit.forEach<bool>( emit.forEach<bool>(
prefController.isDoubleTapExit, prefController.isDoubleTapExitChange,
onData: (data) => state.copyWith(isDoubleTapExit: data), onData: (data) => state.copyWith(isDoubleTapExit: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);

View file

@ -6,9 +6,9 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
required this.prefController, required this.prefController,
required this.accountPrefController, required this.accountPrefController,
}) : super(_State( }) : super(_State(
isEnableMemories: accountPrefController.isEnableMemoryAlbum.value, isEnableMemories: accountPrefController.isEnableMemoryAlbumValue,
isPhotosTabSortByName: prefController.isPhotosTabSortByName.value, isPhotosTabSortByName: prefController.isPhotosTabSortByNameValue,
memoriesRange: prefController.memoriesRange.value, memoriesRange: prefController.memoriesRangeValue,
)) { )) {
on<_Init>(_onInit); on<_Init>(_onInit);
on<_SetEnableMemories>(_onSetEnableMemories); on<_SetEnableMemories>(_onSetEnableMemories);
@ -22,7 +22,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( emit.forEach<bool>(
accountPrefController.isEnableMemoryAlbum, accountPrefController.isEnableMemoryAlbumChange,
onData: (data) => state.copyWith(isEnableMemories: data), onData: (data) => state.copyWith(isEnableMemories: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
@ -30,7 +30,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}, },
), ),
emit.forEach<bool>( emit.forEach<bool>(
prefController.isPhotosTabSortByName, prefController.isPhotosTabSortByNameChange,
onData: (data) => state.copyWith(isPhotosTabSortByName: data), onData: (data) => state.copyWith(isPhotosTabSortByName: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
@ -38,7 +38,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}, },
), ),
emit.forEach<int>( emit.forEach<int>(
prefController.memoriesRange, prefController.memoriesRangeChange,
onData: (data) => state.copyWith(memoriesRange: data), onData: (data) => state.copyWith(memoriesRange: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);

View file

@ -5,9 +5,9 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
isFollowSystemTheme: prefController.isFollowSystemTheme.value, isFollowSystemTheme: prefController.isFollowSystemThemeValue,
isUseBlackInDarkTheme: prefController.isUseBlackInDarkTheme.value, isUseBlackInDarkTheme: prefController.isUseBlackInDarkThemeValue,
seedColor: prefController.seedColor.value?.value, seedColor: prefController.seedColorValue?.value,
)) { )) {
on<_Init>(_onInit); on<_Init>(_onInit);
on<_SetFollowSystemTheme>(_onSetFollowSystemTheme); on<_SetFollowSystemTheme>(_onSetFollowSystemTheme);
@ -22,7 +22,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( emit.forEach<bool>(
prefController.isFollowSystemTheme, prefController.isFollowSystemThemeChange,
onData: (data) => state.copyWith(isFollowSystemTheme: data), onData: (data) => state.copyWith(isFollowSystemTheme: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
@ -30,7 +30,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}, },
), ),
emit.forEach<bool>( emit.forEach<bool>(
prefController.isUseBlackInDarkTheme, prefController.isUseBlackInDarkThemeChange,
onData: (data) => state.copyWith(isUseBlackInDarkTheme: data), onData: (data) => state.copyWith(isUseBlackInDarkTheme: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
@ -38,7 +38,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}, },
), ),
emit.forEach<Color?>( emit.forEach<Color?>(
prefController.seedColor, prefController.seedColorChange,
onData: (data) => state.copyWith(seedColor: data?.value), onData: (data) => state.copyWith(seedColor: data?.value),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);

View file

@ -5,9 +5,9 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
screenBrightness: prefController.viewerScreenBrightness.value, screenBrightness: prefController.viewerScreenBrightnessValue,
isForceRotation: prefController.isViewerForceRotation.value, isForceRotation: prefController.isViewerForceRotationValue,
gpsMapProvider: prefController.gpsMapProvider.value, gpsMapProvider: prefController.gpsMapProviderValue,
)) { )) {
on<_Init>(_onInit); on<_Init>(_onInit);
on<_SetScreenBrightness>(_onSetScreenBrightness); on<_SetScreenBrightness>(_onSetScreenBrightness);
@ -22,7 +22,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<int>( emit.forEach<int>(
prefController.viewerScreenBrightness, prefController.viewerScreenBrightnessChange,
onData: (data) => state.copyWith(screenBrightness: data), onData: (data) => state.copyWith(screenBrightness: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
@ -30,7 +30,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}, },
), ),
emit.forEach<bool>( emit.forEach<bool>(
prefController.isViewerForceRotation, prefController.isViewerForceRotationChange,
onData: (data) => state.copyWith(isForceRotation: data), onData: (data) => state.copyWith(isForceRotation: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);
@ -38,7 +38,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
}, },
), ),
emit.forEach<GpsMapProvider>( emit.forEach<GpsMapProvider>(
prefController.gpsMapProvider, prefController.gpsMapProviderChange,
onData: (data) => state.copyWith(gpsMapProvider: data), onData: (data) => state.copyWith(gpsMapProvider: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
_log.severe("[_onInit] Uncaught exception", e, stackTrace); _log.severe("[_onInit] Uncaught exception", e, stackTrace);

View file

@ -70,7 +70,7 @@ class _Bloc extends Bloc<_Event, _State> {
); );
try { try {
return await ImportPotentialSharedAlbum(c)( return await ImportPotentialSharedAlbum(c)(
account, accountPrefController.shareFolder.value); account, accountPrefController.shareFolderValue);
} catch (e, stackTrace) { } catch (e, stackTrace) {
_log.shout( _log.shout(
"[_importPotentialSharedAlbum] Failed while ImportPotentialSharedAlbum", "[_importPotentialSharedAlbum] Failed while ImportPotentialSharedAlbum",

View file

@ -2,3 +2,4 @@ library np_codegen;
export 'src/drift_table_sort_annotations.dart'; export 'src/drift_table_sort_annotations.dart';
export 'src/np_log_annotations.dart'; export 'src/np_log_annotations.dart';
export 'src/np_subject_accessor_annotations.dart';

View file

@ -0,0 +1,9 @@
class NpSubjectAccessor {
const NpSubjectAccessor({
this.type,
});
final String? type;
}
const npSubjectAccessor = NpSubjectAccessor();

View file

@ -1,7 +1,7 @@
builders: builders:
np_log_build: np_log_build:
import: "package:np_codegen_build/builder.dart" import: "package:np_codegen_build/builder.dart"
builder_factories: ["driftTableSortBuilder", "npLogBuilder"] builder_factories: ["driftTableSortBuilder", "npLogBuilder", "npSubjectAccessorBuilder"]
# The `partId` argument to `SharedPartBuilder` is "some_cool_builder" # The `partId` argument to `SharedPartBuilder` is "some_cool_builder"
build_extensions: {".dart": [".np_codegen.g.part"]} build_extensions: {".dart": [".np_codegen.g.part"]}
auto_apply: dependents auto_apply: dependents

View file

@ -1,6 +1,7 @@
import 'package:build/build.dart'; import 'package:build/build.dart';
import 'package:np_codegen_build/src/drift_table_sort_generator.dart'; import 'package:np_codegen_build/src/drift_table_sort_generator.dart';
import 'package:np_codegen_build/src/np_log_generator.dart'; import 'package:np_codegen_build/src/np_log_generator.dart';
import 'package:np_codegen_build/src/np_subject_accessor_generator.dart';
import 'package:source_gen/source_gen.dart'; import 'package:source_gen/source_gen.dart';
Builder driftTableSortBuilder(BuilderOptions options) => Builder driftTableSortBuilder(BuilderOptions options) =>
@ -8,3 +9,6 @@ Builder driftTableSortBuilder(BuilderOptions options) =>
Builder npLogBuilder(BuilderOptions options) => Builder npLogBuilder(BuilderOptions options) =>
SharedPartBuilder([const NpLogGenerator()], "np_log"); SharedPartBuilder([const NpLogGenerator()], "np_log");
Builder npSubjectAccessorBuilder(BuilderOptions options) => SharedPartBuilder(
[const NpSubjectAccessorGenerator()], "np_subject_accessor");

View file

@ -0,0 +1,132 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:np_codegen/np_codegen.dart';
import 'package:source_gen/source_gen.dart';
class NpSubjectAccessorGenerator
extends GeneratorForAnnotation<NpSubjectAccessor> {
const NpSubjectAccessorGenerator();
@override
Future<String?> generateForAnnotatedElement(
Element element,
ConstantReader annotation,
BuildStep buildStep,
) async {
if (element is! ClassElement) {
// not class, probably field
return null;
}
final clazz = element;
final fields = await _getFields(buildStep.resolver, clazz);
return """
extension \$${clazz.name}NpSubjectAccessor on ${clazz.name} {
${_buildBody(fields)}
}
""";
}
String _buildBody(List<_FieldMeta> fields) {
final results = <String>[];
for (final f in fields) {
results
..add("// ${f.fullname}")
..add(
"ValueStream<${f.typeStr}> get ${f.name} => ${f.fullname}.stream;")
..add("Stream<${f.typeStr}> get ${f.name}New => ${f.name}.skip(1);")
..add(
"Stream<${f.typeStr}> get ${f.name}Change => ${f.name}.distinct().skip(1);")
..add("${f.typeStr} get ${f.name}Value => ${f.fullname}.value;");
}
return results.join("\n");
}
Future<List<_FieldMeta>> _getFields(
Resolver resolver, ClassElement clazz) async {
const typeChecker = TypeChecker.fromRuntime(NpSubjectAccessor);
final data = <_FieldMeta>[];
for (final f in clazz.fields.where(typeChecker.hasAnnotationOf)) {
// final annotation = typeChecker.annotationsOf(f).first;
// final type = annotation.getField("type")!.toTypeValue()!;
final parseName = _parseName(f);
final parseType = await _parseTypeString(resolver, f);
data.add(_FieldMeta(
name: parseName.name,
fullname: parseName.fullname,
typeStr: parseType.typeStr,
));
}
return data;
}
_NameParseResult _parseName(FieldElement field) {
var name = field.name;
if (name.startsWith("_")) {
name = name.substring(1);
}
if (name.endsWith("Controller")) {
name = name.substring(0, name.length - 10);
}
return _NameParseResult(name: name, fullname: field.name);
}
Future<_TypeParseResult> _parseTypeString(
Resolver resolver, FieldElement field) async {
String? typeStr;
if (const TypeChecker.fromRuntime(NpSubjectAccessor)
.hasAnnotationOf(field)) {
final annotation = const TypeChecker.fromRuntime(NpSubjectAccessor)
.annotationsOf(field)
.first;
final type = annotation.getField("type")?.toStringValue();
typeStr = type;
}
if (typeStr == null) {
final astNode = await resolver.astNodeFor(field, resolve: true);
typeStr = (astNode! as VariableDeclaration)
.initializer!
.staticType!
.getDisplayString(withNullability: true);
if (typeStr.startsWith("BehaviorSubject<")) {
typeStr = typeStr.substring(16, typeStr.length - 1);
}
if (typeStr == "InvalidType") {
throw UnsupportedError(
"Type can't be parsed, please specify the type in annotation: ${field.name}");
}
}
return _TypeParseResult(typeStr: typeStr);
}
}
class _NameParseResult {
const _NameParseResult({
required this.name,
required this.fullname,
});
final String name;
final String fullname;
}
class _TypeParseResult {
const _TypeParseResult({
required this.typeStr,
});
final String typeStr;
}
class _FieldMeta {
const _FieldMeta({
required this.name,
required this.fullname,
required this.typeStr,
});
final String name;
final String fullname;
final String typeStr;
}

View file

@ -16,12 +16,13 @@ dependencies:
dev_dependencies: dev_dependencies:
build_test: ^2.1.5 build_test: ^2.1.5
np_lints:
path: ../np_lints
path: any
test: any
code_gen_tester: code_gen_tester:
git: git:
url: https://github.com/rrousselGit/functional_widget url: https://github.com/rrousselGit/functional_widget
ref: v0.10.0 ref: v0.10.0
path: packages/code_gen_tester path: packages/code_gen_tester
np_lints:
path: ../np_lints
path: any
rxdart: any
test: any

View file

@ -0,0 +1,117 @@
import 'dart:io';
import 'package:build/build.dart';
import 'package:build_test/build_test.dart';
import 'package:np_codegen_build/src/np_subject_accessor_generator.dart';
import 'package:path/path.dart' as p;
import 'package:source_gen/source_gen.dart';
import 'package:test/test.dart';
void main() {
_resolveCompilationUnit("test/src/np_subject_accessor.dart");
tearDown(() {
// Increment this after each test so the next test has it's own package
_pkgCacheCount++;
});
group("NpSubjectAccessor", () {
test("empty", () async {
final src = _genSrc("""
@npSubjectAccessor
class Empty {}
""");
final expected = _genExpected(r"""
extension $EmptyNpSubjectAccessor on Empty {}
""");
return _buildTest(src, expected);
});
test("int", () async {
final src = _genSrc("""
@npSubjectAccessor
class IntTest {
@npSubjectAccessor
final _barController = BehaviorSubject.seeded(1);
}
""");
final expected = _genExpected(r"""
extension $IntTestNpSubjectAccessor on IntTest {
// _barController
ValueStream<int> get bar => _barController.stream;
Stream<int> get barNew => bar.skip(1);
Stream<int> get barChange => bar.distinct().skip(1);
int get barValue => _barController.value;
}
""");
return _buildTest(src, expected);
});
test("int nullable", () async {
final src = _genSrc("""
@npSubjectAccessor
class IntNullableTest {
@npSubjectAccessor
final _barController = BehaviorSubject<int?>.seeded(1);
}
""");
final expected = _genExpected(r"""
extension $IntNullableTestNpSubjectAccessor on IntNullableTest {
// _barController
ValueStream<int?> get bar => _barController.stream;
Stream<int?> get barNew => bar.skip(1);
Stream<int?> get barChange => bar.distinct().skip(1);
int? get barValue => _barController.value;
}
""");
return _buildTest(src, expected);
});
});
}
String _genSrc(String src) {
return """
import 'package:np_codegen/np_codegen.dart';
import 'package:rxdart/rxdart.dart';
part 'test.g.dart';
$src
""";
}
String _genExpected(String src) {
return """// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'test.dart';
// **************************************************************************
// NpSubjectAccessorGenerator
// **************************************************************************
$src""";
}
Future _buildTest(String src, String expected) {
return testBuilder(
PartBuilder([const NpSubjectAccessorGenerator()], ".g.dart"),
{"$_pkgName|lib/test.dart": src},
generateFor: {'$_pkgName|lib/test.dart'},
outputs: {"$_pkgName|lib/test.g.dart": decodedMatches(expected)},
);
}
// Taken from source_gen_test, unclear why this is needed...
Future<void> _resolveCompilationUnit(String filePath) async {
final assetId = AssetId.parse('a|lib/${p.basename(filePath)}');
final files =
Directory(p.dirname(filePath)).listSync().whereType<File>().toList();
final fileMap = Map<String, String>.fromEntries(files.map(
(f) => MapEntry('a|lib/${p.basename(f.path)}', f.readAsStringSync())));
await resolveSources(fileMap, (item) async {
return await item.libraryFor(assetId);
}, resolverFor: 'a|lib/${p.basename(filePath)}');
}
String get _pkgName => 'pkg$_pkgCacheCount';
int _pkgCacheCount = 1;

View file

@ -0,0 +1,7 @@
// ignore_for_file: unused_import
import 'package:np_codegen/np_codegen.dart';
import 'package:rxdart/rxdart.dart';
@npSubjectAccessor
class Foo {}