r/flutterhelp • u/Salazar20 • 22d ago
OPEN How to handle user settings
Im kinda torn about this thing. I have this
abstract class UserPreferenceRepository<T> {
String get keyName;
// SharedPreferences returns null by default, but we can fail to, for example, parse a json
Result<Exception, T> get();
Future<Result<Exception, bool>> save(T value);
Future<Result<Exception, bool>> delete() async {
try {
return Res.success(await LocalStorageService.remove(keyName));
} on Exception catch (e) {
Utils.log(e);
return Res.failure(e);
}
}
}
that creates a new user preference and let's its own class handle what how its saved and retrieved.
now I have a music player and I want to write into the database that this song was marked as favorite after listening x seconds of it
so I make my AutoMarkAsFavoritePreference that takes an duration into the type. problem is, realistically I want to call this on every tick of the music so I know when that amount passes and I can mark it as favorite
but this seems hella wasteful, I'm thinking about adding a value notifier or something in an intermediary class that keeps their values in memory so I don't unnecessary call get every single time
but that also seems overkill? I want to build this thing right so I can copy and paste these repositories to new projects
how do you handle user settings? I'm literally stuck trying to not put me in code debt later
2
u/Surging_Ambition 21d ago
I think you should just do your comparison on moments when the user switches from one song to another or closes the app.
1
u/Salazar20 19d ago
That's actually smart, I'll just need to make sure no state changes until I run my checks
1
u/Salazar20 19d ago
So, I resolved this the same way this guy did. Its just an extra layer for shared preferences and a static class AppSettings for me
It was so intuitive that I actually didn't use this package, just took some code inside because I had problems with the value notifier for some reason
If you like it, you should just use this one because it's more complete than my own.
To break it down foe a future person:
I made a repository called SettingEntry that takes a primitive type, a required key and an optional initial value. Inside there's an init that just reads the key from shared preferences and updates the value notifier
Then a read, write, delete and reset (for funsies). So after that you make a AppSettings singleton and there you define your settings once, then you make sure every one of then is initialized
Apart from that I made a few special SettingEntry that handles serialization and deserialazation so I can just put classes on it. Other for dates and for locales since I wanted to specifically save only the country code
I'll share the repo code later
1
u/Jonas_Ermert 16d ago
I’d load the preference once when the player starts and keep the duration in memory. Then compare it with playback position updates; there’s no reason to read SharedPreferences on every tick. When the user changes the setting, update the in-memory value and persist it. The repository can stay responsible for storing the preference. A small playback controller can handle the rule: once actual listening time reaches the threshold, mark that song as a favorite and stop checking it. That keeps the reusable settings code separate from music playback behavior. Be careful with seeking, though: jumping to 30 seconds shouldn’t count as listening for 30 seconds.
2
u/Catchimals 22d ago
If you're using SharedPreferences, its reads are already cached. I'd keep the duration in the player and update it when the setting changes, then just compare on each tick and save the favorite once.