feat: Implement support chat functionality, add 2FA verification screen and routing, and update dependencies.

This commit is contained in:
pradeepkumar
2026-03-11 13:26:16 +05:30
parent 4780eb9a63
commit 6928697c5c
17 changed files with 1660 additions and 20 deletions

View File

@@ -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);
});