76 lines
2.5 KiB
Dart
76 lines
2.5 KiB
Dart
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|||
|
|
|
||
|
|
import '../utils/shared_preferences_provider.dart';
|
||
|
|
import 'connection.dart';
|
||
|
|
import 'connection_storage.dart';
|
||
|
|
|
||
|
|
part 'connection_providers.g.dart';
|
||
|
|
|
||
|
|
@Riverpod(keepAlive: true)
|
||
|
|
ConnectionStorage connectionStorage(Ref ref) {
|
||
|
|
return ConnectionStorage(ref.watch(sharedPreferencesProvider));
|
||
|
|
}
|
||
|
|
|
||
|
|
/// The full list of saved connections. Mutations persist immediately.
|
||
|
|
@Riverpod(keepAlive: true)
|
||
|
|
class SavedConnections extends _$SavedConnections {
|
||
|
|
@override
|
||
|
|
List<Connection> build() => ref.watch(connectionStorageProvider).readConnections();
|
||
|
|
|
||
|
|
Future<void> add(Connection connection) async {
|
||
|
|
state = [...state, connection];
|
||
|
|
await ref.read(connectionStorageProvider).writeConnections(state);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> update(Connection connection) async {
|
||
|
|
state = [
|
||
|
|
for (final c in state)
|
||
|
|
if (c.id == connection.id) connection else c,
|
||
|
|
];
|
||
|
|
await ref.read(connectionStorageProvider).writeConnections(state);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> remove(String id) async {
|
||
|
|
state = state.where((c) => c.id != id).toList(growable: false);
|
||
|
|
await ref.read(connectionStorageProvider).writeConnections(state);
|
||
|
|
final activeId = ref.read(activeConnectionIdProvider);
|
||
|
|
if (activeId == id) {
|
||
|
|
await ref.read(activeConnectionIdProvider.notifier).setActive(
|
||
|
|
state.isEmpty ? null : state.first.id,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// The id of the currently active connection, or null if none is selected
|
||
|
|
/// (e.g. first launch with nothing configured yet).
|
||
|
|
@Riverpod(keepAlive: true)
|
||
|
|
class ActiveConnectionId extends _$ActiveConnectionId {
|
||
|
|
@override
|
||
|
|
String? build() {
|
||
|
|
final stored = ref.watch(connectionStorageProvider).readActiveConnectionId();
|
||
|
|
final connections = ref.watch(savedConnectionsProvider);
|
||
|
|
if (stored != null && connections.any((c) => c.id == stored)) return stored;
|
||
|
|
return connections.isEmpty ? null : connections.first.id;
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> setActive(String? id) async {
|
||
|
|
state = id;
|
||
|
|
await ref.read(connectionStorageProvider).writeActiveConnectionId(id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// The currently active [Connection], or null if none is configured.
|
||
|
|
/// Everything in `core/network` derives from this — switching it rebuilds
|
||
|
|
/// the API client and, transitively, every provider that watches it.
|
||
|
|
@riverpod
|
||
|
|
Connection? activeConnection(Ref ref) {
|
||
|
|
final id = ref.watch(activeConnectionIdProvider);
|
||
|
|
if (id == null) return null;
|
||
|
|
final connections = ref.watch(savedConnectionsProvider);
|
||
|
|
for (final c in connections) {
|
||
|
|
if (c.id == id) return c;
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|