Skip to content

Commit 6a90a85

Browse files
authored
Merge pull request #4 from talkjs/feature/loading-state
Implemented the onLoadingStateChanged callback
2 parents af5fbf7 + dd4155d commit 6a90a85

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

lib/src/chatbox.dart

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:convert';
2+
import 'dart:async';
23

34
import 'package:flutter/material.dart';
45
import 'package:flutter/services.dart';
@@ -15,6 +16,7 @@ import './predicate.dart';
1516

1617
typedef SendMessageHandler = void Function(SendMessageEvent event);
1718
typedef TranslationToggledHandler = void Function(TranslationToggledEvent event);
19+
typedef LoadingStateHandler = void Function(LoadingState state);
1820

1921
class SendMessageEvent {
2022
final ConversationData conversation;
@@ -36,6 +38,8 @@ class TranslationToggledEvent {
3638
isEnabled = json['isEnabled'];
3739
}
3840

41+
enum LoadingState { loading, loaded }
42+
3943
/// A messaging UI for just a single conversation.
4044
///
4145
/// Create a Chatbox through [Session.createChatbox] and then call [mount] to show it.
@@ -57,6 +61,7 @@ class ChatBox extends StatefulWidget {
5761

5862
final SendMessageHandler? onSendMessage;
5963
final TranslationToggledHandler? onTranslationToggled;
64+
final LoadingStateHandler? onLoadingStateChanged;
6065

6166
const ChatBox({
6267
Key? key,
@@ -73,6 +78,7 @@ class ChatBox extends StatefulWidget {
7378
this.asGuest,
7479
this.onSendMessage,
7580
this.onTranslationToggled,
81+
this.onLoadingStateChanged,
7682
}) : super(key: key);
7783

7884
@override
@@ -121,14 +127,18 @@ class ChatBoxState extends State<ChatBox> {
121127
// If it's the first time that the widget is built, then build everything
122128
_webViewCreated = true;
123129

130+
// Here a Timer is needed, as we can't change the widget's state while the widget
131+
// is being constructed, and the callback may very possibly change the state
132+
Timer.run(() => widget.onLoadingStateChanged?.call(LoadingState.loading));
133+
124134
execute('let chatBox;');
125135

126136
_createSession();
127137
_createChatBox();
128138
// messageFilter and highlightedWords are set as options for the chatbox
129139
_createConversation();
130140

131-
execute('chatBox.mount(document.getElementById("talkjs-container"));');
141+
execute('chatBox.mount(document.getElementById("talkjs-container")).then(() => JSCLoadingState.postMessage("loaded"));');
132142
} else {
133143
// If it's not the first time that the widget is built,
134144
// then check what needs to be rebuilt
@@ -161,6 +171,7 @@ class ChatBoxState extends State<ChatBox> {
161171
javascriptChannels: <JavascriptChannel>{
162172
JavascriptChannel(name: 'JSCSendMessage', onMessageReceived: _jscSendMessage),
163173
JavascriptChannel(name: 'JSCTranslationToggled', onMessageReceived: _jscTranslationToggled),
174+
JavascriptChannel(name: 'JSCLoadingState', onMessageReceived: _jscLoadingState),
164175
});
165176
}
166177

@@ -339,6 +350,14 @@ class ChatBoxState extends State<ChatBox> {
339350
widget.onTranslationToggled?.call(TranslationToggledEvent.fromJson(json.decode(message.message)));
340351
}
341352

353+
void _jscLoadingState(JavascriptMessage message) {
354+
if (kDebugMode) {
355+
print('📗 chatbox._jscLoadingState: ${message.message}');
356+
}
357+
358+
widget.onLoadingStateChanged?.call(LoadingState.loaded);
359+
}
360+
342361
/// For internal use only. Implementation detail that may change anytime.
343362
///
344363
/// Return a string with a unique ID

lib/src/conversationlist.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:convert';
2+
import 'dart:async';
23

34
import 'package:flutter/material.dart';
45
import 'package:flutter/services.dart';
@@ -10,6 +11,7 @@ import './session.dart';
1011
import './conversation.dart';
1112
import './user.dart';
1213
import './predicate.dart';
14+
import './chatbox.dart';
1315

1416
typedef SelectConversationHandler = void Function(SelectConversationEvent event);
1517

@@ -80,6 +82,7 @@ class ConversationList extends StatefulWidget {
8082
final ConversationPredicate feedFilter;
8183

8284
final SelectConversationHandler? onSelectConversation;
85+
final LoadingStateHandler? onLoadingStateChanged;
8386

8487
const ConversationList({
8588
Key? key,
@@ -88,6 +91,7 @@ class ConversationList extends StatefulWidget {
8891
this.theme,
8992
this.feedFilter = const ConversationPredicate(),
9093
this.onSelectConversation,
94+
this.onLoadingStateChanged,
9195
}) : super(key: key);
9296

9397
@override
@@ -121,11 +125,15 @@ class ConversationListState extends State<ConversationList> {
121125
if (!_webViewCreated) {
122126
_webViewCreated = true;
123127

128+
// Here a Timer is needed, as we can't change the widget's state while the widget
129+
// is being constructed, and the callback may very possibly change the state
130+
Timer.run(() => widget.onLoadingStateChanged?.call(LoadingState.loading));
131+
124132
_createSession();
125133
_createConversationList();
126134
// feedFilter is set as an option for the inbox
127135

128-
execute('conversationList.mount(document.getElementById("talkjs-container"));');
136+
execute('conversationList.mount(document.getElementById("talkjs-container")).then(() => JSCLoadingState.postMessage("loaded"));');
129137
} else {
130138
// If it's not the first time that the widget is built,
131139
// then check what needs to be rebuilt
@@ -142,6 +150,7 @@ class ConversationListState extends State<ConversationList> {
142150
onPageFinished: _onPageFinished,
143151
javascriptChannels: <JavascriptChannel>{
144152
JavascriptChannel(name: 'JSCSelectConversation', onMessageReceived: _jscSelectConversation),
153+
JavascriptChannel(name: 'JSCLoadingState', onMessageReceived: _jscLoadingState),
145154
});
146155
}
147156

@@ -243,6 +252,14 @@ class ConversationListState extends State<ConversationList> {
243252
widget.onSelectConversation?.call(SelectConversationEvent.fromJson(json.decode(message.message)));
244253
}
245254

255+
void _jscLoadingState(JavascriptMessage message) {
256+
if (kDebugMode) {
257+
print('📗 conversationlist._jscLoadingState: ${message.message}');
258+
}
259+
260+
widget.onLoadingStateChanged?.call(LoadingState.loaded);
261+
}
262+
246263
/// For internal use only. Implementation detail that may change anytime.
247264
///
248265
/// Return a string with a unique ID

0 commit comments

Comments
 (0)