From 10dc8a69f8195e48f86a0afa02957614c2ec7308 Mon Sep 17 00:00:00 2001 From: tangenta Date: Wed, 19 Jul 2023 21:54:30 +0800 Subject: [PATCH] add chat_room controller/repository --- lib/components/{room.dart => chat_room.dart} | 31 +++- lib/controller/chat_room.dart | 40 ++++ lib/main.dart | 2 +- lib/repository/chat_room.dart | 186 +++++++++++++++++++ 4 files changed, 257 insertions(+), 2 deletions(-) rename lib/components/{room.dart => chat_room.dart} (78%) create mode 100644 lib/controller/chat_room.dart create mode 100644 lib/repository/chat_room.dart diff --git a/lib/components/room.dart b/lib/components/chat_room.dart similarity index 78% rename from lib/components/room.dart rename to lib/components/chat_room.dart index c7096a6..391e72e 100644 --- a/lib/components/room.dart +++ b/lib/components/chat_room.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui'; import 'package:dual_screen/dual_screen.dart'; import 'package:flutter/material.dart'; import 'package:moyubie/components/chat.dart'; @@ -93,6 +92,36 @@ class ListPane extends StatelessWidget { appBar: AppBar( automaticallyImplyLeading: false, title: const Text("Chat Room"), + actions: [ + PopupMenuButton( + padding: const EdgeInsets.only(right: 32), + icon: const Icon(Icons.add), + itemBuilder: (context) { + return [ + const PopupMenuItem( + child: ListTile( + leading: Icon(Icons.add), + title: Align( + alignment: Alignment(-1.2, 0), + child: Text("New Chat Room"), + ), + ), + ), + const PopupMenuItem( + child: ListTile( + // dense: true, + // minLeadingWidth: 0, + leading: Icon(Icons.group_add), + title: Align( + alignment: Alignment(-1.2, 0), + child: Text("Join Chat Room"), + ), + ), + ), + ]; + }, + ) + ], ), body: Scrollbar( controller: _scrollController, diff --git a/lib/controller/chat_room.dart b/lib/controller/chat_room.dart new file mode 100644 index 0000000..efdee0a --- /dev/null +++ b/lib/controller/chat_room.dart @@ -0,0 +1,40 @@ +import 'package:moyubie/repository/chat_room.dart'; +import 'package:moyubie/repository/conversation.dart'; +import 'package:get/get.dart'; + +class ChatRoomController extends GetxController { + final roomList = [].obs; + + final currentChatRoomUuid = "".obs; + + static ChatRoomController get to => Get.find(); + @override + void onInit() async { + roomList.value = await ChatRoomRepository().getChatRooms(); + super.onInit(); + } + + // void setCurrentChatRoomUuid(String uuid) async { + // currentChatRoomUuid.value = uuid; + // update(); + // } + + void deleteChatRoom(int index) async { + ChatRoom chatRoom = roomList[index]; + await ChatRoomRepository().deleteChatRoom(chatRoom.uuid); + roomList.value = await ChatRoomRepository().getChatRooms(); + update(); + } + + void renameChatRoom(ChatRoom chatRoom) async { + await ChatRoomRepository().updateChatRoom(chatRoom); + roomList.value = await ChatRoomRepository().getChatRooms(); + update(); + } + + void addChatRoom(ChatRoom chatRoom) async { + await ChatRoomRepository().addChatRoom(chatRoom); + roomList.value = await ChatRoomRepository().getChatRooms(); + update(); + } +} diff --git a/lib/main.dart b/lib/main.dart index 50d7970..a8e3835 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -17,7 +17,7 @@ import 'package:moyubie/configs/translations.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import 'dart:io' show Platform; -import 'components/room.dart'; +import 'components/chat_room.dart'; void main() async { await GetStorage.init(); diff --git a/lib/repository/chat_room.dart b/lib/repository/chat_room.dart new file mode 100644 index 0000000..bc40989 --- /dev/null +++ b/lib/repository/chat_room.dart @@ -0,0 +1,186 @@ +import 'package:sqflite/sqflite.dart'; +import 'package:path/path.dart'; + +class ChatRoom { + String uuid; + String name; + DateTime createTime; + String connectionToken; + + ChatRoom( + {required this.uuid, + required this.name, + required this.createTime, + required this.connectionToken}); + + Map toMap() { + return { + 'uuid': uuid, + 'name': name, + 'create_time': createTime, + 'connection_token': connectionToken, + }; + } +} + +enum MessageSource { + user, + bot, +} + +class Message { + String uuid; + String userName; + DateTime createTime; + String message; + MessageSource source; + + Message( + {required this.uuid, + required this.userName, + required this.createTime, + required this.message, + required this.source}); + Map toMap() { + return { + 'uuid': uuid, + 'user_name': userName, + 'create_time': createTime, + 'message': message, + 'source': source.name, + }; + } + + @override + String toString() { + return 'Message{uuid: $uuid, userName: $userName, createTime: $createTime, message: $message, source: $source}'; + } +} + +class ChatRoomRepository { + static const String _tableChatRoom = 'chat_room'; + static const String _columnChatRoomUuid = 'uuid'; + static const String _columnChatRoomName = 'name'; + static const String _columnChatRoomCreateTime = 'create_time'; + static const String _columnChatRoomConnectionToken = 'connection_token'; + + static const String _columnMessageUuid = 'uuid'; + static const String _columnMessageUserName = 'user_name'; + static const String _columnMessageCreateTime = 'create_time'; + static const String _columnMessageMessage = 'message'; + static const String _columnMessageSource = 'source'; + + static Database? _database; + static ChatRoomRepository? _instance; + + ChatRoomRepository._internal(); + + factory ChatRoomRepository() { + _instance ??= ChatRoomRepository._internal(); + return _instance!; + } + + Future _getDb() async { + if (_database == null) { + final String path = join(await getDatabasesPath(), 'chatgpt.db'); + _database = await openDatabase(path, version: 1, + onCreate: (Database db, int version) async { + await db.execute(''' + CREATE TABLE $_tableChatRoom ( + $_columnChatRoomUuid VARCHAR(36) PRIMARY KEY, + $_columnChatRoomName TEXT + $_columnChatRoomCreateTime TEXT + $_columnChatRoomConnectionToken TEXT + ) + '''); + }); + } + return _database!; + } + + Future> getChatRooms() async { + final db = await _getDb(); + final List> maps = await db.query(_tableChatRoom); + return List.generate(maps.length, (i) { + return ChatRoom( + uuid: maps[i][_columnChatRoomUuid], + name: maps[i][_columnChatRoomName], + createTime: DateTime.parse(maps[i][_columnChatRoomCreateTime]), + connectionToken: maps[i][_columnChatRoomConnectionToken], + ); + }); + } + + Future addChatRoom(ChatRoom chatRoom) async { + final db = await _getDb(); + await db.insert( + _tableChatRoom, + chatRoom.toMap(), + conflictAlgorithm: ConflictAlgorithm.replace, + ); + await db.execute(''' + CREATE TABLE IF NOT EXISTS $chatRoom.uuid ( + $_columnMessageUuid VARCHAR(36) PRIMARY KEY, + $_columnMessageUserName TEXT + $_columnMessageCreateTime TEXT + $_columnMessageMessage TEXT + $_columnMessageSource TEXT + ) + '''); + } + + Future updateChatRoom(ChatRoom chatRoom) async { + final db = await _getDb(); + await db.update( + _tableChatRoom, + chatRoom.toMap(), + where: '$_columnChatRoomUuid = ?', + whereArgs: [chatRoom.uuid], + ); + } + + Future deleteChatRoom(String uuid) async { + final db = await _getDb(); + await db.transaction((txn) async { + await txn.delete( + _tableChatRoom, + where: '$_columnChatRoomUuid = ?', + whereArgs: [uuid], + ); + }); + await db.execute('DROP TABLE IF EXISTS $uuid'); + } + + Future> getMessagesByChatRoomUUid(String uuid) async { + final db = await _getDb(); + final List> maps = await db.query(uuid); + return List.generate(maps.length, (i) { + return Message( + uuid: maps[i][_columnMessageUuid], + userName: maps[i][_columnMessageUserName], + createTime: DateTime.parse(maps[i][_columnMessageCreateTime]), + message: maps[i][_columnMessageMessage], + source: MessageSource.values + .firstWhere((e) => e.name == maps[i][_columnMessageSource]), + ); + }); + } + + Future addMessage(String chatRoomUuid, Message message) async { + final db = await _getDb(); + await db.insert( + chatRoomUuid, + message.toMap(), + conflictAlgorithm: ConflictAlgorithm.replace, + ); + } + + Future deleteMessage(String chatRoomUuid, String messageUuid) async { + final db = await _getDb(); + await db.delete( + chatRoomUuid, + where: '$_columnMessageUuid = ?', + whereArgs: [messageUuid], + ); + } +}