✨ Chat, chat local db, chat messaging retriving (no sync yet)
This commit is contained in:
@ -1,100 +1,32 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/database/drift_db.dart';
|
||||
import 'package:island/database/message.dart';
|
||||
import 'package:island/database/message_repository.dart';
|
||||
import 'package:island/models/chat.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
import 'package:island/widgets/alert.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
// Global database instance
|
||||
final databaseProvider = Provider<AppDatabase>((ref) {
|
||||
final db = AppDatabase();
|
||||
ref.onDispose(() => db.close());
|
||||
return db;
|
||||
});
|
||||
|
||||
final messageRepositoryProvider =
|
||||
FutureProvider.family<MessageRepository, SnChat>((ref, chat) async {
|
||||
final apiClient = ref.watch(apiClientProvider);
|
||||
final database = ref.watch(databaseProvider);
|
||||
return MessageRepository(chat, apiClient, database);
|
||||
});
|
||||
Future<void> resetDatabase(WidgetRef ref) async {
|
||||
if (kIsWeb) return;
|
||||
|
||||
final chatMessagesProvider =
|
||||
FutureProvider.family<List<LocalChatMessage>, SnChat>((ref, room) async {
|
||||
final repository = await ref.watch(
|
||||
messageRepositoryProvider(room).future,
|
||||
);
|
||||
return repository.listMessages();
|
||||
});
|
||||
final db = ref.read(databaseProvider);
|
||||
final basepath = await getApplicationSupportDirectory();
|
||||
final file = File(join(basepath.path, 'solar_network_data.sqlite'));
|
||||
|
||||
class ChatMessageNotifier
|
||||
extends StateNotifier<AsyncValue<List<LocalChatMessage>>> {
|
||||
final MessageRepository _repository;
|
||||
final int roomId;
|
||||
int _currentOffset = 0;
|
||||
final int _pageSize = 20;
|
||||
bool _hasMore = true;
|
||||
// Close current database connection
|
||||
db.close();
|
||||
|
||||
ChatMessageNotifier(this._repository, this.roomId)
|
||||
: super(const AsyncValue.loading()) {
|
||||
loadInitial();
|
||||
// Delete database file
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
}
|
||||
|
||||
Future<void> loadInitial() async {
|
||||
state = const AsyncValue.loading();
|
||||
try {
|
||||
final messages = await _repository.listMessages(
|
||||
offset: 0,
|
||||
take: _pageSize,
|
||||
);
|
||||
_currentOffset = messages.length;
|
||||
_hasMore = messages.length >= _pageSize;
|
||||
state = AsyncValue.data(messages);
|
||||
} catch (e, stack) {
|
||||
state = AsyncValue.error(e, stack);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> loadMore() async {
|
||||
if (!_hasMore) return;
|
||||
|
||||
try {
|
||||
final newMessages = await _repository.listMessages(
|
||||
offset: _currentOffset,
|
||||
take: _pageSize,
|
||||
);
|
||||
|
||||
if (newMessages.isEmpty) {
|
||||
_hasMore = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_currentOffset += newMessages.length;
|
||||
_hasMore = newMessages.length >= _pageSize;
|
||||
|
||||
state = AsyncValue.data([...state.value ?? [], ...newMessages]);
|
||||
} catch (err) {
|
||||
showErrorAlert(err);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> sendMessage(String content) async {
|
||||
try {
|
||||
final message = await _repository.sendMessage(roomId, content);
|
||||
|
||||
final currentMessages = state.value ?? [];
|
||||
state = AsyncValue.data([message, ...currentMessages]);
|
||||
} catch (err) {
|
||||
showErrorAlert(err);
|
||||
}
|
||||
}
|
||||
|
||||
bool get hasMore => _hasMore;
|
||||
// Force refresh the database provider
|
||||
ref.invalidate(databaseProvider);
|
||||
}
|
||||
|
||||
final chatMessageNotifierProvider = StateNotifierProvider.family<
|
||||
ChatMessageNotifier,
|
||||
AsyncValue<List<LocalChatMessage>>,
|
||||
MessageRepository
|
||||
>((ref, repository) => ChatMessageNotifier(repository, repository.room.id));
|
||||
|
@ -21,7 +21,6 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
||||
final user = SnAccount.fromJson(response.data);
|
||||
state = AsyncValue.data(user);
|
||||
} catch (error, stackTrace) {
|
||||
print('Failed to fetch user: $error');
|
||||
state = AsyncValue.error(error, stackTrace);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user