mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-05-14 04:02:17 -04:00
statenotifier
This commit is contained in:
parent
8f0b4aaba0
commit
7a49497620
15 changed files with 28 additions and 56 deletions
|
@ -207,7 +207,8 @@ class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.close),
|
icon: const Icon(Icons.close),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
activeChatState.add(null);
|
ref.read(activeChatStateProvider.notifier).state =
|
||||||
|
null;
|
||||||
}).paddingLTRB(16, 0, 16, 0)
|
}).paddingLTRB(16, 0, 16, 0)
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
|
|
@ -20,7 +20,7 @@ class ChatSingleContactItemWidget extends ConsumerWidget {
|
||||||
//final textTheme = theme.textTheme;
|
//final textTheme = theme.textTheme;
|
||||||
final scale = theme.extension<ScaleScheme>()!;
|
final scale = theme.extension<ScaleScheme>()!;
|
||||||
|
|
||||||
final activeChat = ref.watch(activeChatStateProvider).value;
|
final activeChat = ref.watch(activeChatStateProvider);
|
||||||
final remoteConversationRecordKey =
|
final remoteConversationRecordKey =
|
||||||
proto.TypedKeyProto.fromProto(contact.remoteConversationRecordKey);
|
proto.TypedKeyProto.fromProto(contact.remoteConversationRecordKey);
|
||||||
final selected = activeChat == remoteConversationRecordKey;
|
final selected = activeChat == remoteConversationRecordKey;
|
||||||
|
@ -69,7 +69,8 @@ class ChatSingleContactItemWidget extends ConsumerWidget {
|
||||||
// component is not dragged.
|
// component is not dragged.
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
activeChatState.add(remoteConversationRecordKey);
|
ref.read(activeChatStateProvider.notifier).state =
|
||||||
|
remoteConversationRecordKey;
|
||||||
ref.invalidate(fetchChatListProvider);
|
ref.invalidate(fetchChatListProvider);
|
||||||
},
|
},
|
||||||
title: Text(contact.editedProfile.name),
|
title: Text(contact.editedProfile.name),
|
||||||
|
|
|
@ -15,10 +15,8 @@ class SignalStrengthMeterWidget extends ConsumerWidget {
|
||||||
final scale = theme.extension<ScaleScheme>()!;
|
final scale = theme.extension<ScaleScheme>()!;
|
||||||
|
|
||||||
const iconSize = 16.0;
|
const iconSize = 16.0;
|
||||||
final connState = ref.watch(globalConnectionStateProvider).value;
|
final connState = ref.watch(globalConnectionStateProvider);
|
||||||
if (connState == null) {
|
|
||||||
return const Icon(Icons.signal_cellular_off, size: iconSize);
|
|
||||||
}
|
|
||||||
late final double value;
|
late final double value;
|
||||||
late final Color color;
|
late final Color color;
|
||||||
late final Color inactiveColor;
|
late final Color inactiveColor;
|
||||||
|
|
|
@ -31,7 +31,7 @@ class HomePage extends ConsumerStatefulWidget {
|
||||||
final contactList = ref.watch(fetchContactListProvider).asData?.value ??
|
final contactList = ref.watch(fetchContactListProvider).asData?.value ??
|
||||||
const IListConst([]);
|
const IListConst([]);
|
||||||
|
|
||||||
final activeChat = ref.watch(activeChatStateProvider).asData?.value;
|
final activeChat = ref.watch(activeChatStateProvider);
|
||||||
if (activeChat == null) {
|
if (activeChat == null) {
|
||||||
return const EmptyChatWidget();
|
return const EmptyChatWidget();
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ class HomePage extends ConsumerStatefulWidget {
|
||||||
activeChat,
|
activeChat,
|
||||||
);
|
);
|
||||||
if (activeChatContactIdx == -1) {
|
if (activeChatContactIdx == -1) {
|
||||||
activeChatState.add(null);
|
ref.read(activeChatStateProvider.notifier).state = null;
|
||||||
return const EmptyChatWidget();
|
return const EmptyChatWidget();
|
||||||
}
|
}
|
||||||
final activeChatContact = contactList[activeChatContactIdx];
|
final activeChatContact = contactList[activeChatContactIdx];
|
||||||
|
|
|
@ -100,7 +100,7 @@ class Processor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
globalConnectionState.add(cs);
|
globalConnectionState.state = cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> processUpdateConfig(VeilidUpdateConfig updateConfig) async {
|
Future<void> processUpdateConfig(VeilidUpdateConfig updateConfig) async {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
import '../proto/proto.dart' as proto;
|
import '../proto/proto.dart' as proto;
|
||||||
import '../proto/proto.dart' show Chat, ChatType;
|
import '../proto/proto.dart' show Chat, ChatType;
|
||||||
|
|
||||||
import '../tools/tools.dart';
|
|
||||||
import '../veilid_support/veilid_support.dart';
|
import '../veilid_support/veilid_support.dart';
|
||||||
import 'account.dart';
|
import 'account.dart';
|
||||||
|
|
||||||
|
@ -72,8 +72,8 @@ Future<void> deleteChat(
|
||||||
if (c.remoteConversationKey == remoteConversationKey) {
|
if (c.remoteConversationKey == remoteConversationKey) {
|
||||||
await chatList.tryRemoveItem(i);
|
await chatList.tryRemoveItem(i);
|
||||||
|
|
||||||
if (activeChatState.currentState == remoteConversationRecordKey) {
|
if (activeChatState.state == remoteConversationRecordKey) {
|
||||||
activeChatState.add(null);
|
activeChatState.state = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -113,7 +113,7 @@ Future<IList<Chat>?> fetchChatList(FetchChatListRef ref) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The selected chat
|
// The selected chat
|
||||||
ExternalStreamState<TypedKey?> activeChatState =
|
final activeChatState = StateController<TypedKey?>(null);
|
||||||
ExternalStreamState<TypedKey?>(null);
|
final activeChatStateProvider =
|
||||||
AutoDisposeStreamProvider<TypedKey?> activeChatStateProvider =
|
AutoDisposeStateNotifierProvider<StateController<TypedKey?>, TypedKey?>(
|
||||||
activeChatState.provider();
|
(ref) => activeChatState);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
import '../tools/tools.dart';
|
|
||||||
|
|
||||||
enum GlobalConnectionState {
|
enum GlobalConnectionState {
|
||||||
detached,
|
detached,
|
||||||
detaching,
|
detaching,
|
||||||
|
@ -13,7 +11,8 @@ enum GlobalConnectionState {
|
||||||
overAttached,
|
overAttached,
|
||||||
}
|
}
|
||||||
|
|
||||||
ExternalStreamState<GlobalConnectionState> globalConnectionState =
|
final globalConnectionState =
|
||||||
ExternalStreamState<GlobalConnectionState>(GlobalConnectionState.detached);
|
StateController<GlobalConnectionState>(GlobalConnectionState.detached);
|
||||||
AutoDisposeStreamProvider<GlobalConnectionState> globalConnectionStateProvider =
|
final globalConnectionStateProvider = AutoDisposeStateNotifierProvider<
|
||||||
globalConnectionState.provider();
|
StateController<GlobalConnectionState>,
|
||||||
|
GlobalConnectionState>((ref) => globalConnectionState);
|
||||||
|
|
|
@ -335,7 +335,7 @@ class ActiveConversationMessages extends _$ActiveConversationMessages {
|
||||||
FutureOr<IList<Message>?> build() async {
|
FutureOr<IList<Message>?> build() async {
|
||||||
await eventualVeilid.future;
|
await eventualVeilid.future;
|
||||||
|
|
||||||
final activeChat = activeChatState.currentState;
|
final activeChat = ref.watch(activeChatStateProvider);
|
||||||
if (activeChat == null) {
|
if (activeChat == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ class _FetchLocalAccountProviderElement
|
||||||
(origin as FetchLocalAccountProvider).accountMasterRecordKey;
|
(origin as FetchLocalAccountProvider).accountMasterRecordKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$localAccountsHash() => r'148d98fcd8a61147bb475708d50b9699887c5bec';
|
String _$localAccountsHash() => r'f19ec560b585d353219be82bc383b2c091660c53';
|
||||||
|
|
||||||
/// See also [LocalAccounts].
|
/// See also [LocalAccounts].
|
||||||
@ProviderFor(LocalAccounts)
|
@ProviderFor(LocalAccounts)
|
||||||
|
|
|
@ -157,7 +157,7 @@ class _FetchLoginProviderElement
|
||||||
(origin as FetchLoginProvider).accountMasterRecordKey;
|
(origin as FetchLoginProvider).accountMasterRecordKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$loginsHash() => r'41c4630869b474c409b2fb3461dd2a56d9350c7f';
|
String _$loginsHash() => r'2660f71bb7903464187a93fba5c07e22041e8c40';
|
||||||
|
|
||||||
/// See also [Logins].
|
/// See also [Logins].
|
||||||
@ProviderFor(Logins)
|
@ProviderFor(Logins)
|
||||||
|
|
|
@ -29,7 +29,7 @@ class RouterNotifier extends _$RouterNotifier implements Listenable {
|
||||||
hasAnyAccount = await ref.watch(
|
hasAnyAccount = await ref.watch(
|
||||||
localAccountsProvider.selectAsync((data) => data.isNotEmpty),
|
localAccountsProvider.selectAsync((data) => data.isNotEmpty),
|
||||||
);
|
);
|
||||||
hasActiveChat = ref.watch(activeChatStateProvider).value != null;
|
hasActiveChat = ref.watch(activeChatStateProvider) != null;
|
||||||
|
|
||||||
// When this notifier's state changes, inform GoRouter
|
// When this notifier's state changes, inform GoRouter
|
||||||
ref.listenSelf((_, __) {
|
ref.listenSelf((_, __) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ part of 'router_notifier.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$routerNotifierHash() => r'8e636edc119d07296a95a5de8a6edadb119154cf';
|
String _$routerNotifierHash() => r'f462d13cf63fa23a7a8e6a4edfa63984f32adaf1';
|
||||||
|
|
||||||
/// See also [RouterNotifier].
|
/// See also [RouterNotifier].
|
||||||
@ProviderFor(RouterNotifier)
|
@ProviderFor(RouterNotifier)
|
||||||
|
|
|
@ -133,7 +133,7 @@ class BackgroundTickerState extends ConsumerState<BackgroundTicker> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _doNewMessageCheck() async {
|
Future<void> _doNewMessageCheck() async {
|
||||||
final activeChat = activeChatState.currentState;
|
final activeChat = ref.read(activeChatStateProvider);
|
||||||
if (activeChat == null) {
|
if (activeChat == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
||||||
|
|
||||||
// Caches a state value which can be changed from anywhere
|
|
||||||
// Creates a provider interface that notices when the value changes
|
|
||||||
class ExternalStreamState<T> {
|
|
||||||
ExternalStreamState(T initialState)
|
|
||||||
: currentState = initialState,
|
|
||||||
streamController = StreamController<T>.broadcast();
|
|
||||||
T currentState;
|
|
||||||
StreamController<T> streamController;
|
|
||||||
void add(T newState) {
|
|
||||||
currentState = newState;
|
|
||||||
streamController.add(newState);
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoDisposeStreamProvider<T> provider() =>
|
|
||||||
AutoDisposeStreamProvider<T>((ref) async* {
|
|
||||||
if (await streamController.stream.isEmpty) {
|
|
||||||
yield currentState;
|
|
||||||
}
|
|
||||||
await for (final value in streamController.stream) {
|
|
||||||
yield value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
export 'animations.dart';
|
export 'animations.dart';
|
||||||
export 'external_stream_state.dart';
|
|
||||||
export 'loggy.dart';
|
export 'loggy.dart';
|
||||||
export 'phono_byte.dart';
|
export 'phono_byte.dart';
|
||||||
export 'radix_generator.dart';
|
export 'radix_generator.dart';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue