chore: run dart format
Some checks are pending
Flutter CI & Release / Test (push) Waiting to run
Flutter CI & Release / Build Android APKs (push) Blocked by required conditions
Flutter CI & Release / build_linux (push) Blocked by required conditions
Flutter CI & Release / Create GitHub Release (push) Blocked by required conditions

This commit is contained in:
Dr.Blank 2026-01-10 16:51:05 +05:30
parent a520136e01
commit e23c0b6c5f
No known key found for this signature in database
GPG key ID: BA5F87FF0560C57B
84 changed files with 1565 additions and 1945 deletions

View file

@ -20,16 +20,12 @@ import 'package:vaani/shared/extensions/obfuscation.dart' show ObfuscateSet;
import 'package:vaani/shared/widgets/add_new_server.dart' show AddNewServer;
class ServerManagerPage extends HookConsumerWidget {
const ServerManagerPage({
super.key,
});
const ServerManagerPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
title: const Text('Manage Accounts'),
),
appBar: AppBar(title: const Text('Manage Accounts')),
body: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
@ -41,9 +37,7 @@ class ServerManagerPage extends HookConsumerWidget {
}
class ServerManagerBody extends HookConsumerWidget {
const ServerManagerBody({
super.key,
});
const ServerManagerBody({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
@ -61,9 +55,7 @@ class ServerManagerBody extends HookConsumerWidget {
// crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
children: [
const Text(
'Registered Servers',
),
const Text('Registered Servers'),
Expanded(
child: ListView.builder(
itemCount: registeredServers.length,
@ -76,21 +68,17 @@ class ServerManagerBody extends HookConsumerWidget {
'Users: ${availableUsers.where((element) => element.server == registeredServer).length}',
),
// children are list of users of this server
children: availableUsers
.where(
(element) => element.server == registeredServer,
)
.map<Widget>(
(e) => AvailableUserTile(user: e),
)
.nonNulls
.toList()
// add buttons of delete server and add user to server at the end
..addAll([
AddUserTile(server: registeredServer),
DeleteServerTile(server: registeredServer),
]),
children:
availableUsers
.where((element) => element.server == registeredServer)
.map<Widget>((e) => AvailableUserTile(user: e))
.nonNulls
.toList()
// add buttons of delete server and add user to server at the end
..addAll([
AddUserTile(server: registeredServer),
DeleteServerTile(server: registeredServer),
]),
);
},
),
@ -111,28 +99,24 @@ class ServerManagerBody extends HookConsumerWidget {
final newServer = model.AudiobookShelfServer(
serverUrl: makeBaseUrl(serverURIController.text),
);
ref.read(audiobookShelfServerProvider.notifier).addServer(
newServer,
);
ref.read(apiSettingsProvider.notifier).updateState(
apiSettings.copyWith(
activeServer: newServer,
),
ref
.read(audiobookShelfServerProvider.notifier)
.addServer(newServer);
ref
.read(apiSettingsProvider.notifier)
.updateState(
apiSettings.copyWith(activeServer: newServer),
);
serverURIController.clear();
} on ServerAlreadyExistsException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(e.toString()),
),
);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(e.toString())));
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Invalid URL'),
),
);
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('Invalid URL')));
}
},
),
@ -144,10 +128,7 @@ class ServerManagerBody extends HookConsumerWidget {
}
class DeleteServerTile extends HookConsumerWidget {
const DeleteServerTile({
super.key,
required this.server,
});
const DeleteServerTile({super.key, required this.server});
final model.AudiobookShelfServer server;
@ -167,9 +148,7 @@ class DeleteServerTile extends HookConsumerWidget {
child: Text.rich(
TextSpan(
children: [
const TextSpan(
text: 'This will remove the server ',
),
const TextSpan(text: 'This will remove the server '),
TextSpan(
text: server.serverUrl.host,
style: TextStyle(
@ -194,13 +173,8 @@ class DeleteServerTile extends HookConsumerWidget {
TextButton(
onPressed: () {
ref
.read(
audiobookShelfServerProvider.notifier,
)
.removeServer(
server,
removeUsers: true,
);
.read(audiobookShelfServerProvider.notifier)
.removeServer(server, removeUsers: true);
Navigator.of(context).pop();
},
child: const Text('Delete'),
@ -215,10 +189,7 @@ class DeleteServerTile extends HookConsumerWidget {
}
class AddUserTile extends HookConsumerWidget {
const AddUserTile({
super.key,
required this.server,
});
const AddUserTile({super.key, required this.server});
final model.AudiobookShelfServer server;
@ -252,10 +223,12 @@ class AddUserTile extends HookConsumerWidget {
label: 'Switch',
onPressed: () {
// Switch to the new user
ref.read(apiSettingsProvider.notifier).updateState(
ref.read(apiSettingsProvider).copyWith(
activeUser: user,
),
ref
.read(apiSettingsProvider.notifier)
.updateState(
ref
.read(apiSettingsProvider)
.copyWith(activeUser: user),
);
context.goNamed(Routes.home.name);
},
@ -283,10 +256,7 @@ class AddUserTile extends HookConsumerWidget {
}
class AvailableUserTile extends HookConsumerWidget {
const AvailableUserTile({
super.key,
required this.user,
});
const AvailableUserTile({super.key, required this.user});
final model.AuthenticatedUser user;
@ -303,18 +273,14 @@ class AvailableUserTile extends HookConsumerWidget {
onTap: apiSettings.activeUser == user
? null
: () {
ref.read(apiSettingsProvider.notifier).updateState(
apiSettings.copyWith(
activeUser: user,
),
);
ref
.read(apiSettingsProvider.notifier)
.updateState(apiSettings.copyWith(activeUser: user));
// pop all routes and go to the home page
// while (context.canPop()) {
// context.pop();
// }
context.goNamed(
Routes.home.name,
);
context.goNamed(Routes.home.name);
},
trailing: IconButton(
icon: const Icon(Icons.delete),
@ -337,9 +303,7 @@ class AvailableUserTile extends HookConsumerWidget {
color: Theme.of(context).colorScheme.primary,
),
),
const TextSpan(
text: ' from this app.',
),
const TextSpan(text: ' from this app.'),
],
),
),
@ -353,9 +317,7 @@ class AvailableUserTile extends HookConsumerWidget {
TextButton(
onPressed: () {
ref
.read(
authenticatedUsersProvider.notifier,
)
.read(authenticatedUsersProvider.notifier)
.removeUser(user);
Navigator.of(context).pop();
},

View file

@ -11,10 +11,7 @@ import 'package:flutter/foundation.dart';
import 'package:vaani/main.dart' show appLogger;
class LibrarySwitchChip extends HookConsumerWidget {
const LibrarySwitchChip({
super.key,
required this.libraries,
});
const LibrarySwitchChip({super.key, required this.libraries});
final List<Library> libraries;
@override
@ -26,30 +23,22 @@ class LibrarySwitchChip extends HookConsumerWidget {
AbsIcons.getIconByName(
apiSettings.activeLibraryId != null
? libraries
.firstWhere(
(lib) => lib.id == apiSettings.activeLibraryId,
)
.icon
.firstWhere((lib) => lib.id == apiSettings.activeLibraryId)
.icon
: libraries.first.icon,
),
), // Replace with your icon
label: const Text('Change Library'),
// Enable only if libraries are loaded and not empty
onPressed: libraries.isNotEmpty
? () => showLibrarySwitcher(
context,
ref,
)
? () => showLibrarySwitcher(context, ref)
: null, // Disable if no libraries
);
}
}
// --- Helper Function to Show the Switcher ---
void showLibrarySwitcher(
BuildContext context,
WidgetRef ref,
) {
void showLibrarySwitcher(BuildContext context, WidgetRef ref) {
final content = _LibrarySelectionContent();
// --- Platform-Specific UI ---
@ -209,7 +198,9 @@ class _LibrarySelectionContent extends ConsumerWidget {
// Get current settings state
final currentSettings = ref.read(apiSettingsProvider);
// Update the active library ID
ref.read(apiSettingsProvider.notifier).updateState(
ref
.read(apiSettingsProvider.notifier)
.updateState(
currentSettings.copyWith(activeLibraryId: library.id),
);
// Close the dialog/bottom sheet

View file

@ -12,9 +12,7 @@ import 'package:vaani/shared/widgets/not_implemented.dart';
import 'package:vaani/shared/widgets/vaani_logo.dart';
class YouPage extends HookConsumerWidget {
const YouPage({
super.key,
});
const YouPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
@ -88,8 +86,9 @@ class YouPage extends HookConsumerWidget {
// Maybe show error details or allow retry
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text('Failed to load libraries: $error'),
content: Text(
'Failed to load libraries: $error',
),
),
);
},
@ -159,9 +158,7 @@ class YouPage extends HookConsumerWidget {
Theme.of(context).colorScheme.primary,
BlendMode.srcIn,
),
child: const VaaniLogo(
size: 48,
),
child: const VaaniLogo(size: 48),
),
),
],
@ -176,9 +173,7 @@ class YouPage extends HookConsumerWidget {
}
class UserBar extends HookConsumerWidget {
const UserBar({
super.key,
});
const UserBar({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
@ -217,8 +212,9 @@ class UserBar extends HookConsumerWidget {
Text(
api.baseUrl.toString(),
style: textTheme.bodyMedium?.copyWith(
color:
themeData.colorScheme.onSurface.withValues(alpha: 0.6),
color: themeData.colorScheme.onSurface.withValues(
alpha: 0.6,
),
),
),
],