feat: Implement support chat functionality, add 2FA verification screen and routing, and update dependencies.
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:real_estate_mobile/features/support_chat/data/models/support_chat_models.dart';
|
||||
import 'package:real_estate_mobile/features/support_chat/data/support_chat_repository.dart';
|
||||
|
||||
class SupportChatState {
|
||||
final SupportChat? chat;
|
||||
final List<SupportMessage> messages;
|
||||
final bool isLoading;
|
||||
final bool isSending;
|
||||
final bool isLoadingMore;
|
||||
final bool hasMore;
|
||||
final int currentPage;
|
||||
final bool isTyping;
|
||||
final String? error;
|
||||
|
||||
const SupportChatState({
|
||||
this.chat,
|
||||
this.messages = const [],
|
||||
this.isLoading = true,
|
||||
this.isSending = false,
|
||||
this.isLoadingMore = false,
|
||||
this.hasMore = false,
|
||||
this.currentPage = 1,
|
||||
this.isTyping = false,
|
||||
this.error,
|
||||
});
|
||||
|
||||
SupportChatState copyWith({
|
||||
SupportChat? chat,
|
||||
List<SupportMessage>? messages,
|
||||
bool? isLoading,
|
||||
bool? isSending,
|
||||
bool? isLoadingMore,
|
||||
bool? hasMore,
|
||||
int? currentPage,
|
||||
bool? isTyping,
|
||||
String? error,
|
||||
}) {
|
||||
return SupportChatState(
|
||||
chat: chat ?? this.chat,
|
||||
messages: messages ?? this.messages,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
isSending: isSending ?? this.isSending,
|
||||
isLoadingMore: isLoadingMore ?? this.isLoadingMore,
|
||||
hasMore: hasMore ?? this.hasMore,
|
||||
currentPage: currentPage ?? this.currentPage,
|
||||
isTyping: isTyping ?? this.isTyping,
|
||||
error: error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SupportChatNotifier extends StateNotifier<SupportChatState> {
|
||||
final SupportChatRepository _repo;
|
||||
|
||||
SupportChatNotifier(this._repo) : super(const SupportChatState());
|
||||
|
||||
Future<void> initChat() async {
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
try {
|
||||
final chat = await _repo.getOrCreateChat();
|
||||
final result = await _repo.getMessages(chat.id);
|
||||
await _repo.markAsRead(chat.id);
|
||||
|
||||
state = state.copyWith(
|
||||
chat: chat,
|
||||
messages: result.messages,
|
||||
hasMore: result.pagination.hasMore,
|
||||
currentPage: result.pagination.page,
|
||||
isLoading: false,
|
||||
);
|
||||
} catch (e) {
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
error: 'Failed to load support chat. Please try again.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> sendMessage(String content) async {
|
||||
final chat = state.chat;
|
||||
if (chat == null || content.trim().isEmpty) return;
|
||||
|
||||
state = state.copyWith(isSending: true);
|
||||
try {
|
||||
final message = await _repo.sendMessage(chat.id, content.trim());
|
||||
state = state.copyWith(
|
||||
messages: [...state.messages, message],
|
||||
isSending: false,
|
||||
);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isSending: false);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> loadMore() async {
|
||||
final chat = state.chat;
|
||||
if (chat == null || !state.hasMore || state.isLoadingMore) return;
|
||||
|
||||
state = state.copyWith(isLoadingMore: true);
|
||||
try {
|
||||
final nextPage = state.currentPage + 1;
|
||||
final result = await _repo.getMessages(chat.id, page: nextPage);
|
||||
state = state.copyWith(
|
||||
messages: [...result.messages, ...state.messages],
|
||||
currentPage: nextPage,
|
||||
hasMore: result.pagination.hasMore,
|
||||
isLoadingMore: false,
|
||||
);
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoadingMore: false);
|
||||
}
|
||||
}
|
||||
|
||||
void addIncomingMessage(SupportMessage message) {
|
||||
if (state.chat == null || message.chatId != state.chat!.id) return;
|
||||
if (state.messages.any((m) => m.id == message.id)) return;
|
||||
|
||||
state = state.copyWith(messages: [...state.messages, message]);
|
||||
_repo.markAsRead(state.chat!.id);
|
||||
}
|
||||
|
||||
void setTyping(bool typing) {
|
||||
state = state.copyWith(isTyping: typing);
|
||||
}
|
||||
}
|
||||
|
||||
final supportChatProvider =
|
||||
StateNotifierProvider<SupportChatNotifier, SupportChatState>((ref) {
|
||||
final repo = ref.watch(supportChatRepositoryProvider);
|
||||
return SupportChatNotifier(repo);
|
||||
});
|
||||
Reference in New Issue
Block a user