Skip to content

Commit af08f7b

Browse files
Add sharing text (chat)
Signed-off-by: huynguyennovem <huynguyennovem@gmail.com>
1 parent 859d108 commit af08f7b

25 files changed

Lines changed: 862 additions & 186 deletions

lib/config/constants.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const mNavigationPath = 'navigation';
88
const mClientPath = 'client';
99
const mServerPath = 'server';
1010
const mSendPath = 'send';
11-
const mReceivePath = 'receive';
11+
const mChatPath = 'chat';
1212
const mUploadingPath = 'uploading';
1313
const mScanningPath = 'scanning';
1414
const mManualConnectPath = 'manual_connect';

lib/di/di.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:netshare/service/download_service.dart';
55
import 'package:netshare/data/global_scope_data.dart';
66
import 'package:netshare/data/hivedb/clients/shared_file_client.dart';
77
import 'package:netshare/data/pref_data.dart';
8+
import 'package:netshare/service/message_manage_service.dart';
89

910
final getIt = GetIt.instance;
1011

@@ -13,6 +14,7 @@ void setupDI() {
1314
getIt.registerSingleton<ApiService>(ApiService());
1415
getIt.registerSingleton<PrefData>(PrefData());
1516
getIt.registerSingleton<DownloadService>(DownloadService());
17+
getIt.registerSingleton<MessageManagerService>(MessageManagerService());
1618

1719
// hive clients
1820
getIt.registerSingleton<SharedFileClient>(SharedFileClient());

lib/entity/api_response.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'package:equatable/equatable.dart';
2+
3+
class ApiResponse extends Equatable {
4+
final String? message;
5+
final int? code;
6+
7+
const ApiResponse({required this.message, required this.code});
8+
9+
const ApiResponse.success() : this(message: 'Success', code: 200);
10+
11+
const ApiResponse.fail() : this(message: 'Fail', code: 400);
12+
13+
factory ApiResponse.fromJson(dynamic json) =>
14+
ApiResponse(message: json['message'], code: json['code']);
15+
16+
Map<String, dynamic> toJson() {
17+
final map = <String, dynamic>{};
18+
map['message'] = message;
19+
map['code'] = code;
20+
return map;
21+
}
22+
23+
@override
24+
List<Object?> get props => [message, code];
25+
}

lib/entity/message.dart

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:netshare/entity/message_role.dart';
3+
import 'package:netshare/entity/message_state.dart';
4+
import 'package:netshare/util/extension.dart';
5+
6+
class Message extends Equatable {
7+
final String text;
8+
final String receiver;
9+
final String sender;
10+
final DateTime createdTime;
11+
final MessageState messageState;
12+
final MessageRole messageRole;
13+
final bool? isDeleted;
14+
15+
const Message({
16+
required this.text,
17+
required this.receiver,
18+
required this.sender,
19+
required this.createdTime,
20+
required this.messageState,
21+
required this.messageRole,
22+
this.isDeleted = false,
23+
});
24+
25+
Message copyWith({
26+
String? text,
27+
bool? isDeleted,
28+
MessageState? messageState,
29+
MessageRole? messageRole,
30+
}) =>
31+
Message(
32+
text: text ?? this.text,
33+
createdTime: createdTime,
34+
receiver: receiver,
35+
sender: sender,
36+
messageState: messageState ?? this.messageState,
37+
messageRole: messageRole ?? this.messageRole,
38+
isDeleted: isDeleted ?? this.isDeleted,
39+
);
40+
41+
factory Message.fromJson(dynamic json) => Message(
42+
text: json['text'],
43+
createdTime: DateTime.parse(json['createdTime']),
44+
receiver: json['receiver'],
45+
sender: json['sender'],
46+
messageState: MessageStateExtension.fromString(json['messageState']),
47+
messageRole: MessageRoleExtension.fromString(json['messageRole']),
48+
isDeleted: json['isDeleted'],
49+
);
50+
51+
Map<String, dynamic> toJson() {
52+
final map = <String, dynamic>{};
53+
map['text'] = text;
54+
map['receiver'] = receiver;
55+
map['sender'] = sender;
56+
map['createdTime'] = createdTime.toIso8601String();
57+
map['messageState'] = messageState.value;
58+
map['messageRole'] = messageRole.value;
59+
map['isDeleted'] = isDeleted;
60+
return map;
61+
}
62+
63+
@override
64+
bool operator ==(Object other) =>
65+
identical(this, other) ||
66+
super == other &&
67+
other is Message &&
68+
runtimeType == other.runtimeType &&
69+
text == other.text &&
70+
createdTime == other.createdTime;
71+
72+
@override
73+
int get hashCode => super.hashCode ^ text.hashCode ^ createdTime.hashCode;
74+
75+
@override
76+
List<Object?> get props => [text, createdTime];
77+
78+
@override
79+
String toString() {
80+
return 'Message{text: $text, receiver: $receiver, sender: $sender, createdTime: $createdTime, messageState: $messageState, messageRole: $messageRole, isDeleted: $isDeleted}';
81+
}
82+
}

lib/entity/message_role.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
enum MessageRole {
2+
client,
3+
server,
4+
}

lib/entity/message_state.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
enum MessageState {
2+
sending,
3+
sent,
4+
error,
5+
}

lib/main.dart

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@ import 'package:netshare/ui/common_view/confirm_dialog.dart';
66
import 'package:provider/provider.dart';
77

88
import 'package:netshare/config/styles.dart';
9+
import 'package:netshare/data/preload_data.dart';
910
import 'package:netshare/di/di.dart';
1011
import 'package:netshare/plugin_management/plugins.dart';
12+
import 'package:netshare/provider/app_provider.dart';
13+
import 'package:netshare/provider/chat_provider.dart';
1114
import 'package:netshare/provider/connection_provider.dart';
12-
import 'package:netshare/provider/db_provider.dart';
1315
import 'package:netshare/provider/file_provider.dart';
16+
import 'package:netshare/ui/chat/chat_widget.dart';
1417
import 'package:netshare/ui/client/scan_qr_widget.dart';
15-
import 'package:netshare/ui/navigation_widget.dart';
1618
import 'package:netshare/ui/client/client_widget.dart';
17-
import 'package:netshare/ui/receive/receive_widget.dart';
1819
import 'package:netshare/ui/send/send_widget.dart';
1920
import 'package:netshare/ui/server/server_widget.dart';
2021
import 'package:netshare/util/utility_functions.dart';
@@ -57,11 +58,6 @@ class _MyAppState extends State<MyApp> {
5758
}
5859
},
5960
),
60-
GoRoute(
61-
name: mNavigationPath,
62-
path: '/$mNavigationPath',
63-
builder: (context, state) => const NavigationWidget(),
64-
),
6561
GoRoute(
6662
name: mServerPath,
6763
path: '/$mServerPath',
@@ -71,32 +67,30 @@ class _MyAppState extends State<MyApp> {
7167
name: mClientPath,
7268
path: '/$mClientPath',
7369
builder: (context, state) => const ClientWidget(),
74-
routes: [
75-
GoRoute(
76-
name: mSendPath,
77-
path: mSendPath,
78-
builder: (BuildContext context, GoRouterState state) =>
79-
const SendWidget(),
80-
routes: [
81-
GoRoute(
82-
name: mUploadingPath,
83-
path: mUploadingPath,
84-
builder: (context, state) => const UploadingWidget(),
85-
)
86-
],
87-
),
88-
GoRoute(
89-
name: mReceivePath,
90-
path: mReceivePath,
91-
builder: (BuildContext context, GoRouterState state) => const ReceiveWidget(),
92-
),
93-
GoRoute(
94-
name: mScanningPath,
95-
path: mScanningPath,
96-
builder: (BuildContext context, GoRouterState state) =>
97-
const ScanQRWidget(),
98-
),
99-
],
70+
routes: [
71+
GoRoute(
72+
name: mSendPath,
73+
path: mSendPath,
74+
builder: (BuildContext context, GoRouterState state) => const SendWidget(),
75+
routes: [
76+
GoRoute(
77+
name: mUploadingPath,
78+
path: mUploadingPath,
79+
builder: (context, state) => const UploadingWidget(),
80+
)
81+
],
82+
),
83+
GoRoute(
84+
name: mChatPath,
85+
path: mChatPath,
86+
builder: (BuildContext context, GoRouterState state) => const ChatWidget(),
87+
),
88+
GoRoute(
89+
name: mScanningPath,
90+
path: mScanningPath,
91+
builder: (BuildContext context, GoRouterState state) => const ScanQRWidget(),
92+
),
93+
],
10094
),
10195
],
10296
);
@@ -107,17 +101,17 @@ class _MyAppState extends State<MyApp> {
107101
return MultiProvider(
108102
providers: [
109103
ChangeNotifierProvider(create: (context) => FileProvider()),
110-
ChangeNotifierProvider(create: (context) => DatabaseProvider()),
111104
ChangeNotifierProvider(create: (context) => ConnectionProvider()),
105+
ChangeNotifierProvider(create: (context) => ChatProvider()),
106+
ChangeNotifierProvider(create: (context) => AppProvider()),
112107
],
113108
child: MaterialApp.router(
114109
debugShowCheckedModeBanner: false,
115110
title: 'NetShare',
116111
theme: ThemeData(
117112
useMaterial3: true,
118113
appBarTheme: const AppBarTheme(color: backgroundColor),
119-
colorScheme: ColorScheme.fromSeed(
120-
seedColor: seedColor, background: backgroundColor),
114+
colorScheme: ColorScheme.fromSeed(seedColor: seedColor, background: backgroundColor),
121115
iconButtonTheme: const IconButtonThemeData(
122116
style: ButtonStyle(
123117
iconColor: MaterialStatePropertyAll<Color>(textIconButtonColor),

lib/provider/app_provider.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'package:flutter/widgets.dart';
2+
import 'package:netshare/entity/function_mode.dart';
3+
4+
class AppProvider extends ChangeNotifier {
5+
FunctionMode _appMode = FunctionMode.none;
6+
FunctionMode get appMode => _appMode;
7+
8+
void updateAppMode({required FunctionMode appMode}) {
9+
_appMode = appMode;
10+
notifyListeners();
11+
}
12+
}

lib/provider/chat_provider.dart

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:netshare/entity/message.dart';
3+
import 'package:netshare/entity/message_state.dart';
4+
5+
class ChatProvider extends ChangeNotifier {
6+
final List<Message> _messages = [];
7+
List<Message> get messages => _messages;
8+
9+
10+
void addMessage({required Message message}) {
11+
_messages.add(message);
12+
notifyListeners();
13+
}
14+
15+
void addAllMessages({required Set<Message> messages, bool isAppending = false}) {
16+
if(!isAppending) {
17+
_messages.clear();
18+
}
19+
_messages.addAll(messages);
20+
notifyListeners();
21+
}
22+
23+
void clearAllMessages() {
24+
_messages.clear();
25+
notifyListeners();
26+
}
27+
28+
void updateMessage({
29+
required Message sourceMessage,
30+
String? newText,
31+
bool? isDeleted,
32+
MessageState? messageState,
33+
}) {
34+
if(_messages.isEmpty) return;
35+
Message? oldMessage;
36+
try {
37+
oldMessage = _messages.firstWhere((message) => message == sourceMessage);
38+
} catch (e) {
39+
oldMessage == null;
40+
}
41+
if(oldMessage == null) return;
42+
final oldIndex = _messages.indexOf(oldMessage);
43+
final updatedMessage = oldMessage.copyWith(
44+
text: newText,
45+
isDeleted: isDeleted,
46+
messageState: messageState,
47+
);
48+
_messages[oldIndex] = updatedMessage;
49+
notifyListeners();
50+
}
51+
}

lib/provider/db_provider.dart

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)