mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-26 06:49:22 +00:00
Use Websocket to update number of unread notifications
This commit is contained in:
parent
36f89a9a53
commit
1b13a90615
@ -9,6 +9,13 @@ import 'package:event_bus/event_bus.dart';
|
|||||||
/// Main WebSocket closed
|
/// Main WebSocket closed
|
||||||
class WSClosedEvent {}
|
class WSClosedEvent {}
|
||||||
|
|
||||||
|
/// New number of notifications
|
||||||
|
class NewNumberNotifsEvent {
|
||||||
|
final int newNum;
|
||||||
|
|
||||||
|
NewNumberNotifsEvent(this.newNum);
|
||||||
|
}
|
||||||
|
|
||||||
class EventsHelper {
|
class EventsHelper {
|
||||||
static EventBus _mgr = EventBus();
|
static EventBus _mgr = EventBus();
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:comunic/helpers/events_helper.dart';
|
import 'package:comunic/helpers/events_helper.dart';
|
||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
import 'package:comunic/models/config.dart';
|
import 'package:comunic/models/config.dart';
|
||||||
|
import 'package:comunic/models/ws_message.dart';
|
||||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
|
|
||||||
/// User web socket helper
|
/// User web socket helper
|
||||||
@ -40,7 +43,10 @@ class WebSocketHelper {
|
|||||||
|
|
||||||
_ws.stream.listen(
|
_ws.stream.listen(
|
||||||
// When we got data
|
// When we got data
|
||||||
(onData) => print("WS New data: $onData"),
|
(data) {
|
||||||
|
print("WS New data: $data");
|
||||||
|
_processMessage(data.toString());
|
||||||
|
},
|
||||||
|
|
||||||
// Print errors on console
|
// Print errors on console
|
||||||
onError: (e, stack) {
|
onError: (e, stack) {
|
||||||
@ -55,4 +61,31 @@ class WebSocketHelper {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Process incoming message
|
||||||
|
static _processMessage(String msgStr) {
|
||||||
|
try {
|
||||||
|
final msg = WsMessage.fromJSON(jsonDecode(msgStr));
|
||||||
|
|
||||||
|
if (!msg.hasId)
|
||||||
|
_processUnattendedMessage(msg);
|
||||||
|
else
|
||||||
|
throw Exception("Do not know how to process attended message!");
|
||||||
|
} catch (e, stack) {
|
||||||
|
print("WS could not process message: $e");
|
||||||
|
print(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Process an unattended message
|
||||||
|
static _processUnattendedMessage(WsMessage msg) {
|
||||||
|
switch (msg.title) {
|
||||||
|
case "number_notifs":
|
||||||
|
EventsHelper.emit(NewNumberNotifsEvent(msg.data));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw Exception("Unknown message type: ${msg.title}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
class CountUnreadNotifications {
|
class CountUnreadNotifications {
|
||||||
final int notifications;
|
int notifications;
|
||||||
final int conversations;
|
int conversations;
|
||||||
|
|
||||||
CountUnreadNotifications({
|
CountUnreadNotifications({
|
||||||
this.notifications,
|
this.notifications,
|
||||||
|
25
lib/models/ws_message.dart
Normal file
25
lib/models/ws_message.dart
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
/// WebSocket message
|
||||||
|
///
|
||||||
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
|
class WsMessage {
|
||||||
|
final String id;
|
||||||
|
final String title;
|
||||||
|
final dynamic data;
|
||||||
|
|
||||||
|
const WsMessage({
|
||||||
|
@required this.id,
|
||||||
|
@required this.title,
|
||||||
|
@required this.data,
|
||||||
|
}) : assert(id != null),
|
||||||
|
assert(title != null);
|
||||||
|
|
||||||
|
/// Construct a message from a JSON document (messages coming from the server)
|
||||||
|
static WsMessage fromJSON(final Map<dynamic, dynamic> m) {
|
||||||
|
return WsMessage(id: m["id"], title: m["title"], data: m["data"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get hasId => this.id != null && this.id.isNotEmpty;
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:comunic/helpers/events_helper.dart';
|
||||||
import 'package:comunic/helpers/notifications_helper.dart';
|
import 'package:comunic/helpers/notifications_helper.dart';
|
||||||
import 'package:comunic/models/count_unread_notifications.dart';
|
import 'package:comunic/models/count_unread_notifications.dart';
|
||||||
import 'package:comunic/ui/widgets/safe_state.dart';
|
import 'package:comunic/ui/widgets/safe_state.dart';
|
||||||
@ -113,8 +114,7 @@ class ComunicAppBar extends StatefulWidget implements PreferredSizeWidget {
|
|||||||
final OnSelectMenuAction onTap;
|
final OnSelectMenuAction onTap;
|
||||||
final BarCallbackActions selectedAction;
|
final BarCallbackActions selectedAction;
|
||||||
|
|
||||||
const ComunicAppBar(
|
const ComunicAppBar({Key key, @required this.onTap, @required this.selectedAction})
|
||||||
{Key key, @required this.onTap, @required this.selectedAction})
|
|
||||||
: assert(onTap != null),
|
: assert(onTap != null),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
@ -126,12 +126,17 @@ class ComunicAppBar extends StatefulWidget implements PreferredSizeWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ComunicAppBarState extends SafeState<ComunicAppBar> {
|
class _ComunicAppBarState extends SafeState<ComunicAppBar> {
|
||||||
CountUnreadNotifications _unreadNotifications;
|
var _unreadNotifications =
|
||||||
|
CountUnreadNotifications(notifications: 0, conversations: 0);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_refreshCountUnread();
|
_refreshCountUnread();
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
|
// Listen to notifications number update
|
||||||
|
this.listenChangeState<NewNumberNotifsEvent>(
|
||||||
|
(d) => _unreadNotifications.notifications = d.newNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _refreshCountUnread() async {
|
void _refreshCountUnread() async {
|
||||||
|
@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
|
|||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
abstract class SafeState<T extends StatefulWidget> extends State<T> {
|
abstract class SafeState<T extends StatefulWidget> extends State<T> {
|
||||||
|
|
||||||
final _subscriptions = List<StreamSubscription>();
|
final _subscriptions = List<StreamSubscription>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -21,8 +20,7 @@ abstract class SafeState<T extends StatefulWidget> extends State<T> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void setState(fn) {
|
void setState(fn) {
|
||||||
if(mounted)
|
if (mounted) super.setState(fn);
|
||||||
super.setState(fn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register to a new subscription
|
/// Register to a new subscription
|
||||||
@ -30,4 +28,14 @@ abstract class SafeState<T extends StatefulWidget> extends State<T> {
|
|||||||
void listen<T>(void onEvent(T event)) {
|
void listen<T>(void onEvent(T event)) {
|
||||||
_subscriptions.add(EventsHelper.on<T>(onEvent));
|
_subscriptions.add(EventsHelper.on<T>(onEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Register to a new subscription
|
||||||
|
///
|
||||||
|
/// Callback will we called inside of setState
|
||||||
|
@protected
|
||||||
|
void listenChangeState<T>(void onEvent(T event)) {
|
||||||
|
_subscriptions.add(EventsHelper.on<T>((d) {
|
||||||
|
setState(() => onEvent(d));
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user