feat(flutter): settings screen + 4-icon home AppBar
- models/my_profile.dart (MyProfile + ListenBrainzStatus) - api/endpoints/settings.dart (profile / password / listenbrainz CRUD) - settings/settings_screen.dart with three sections: - Profile: display_name + email, Save profile - Password: current + new + confirm, validates >=8 + match - ListenBrainz: token paste + scrobble-enabled toggle - /settings route + Settings icon on home AppBar - Home AppBar now: Library + Playlists + Search + Settings (was just Search)
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
/// Mirrors web/src/lib/api/me.ts MyProfile. The `display_name` and
|
||||
/// `email` are nullable — server returns null when the user hasn't
|
||||
/// set them yet (registration only requires a username).
|
||||
class MyProfile {
|
||||
const MyProfile({
|
||||
required this.id,
|
||||
required this.username,
|
||||
this.displayName,
|
||||
this.email,
|
||||
required this.isAdmin,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final String username;
|
||||
final String? displayName;
|
||||
final String? email;
|
||||
final bool isAdmin;
|
||||
|
||||
factory MyProfile.fromJson(Map<String, dynamic> j) => MyProfile(
|
||||
id: j['id'] as String? ?? '',
|
||||
username: j['username'] as String? ?? '',
|
||||
displayName: j['display_name'] as String?,
|
||||
email: j['email'] as String?,
|
||||
isAdmin: j['is_admin'] as bool? ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
/// Mirrors web/src/lib/api/listenbrainz.ts LBStatus.
|
||||
class ListenBrainzStatus {
|
||||
const ListenBrainzStatus({
|
||||
required this.enabled,
|
||||
required this.tokenSet,
|
||||
this.lastScrobbledAt,
|
||||
});
|
||||
|
||||
final bool enabled;
|
||||
/// True when the user has stored a token (token itself is never read
|
||||
/// back from the server). UI uses this to show "token saved" vs
|
||||
/// "no token" without exposing the value.
|
||||
final bool tokenSet;
|
||||
final String? lastScrobbledAt;
|
||||
|
||||
factory ListenBrainzStatus.fromJson(Map<String, dynamic> j) =>
|
||||
ListenBrainzStatus(
|
||||
enabled: j['enabled'] as bool? ?? false,
|
||||
tokenSet: j['token_set'] as bool? ?? false,
|
||||
lastScrobbledAt: j['last_scrobbled_at'] as String?,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user