Browse Source

show notification when onMessage foreground

master
daivph 5 years ago
parent
commit
4938cbd635
8 changed files with 89 additions and 202 deletions
  1. +1
    -1
      ios/Flutter/.last_build_id
  2. +1
    -1
      lib/presentation/screens/notification/bloc/noti_event.dart
  3. +1
    -1
      lib/presentation/screens/notification/bloc/noti_state.dart
  4. +23
    -90
      lib/presentation/screens/notification/sc_notification.dart
  5. +1
    -0
      lib/presentation/screens/notification/update_count_noti_bloc.dart
  6. +0
    -100
      lib/presentation/screens/plot/sc_plot.dart
  7. +32
    -9
      lib/presentation/screens/tabbar/tabbar.dart
  8. +30
    -0
      lib/utils/NotificationsBloc.dart

+ 1
- 1
ios/Flutter/.last_build_id View File

@@ -1 +1 @@
af5bc8188bfe648f3bf82e3093eb6f6d
d91c957b2422e26116533c8dae89710a

+ 1
- 1
lib/presentation/screens/notification/bloc/noti_event.dart View File

@@ -1,6 +1,6 @@
part of 'noti_bloc.dart';

abstract class NotiEvent extends Equatable {
abstract class NotiEvent {
const NotiEvent();

@override

+ 1
- 1
lib/presentation/screens/notification/bloc/noti_state.dart View File

@@ -1,6 +1,6 @@
part of 'noti_bloc.dart';

abstract class NotiState extends Equatable {
abstract class NotiState {
const NotiState();

@override

+ 23
- 90
lib/presentation/screens/notification/sc_notification.dart View File

@@ -1,16 +1,13 @@
import 'package:farm_tpf/custom_model/NotificationDTO.dart';
import 'package:farm_tpf/data/repository/repository.dart';
import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart';
import 'package:farm_tpf/presentation/custom_widgets/dash_line_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
import 'package:farm_tpf/presentation/screens/notification/update_count_noti_bloc.dart';
import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_information.dart';
import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_parameter.dart';
import 'package:farm_tpf/utils/NotificationsBloc.dart';
import 'package:farm_tpf/utils/const_icons.dart';
import 'package:farm_tpf/utils/pref.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:farm_tpf/utils/formatter.dart';
@@ -24,66 +21,8 @@ class NotificationScreen extends StatefulWidget {
}

class _NotificationScreenState extends State<NotificationScreen> {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
var notiBloc = NotiBloc(repository: Repository());

@override
void initState() {
super.initState();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
try {
notiBloc.add(OnRefreshFromNotification());
updateCountNotiBloc.getNotifications((data) {}, (err) {});
} catch (e) {
print(e);
}
});
}

@override
Widget build(BuildContext context) {
return BlocBuilder(
cubit: notiBloc,
builder: (context, state) {
return HoldInfinityWidget(
notiBloc: notiBloc,
);
});
}
}

class HoldInfinityWidget extends StatelessWidget {
final NotiBloc notiBloc;
HoldInfinityWidget({@required this.notiBloc});
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
body: BlocBuilder<NotiBloc, NotiState>(
cubit: notiBloc,
builder: (context, state) {
return SafeArea(
child: InfinityView(
notiBloc: notiBloc,
),
);
},
));
}
}

class InfinityView extends StatefulWidget {
final NotiBloc notiBloc;
InfinityView({@required this.notiBloc});
@override
_InfinityViewState createState() => _InfinityViewState();
}

class _InfinityViewState extends State<InfinityView> {
final _scrollController = ScrollController();
final _scrollThreshold = 250.0;
List<NotificationDTO> currentItems = new List<NotificationDTO>();
@@ -91,6 +30,7 @@ class _InfinityViewState extends State<InfinityView> {
int currentPage = 0;
bool currentHasReachedMax = true;
bool isUpdatingFromApi = true;
Stream<LocalNotification> _notificationsStream;

var pref = LocalPref();
var token;
@@ -99,7 +39,7 @@ class _InfinityViewState extends State<InfinityView> {
final maxScroll = _scrollController.position.maxScrollExtent;
final currentScroll = _scrollController.position.pixels;
if (maxScroll - currentScroll < _scrollThreshold) {
widget.notiBloc.add(DataFetched());
notiBloc.add(DataFetched());
}
});
token = await pref.getString(DATA_CONST.TOKEN_KEY);
@@ -108,14 +48,20 @@ class _InfinityViewState extends State<InfinityView> {
@override
void initState() {
getSharedPrefs();
widget.notiBloc.add(DataFetched());
notiBloc.add(DataFetched());
_notificationsStream = NotificationsBloc.instance.notificationsStream;
_notificationsStream.listen((notification) {
updateCountNotiBloc.getNotifications((data) {}, (err) {});
print('Notification: $notification');
notiBloc.add(OnRefresh());
});
super.initState();
}

@override
Widget build(BuildContext context) {
return BlocBuilder<NotiBloc, NotiState>(
cubit: widget.notiBloc,
cubit: notiBloc,
builder: (context, state) {
if (state is NotiFailure) {
return Center(child: Text(state.errorString));
@@ -160,29 +106,16 @@ class _InfinityViewState extends State<InfinityView> {
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 22),
)),
BlocBuilder<NotiBloc, NotiState>(
cubit: widget.notiBloc,
builder: (context, state) {
if (state is NotiSuccess) {
if (state.items.length > 0) {
return FlatButton(
onPressed: () {
widget.notiBloc.add(
MarkAllNotificationUpdate(status: "1"));
},
child: Text('Đánh dấu đã đọc tất cả',
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 14,
color: Colors.blue)));
} else {
return SizedBox();
}
} else {
return SizedBox();
}
},
)
FlatButton(
onPressed: () {
notiBloc
.add(MarkAllNotificationUpdate(status: "1"));
},
child: Text('Đánh dấu đã đọc tất cả',
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 14,
color: Colors.blue)))
],
)),
Expanded(
@@ -193,7 +126,7 @@ class _InfinityViewState extends State<InfinityView> {
return index >= state.items.length
? BottomLoader()
: ItemInfinityWidget(
notiBloc: widget.notiBloc,
notiBloc: notiBloc,
unread: state.unread,
read: state.read,
currentItems: currentItems,
@@ -208,7 +141,7 @@ class _InfinityViewState extends State<InfinityView> {
controller: _scrollController,
),
onRefresh: () async {
widget.notiBloc.add(OnRefresh());
notiBloc.add(OnRefresh());
}))
],
);

+ 1
- 0
lib/presentation/screens/notification/update_count_noti_bloc.dart View File

@@ -11,6 +11,7 @@ class UpdateCountNotiBloc {
void getNotifications(Function(NotificationObjectDTO) onSuccess,
Function(String) onError) async {
_repository.getNotifications().then((value) {
print('get noti ok ${value.numberUnreadTotal}');
onSuccess(value);
_notiFetcher.sink.add(value);
}).catchError((onError) {

+ 0
- 100
lib/presentation/screens/plot/sc_plot.dart View File

@@ -1,10 +1,4 @@
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:farm_tpf/custom_model/NotificationDTO.dart';
import 'package:farm_tpf/data/repository/repository.dart';
import 'package:farm_tpf/data/repository/user_repository.dart';
import 'package:farm_tpf/main.dart';
import 'package:farm_tpf/models/index.dart';
import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart';
import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
@@ -12,14 +6,11 @@ import 'package:farm_tpf/presentation/screens/plot/widget_search.dart';
import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
import 'package:farm_tpf/utils/const_assets.dart';
import 'package:farm_tpf/utils/const_color.dart';
import 'package:farm_tpf/utils/const_common.dart';
import 'package:farm_tpf/utils/pref.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:farm_tpf/utils/const_string.dart';
import 'package:farm_tpf/utils/formatter.dart';
import 'package:get/get.dart';

import 'bloc/plot_bloc.dart';

@@ -29,106 +20,15 @@ class PlotListScreen extends StatefulWidget {
}

class _PlotListScreenState extends State<PlotListScreen> {
UserRepository _userRepository = UserRepository();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
var pref = LocalPref();
var token;
var client;
String pushkey = "";
String currentFullName = "";

Future<Null> getSharedPrefs() async {
token = await pref.getString(DATA_CONST.TOKEN_KEY);
pushkey = await pref.getString(DATA_CONST.PUSH_KEY);
currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
var options = BaseOptions(baseUrl: ConstCommon.baseUrl);
options.headers["Authorization"] = "Bearer $token";
client = Dio(options);
if (Platform.isIOS) {
_firebaseMessaging
.requestNotificationPermissions(IosNotificationSettings());
}
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage---: $message");
},
onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
Future.delayed(Duration(milliseconds: 500), () {
_notificationNavigateOnFCM(message);
});
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
_notificationNavigateOnFCM(message);
},
);
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(
sound: true, badge: true, alert: true, provisional: true));
_firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) {
print("Settings registered: $settings");
});
if (pushkey?.isEmpty ?? true) {
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
print("Push Messaging token: $token");
_userRepository.updateFcmToken(token).then((value) {
print("send push key successful");
pref.saveString(DATA_CONST.PUSH_KEY, token);
});
// client.put("");
});
} else {
print("Don't need get push key");
}

if (currentFullName?.isEmpty ?? true) {
try {
var currentUser = await _userRepository.getUser();
pref.saveString(DATA_CONST.CURRENT_FULL_NAME, currentUser.fullName);
print("fullname: ${currentUser.fullName}");
} catch (e) {
print("error: ${e.toString()}");
}
}
}

_notificationNavigateOnFCM(Map<String, dynamic> message) {
//parse data difference between Ios and Android
var noti;
if (Platform.isAndroid) {
var data = message['data'];
noti = NotificationDTO()
..contents = data['contents']
..tbCropId = data['tbCropId']
..type = data['type'];
} else {
noti = NotificationDTO.fromJson(message);
}
if (noti.contents == "ENV_UPDATE") {
Get.to(PlotDetailScreen(
cropType: noti.type,
cropId: noti.tbCropId,
initialIndex: 0,
));
} else if (noti.contents == "PIC_UPDATE") {
Get.to(PlotDetailScreen(
cropType: noti.type,
cropId: noti.tbCropId,
initialIndex: 1,
));
} else {
//Go home
}
}

@override
void initState() {
super.initState();
// getSharedPrefs();
}

@override

+ 32
- 9
lib/presentation/screens/tabbar/tabbar.dart View File

@@ -2,7 +2,6 @@ import 'dart:io';

import 'package:badges/badges.dart';
import 'package:dio/dio.dart';
import 'package:farm_tpf/custom_model/NotificationDTO.dart';
import 'package:farm_tpf/custom_model/NotificationObjectDTO.dart';
import 'package:farm_tpf/data/repository/user_repository.dart';
import 'package:farm_tpf/presentation/screens/account/sc_account.dart';
@@ -11,6 +10,7 @@ import 'package:farm_tpf/presentation/screens/notification/sc_notification.dart'
import 'package:farm_tpf/presentation/screens/notification/update_count_noti_bloc.dart';
import 'package:farm_tpf/presentation/screens/plot/sc_plot.dart';
import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
import 'package:farm_tpf/utils/NotificationsBloc.dart';
import 'package:farm_tpf/utils/const_color.dart';
import 'package:farm_tpf/utils/const_common.dart';
import 'package:farm_tpf/utils/const_icons.dart';
@@ -32,6 +32,7 @@ class TabbarScreen extends StatefulWidget {
}

class _TabbarScreenState extends State<TabbarScreen> {
Stream<LocalNotification> _notificationsStream;
UserRepository _userRepository = UserRepository();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
var pref = LocalPref();
@@ -67,10 +68,25 @@ class _TabbarScreenState extends State<TabbarScreen> {
}
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage---: $message");
print("onMessage--tabbar-: $message");
try {
print('call bloc update noti');
final String type = message['tbCropType'];
final String contents = message['contents'];
final String tbCropId = message['tbCropId'];

updateCountNotiBloc.getNotifications((data) {}, (err) {});
final notification = LocalNotification(type, contents, tbCropId);
NotificationsBloc.instance.newNotification(notification);

if (contents == "ENV_UPDATE") {
if (Get.isSnackbarOpen) Get.back();
Get.snackbar(null, 'Thông số môi trường được cập nhật');
} else if (contents == "PIC_UPDATE") {
if (Get.isSnackbarOpen) Get.back();
Get.snackbar(null, 'Người phụ trách được cập nhật');
} else {
//Go home
}
} catch (e) {
print('error');
print(e);
@@ -80,11 +96,13 @@ class _TabbarScreenState extends State<TabbarScreen> {
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
Future.delayed(Duration(milliseconds: 500), () {
updateCountNotiBloc.getNotifications((data) {}, (err) {});
_notificationNavigateOnFCM(message);
});
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
updateCountNotiBloc.getNotifications((data) {}, (err) {});
_notificationNavigateOnFCM(message);
},
);
@@ -126,23 +144,28 @@ class _TabbarScreenState extends State<TabbarScreen> {
getSharedPrefs();
changeTabbar.initValue();
updateCountNotiBloc.getNotifications((data) {}, (err) {});
_notificationsStream = NotificationsBloc.instance.notificationsStream;
_notificationsStream.listen((notification) {
updateCountNotiBloc.getNotifications((data) {}, (err) {});
print('Notification: $notification');
});
}

_notificationNavigateOnFCM(Map<String, dynamic> message) {
try {
final int type = message['tbCropType'];
final String type = message['tbCropType'];
final String contents = message['contents'];
final int tbCropId = message['tbCropId'];
final String tbCropId = message['tbCropId'];
if (contents == "ENV_UPDATE") {
Get.to(PlotDetailScreen(
cropType: type,
cropId: tbCropId,
cropType: int.parse(type),
cropId: int.parse(tbCropId),
initialIndex: 0,
));
} else if (contents == "PIC_UPDATE") {
Get.to(PlotDetailScreen(
cropType: type,
cropId: tbCropId,
cropType: int.parse(type),
cropId: int.parse(tbCropId),
initialIndex: 1,
));
} else {

+ 30
- 0
lib/utils/NotificationsBloc.dart View File

@@ -0,0 +1,30 @@
import 'package:rxdart/rxdart.dart';

class LocalNotification {
final String type;
final String contents;
final String tbCropId;

LocalNotification(this.type, this.contents, this.tbCropId);
}

class NotificationsBloc {
NotificationsBloc._internal();

static final NotificationsBloc instance = NotificationsBloc._internal();

final BehaviorSubject<LocalNotification> _notificationsStreamController =
BehaviorSubject<LocalNotification>();

Stream<LocalNotification> get notificationsStream {
return _notificationsStreamController;
}

void newNotification(LocalNotification notification) {
_notificationsStreamController.sink.add(notification);
}

void dispose() {
_notificationsStreamController?.close();
}
}

Loading…
Cancel
Save