-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
708 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 118 additions & 4 deletions
122
example/lib/src/feature/chat/controller/chat_connection_state.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,119 @@ | ||
enum ChatConnectionState { | ||
disconnected, | ||
connecting, | ||
connected, | ||
import 'package:meta/meta.dart'; | ||
|
||
/// {@template chat_connection_state} | ||
/// ChatConnectionState. | ||
/// {@endtemplate} | ||
sealed class ChatConnectionState extends _$ChatConnectionStateBase { | ||
/// Disconnected | ||
/// {@macro chat_connection_state} | ||
const factory ChatConnectionState.disconnected({ | ||
String message, | ||
}) = ChatConnectionState$Disconnected; | ||
|
||
/// Connecting | ||
/// {@macro chat_connection_state} | ||
const factory ChatConnectionState.connecting({ | ||
String message, | ||
}) = ChatConnectionState$Connecting; | ||
|
||
/// Connected | ||
/// {@macro chat_connection_state} | ||
const factory ChatConnectionState.connected({ | ||
String message, | ||
}) = ChatConnectionState$Connected; | ||
|
||
/// {@macro chat_connection_state} | ||
const ChatConnectionState({required super.message}); | ||
} | ||
|
||
/// Disconnected | ||
/// {@nodoc} | ||
final class ChatConnectionState$Disconnected extends ChatConnectionState { | ||
/// {@nodoc} | ||
const ChatConnectionState$Disconnected({super.message = 'Disconnected'}); | ||
} | ||
|
||
/// Connecting | ||
/// {@nodoc} | ||
final class ChatConnectionState$Connecting extends ChatConnectionState { | ||
/// {@nodoc} | ||
const ChatConnectionState$Connecting({super.message = 'Connecting'}); | ||
} | ||
|
||
/// Connected | ||
/// {@nodoc} | ||
final class ChatConnectionState$Connected extends ChatConnectionState { | ||
/// {@nodoc} | ||
const ChatConnectionState$Connected({super.message = 'Connected'}); | ||
} | ||
|
||
/// Pattern matching for [ChatConnectionState]. | ||
typedef ChatConnectionStateMatch<R, S extends ChatConnectionState> = R Function( | ||
S state); | ||
|
||
/// {@nodoc} | ||
@immutable | ||
abstract base class _$ChatConnectionStateBase { | ||
/// {@nodoc} | ||
const _$ChatConnectionStateBase({required this.message}); | ||
|
||
/// Message or state description. | ||
@nonVirtual | ||
final String message; | ||
|
||
/// Is connecting? | ||
bool get isConnecting => | ||
maybeMap<bool>(orElse: () => false, connecting: (_) => true); | ||
|
||
/// Is connected? | ||
bool get isConnected => | ||
maybeMap<bool>(orElse: () => false, connected: (_) => true); | ||
|
||
/// Is disconnected? | ||
bool get isDisconnected => | ||
maybeMap<bool>(orElse: () => false, disconnected: (_) => true); | ||
|
||
/// Pattern matching for [ChatConnectionState]. | ||
R map<R>({ | ||
required ChatConnectionStateMatch<R, ChatConnectionState$Disconnected> | ||
disconnected, | ||
required ChatConnectionStateMatch<R, ChatConnectionState$Connecting> | ||
connecting, | ||
required ChatConnectionStateMatch<R, ChatConnectionState$Connected> | ||
connected, | ||
}) => | ||
switch (this) { | ||
ChatConnectionState$Disconnected s => disconnected(s), | ||
ChatConnectionState$Connecting s => connecting(s), | ||
ChatConnectionState$Connected s => connected(s), | ||
_ => throw AssertionError(), | ||
}; | ||
|
||
/// Pattern matching for [ChatConnectionState]. | ||
R maybeMap<R>({ | ||
ChatConnectionStateMatch<R, ChatConnectionState$Disconnected>? disconnected, | ||
ChatConnectionStateMatch<R, ChatConnectionState$Connecting>? connecting, | ||
ChatConnectionStateMatch<R, ChatConnectionState$Connected>? connected, | ||
required R Function() orElse, | ||
}) => | ||
map<R>( | ||
disconnected: disconnected ?? (_) => orElse(), | ||
connecting: connecting ?? (_) => orElse(), | ||
connected: connected ?? (_) => orElse(), | ||
); | ||
|
||
/// Pattern matching for [ChatConnectionState]. | ||
R? mapOrNull<R>({ | ||
ChatConnectionStateMatch<R, ChatConnectionState$Disconnected>? disconnected, | ||
ChatConnectionStateMatch<R, ChatConnectionState$Connecting>? connecting, | ||
ChatConnectionStateMatch<R, ChatConnectionState$Connected>? connected, | ||
}) => | ||
map<R?>( | ||
disconnected: disconnected ?? (_) => null, | ||
connecting: connecting ?? (_) => null, | ||
connected: connected ?? (_) => null, | ||
); | ||
|
||
@override | ||
String toString() => message; | ||
} |
41 changes: 41 additions & 0 deletions
41
example/lib/src/feature/chat/controller/chat_messages_controller.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import 'package:l/l.dart'; | ||
import 'package:spinifyapp/src/common/controller/droppable_controller_concurrency.dart'; | ||
import 'package:spinifyapp/src/common/controller/state_controller.dart'; | ||
import 'package:spinifyapp/src/feature/authentication/model/user.dart'; | ||
import 'package:spinifyapp/src/feature/chat/controller/chat_messages_state.dart'; | ||
import 'package:spinifyapp/src/feature/chat/data/chat_repository.dart'; | ||
|
||
final class ChatMessagesController extends StateController<ChatMessagesState> | ||
with DroppableControllerConcurrency { | ||
ChatMessagesController({required IChatRepository repository}) | ||
: _repository = repository, | ||
super(initialState: ChatMessagesState.initial); | ||
|
||
final IChatRepository _repository; | ||
|
||
void sendMessage(AuthenticatedUser user, String message) => handle( | ||
() async { | ||
l.v6('Sending message'); | ||
await _repository.sendMessage(user, message); | ||
setState(ChatMessagesState.successful( | ||
data: state.data, message: 'Message sent')); | ||
l.v6('Message sent'); | ||
}, | ||
(error, stackTrace) { | ||
l.w('Error sending message: $error', stackTrace); | ||
setState( | ||
ChatMessagesState.error( | ||
data: state.data, message: 'Error sending message'), | ||
); | ||
}, | ||
() => setState(ChatMessagesState.idle(data: state.data)), | ||
); | ||
|
||
void disconnect() => handle(_repository.disconnect); | ||
|
||
@override | ||
void dispose() { | ||
_repository.disconnect(); | ||
super.dispose(); | ||
} | ||
} |
161 changes: 161 additions & 0 deletions
161
example/lib/src/feature/chat/controller/chat_messages_state.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import 'package:meta/meta.dart'; | ||
|
||
/// {@template chat_messages_state_placeholder} | ||
/// Entity placeholder for ChatMessagesState | ||
/// {@endtemplate} | ||
typedef ChatMessagesEntity = Object; | ||
|
||
/// {@template chat_messages_state} | ||
/// ChatMessagesState. | ||
/// {@endtemplate} | ||
sealed class ChatMessagesState extends _$ChatMessagesStateBase { | ||
/// Idling state | ||
/// {@macro chat_messages_state} | ||
const factory ChatMessagesState.idle({ | ||
required ChatMessagesEntity? data, | ||
String message, | ||
}) = ChatMessagesState$Idle; | ||
|
||
/// Processing | ||
/// {@macro chat_messages_state} | ||
const factory ChatMessagesState.processing({ | ||
required ChatMessagesEntity? data, | ||
String message, | ||
}) = ChatMessagesState$Processing; | ||
|
||
/// Successful | ||
/// {@macro chat_messages_state} | ||
const factory ChatMessagesState.successful({ | ||
required ChatMessagesEntity? data, | ||
String message, | ||
}) = ChatMessagesState$Successful; | ||
|
||
/// An error has occurred | ||
/// {@macro chat_messages_state} | ||
const factory ChatMessagesState.error({ | ||
required ChatMessagesEntity? data, | ||
String message, | ||
}) = ChatMessagesState$Error; | ||
|
||
/// {@macro chat_messages_state} | ||
const ChatMessagesState({required super.data, required super.message}); | ||
|
||
static ChatMessagesState get initial => | ||
const ChatMessagesState.idle(data: null); | ||
} | ||
|
||
/// Idling state | ||
/// {@nodoc} | ||
final class ChatMessagesState$Idle extends ChatMessagesState { | ||
/// {@nodoc} | ||
const ChatMessagesState$Idle({required super.data, super.message = 'Idling'}); | ||
} | ||
|
||
/// Processing | ||
/// {@nodoc} | ||
final class ChatMessagesState$Processing extends ChatMessagesState { | ||
/// {@nodoc} | ||
const ChatMessagesState$Processing( | ||
{required super.data, super.message = 'Processing'}); | ||
} | ||
|
||
/// Successful | ||
/// {@nodoc} | ||
final class ChatMessagesState$Successful extends ChatMessagesState { | ||
/// {@nodoc} | ||
const ChatMessagesState$Successful( | ||
{required super.data, super.message = 'Successful'}); | ||
} | ||
|
||
/// Error | ||
/// {@nodoc} | ||
final class ChatMessagesState$Error extends ChatMessagesState { | ||
/// {@nodoc} | ||
const ChatMessagesState$Error( | ||
{required super.data, super.message = 'An error has occurred.'}); | ||
} | ||
|
||
/// Pattern matching for [ChatMessagesState]. | ||
typedef ChatMessagesStateMatch<R, S extends ChatMessagesState> = R Function( | ||
S state); | ||
|
||
/// {@nodoc} | ||
@immutable | ||
abstract base class _$ChatMessagesStateBase { | ||
/// {@nodoc} | ||
const _$ChatMessagesStateBase({required this.data, required this.message}); | ||
|
||
/// Data entity payload. | ||
@nonVirtual | ||
final ChatMessagesEntity? data; | ||
|
||
/// Message or state description. | ||
@nonVirtual | ||
final String message; | ||
|
||
/// Has data? | ||
bool get hasData => data != null; | ||
|
||
/// If an error has occurred? | ||
bool get hasError => maybeMap<bool>(orElse: () => false, error: (_) => true); | ||
|
||
/// Is in progress state? | ||
bool get isProcessing => | ||
maybeMap<bool>(orElse: () => false, processing: (_) => true); | ||
|
||
/// Is in idle state? | ||
bool get isIdling => !isProcessing; | ||
|
||
/// Pattern matching for [ChatMessagesState]. | ||
R map<R>({ | ||
required ChatMessagesStateMatch<R, ChatMessagesState$Idle> idle, | ||
required ChatMessagesStateMatch<R, ChatMessagesState$Processing> processing, | ||
required ChatMessagesStateMatch<R, ChatMessagesState$Successful> successful, | ||
required ChatMessagesStateMatch<R, ChatMessagesState$Error> error, | ||
}) => | ||
switch (this) { | ||
ChatMessagesState$Idle s => idle(s), | ||
ChatMessagesState$Processing s => processing(s), | ||
ChatMessagesState$Successful s => successful(s), | ||
ChatMessagesState$Error s => error(s), | ||
_ => throw AssertionError(), | ||
}; | ||
|
||
/// Pattern matching for [ChatMessagesState]. | ||
R maybeMap<R>({ | ||
ChatMessagesStateMatch<R, ChatMessagesState$Idle>? idle, | ||
ChatMessagesStateMatch<R, ChatMessagesState$Processing>? processing, | ||
ChatMessagesStateMatch<R, ChatMessagesState$Successful>? successful, | ||
ChatMessagesStateMatch<R, ChatMessagesState$Error>? error, | ||
required R Function() orElse, | ||
}) => | ||
map<R>( | ||
idle: idle ?? (_) => orElse(), | ||
processing: processing ?? (_) => orElse(), | ||
successful: successful ?? (_) => orElse(), | ||
error: error ?? (_) => orElse(), | ||
); | ||
|
||
/// Pattern matching for [ChatMessagesState]. | ||
R? mapOrNull<R>({ | ||
ChatMessagesStateMatch<R, ChatMessagesState$Idle>? idle, | ||
ChatMessagesStateMatch<R, ChatMessagesState$Processing>? processing, | ||
ChatMessagesStateMatch<R, ChatMessagesState$Successful>? successful, | ||
ChatMessagesStateMatch<R, ChatMessagesState$Error>? error, | ||
}) => | ||
map<R?>( | ||
idle: idle ?? (_) => null, | ||
processing: processing ?? (_) => null, | ||
successful: successful ?? (_) => null, | ||
error: error ?? (_) => null, | ||
); | ||
|
||
@override | ||
int get hashCode => data.hashCode; | ||
|
||
@override | ||
bool operator ==(Object other) => identical(this, other); | ||
|
||
@override | ||
String toString() => 'ChatMessagesState(data: $data, message: $message)'; | ||
} |
Oops, something went wrong.