123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579 |
- import 'dart:async';
- import 'dart:convert';
- import 'dart:io';
- import 'package:broadcast/broadcast.dart';
- import 'package:connectivity_plus/connectivity_plus.dart';
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:flutter_local_notifications/flutter_local_notifications.dart' hide Message;
- import 'package:get_it/get_it.dart';
- import 'package:getuiflut/getuiflut.dart';
- import 'package:provider/provider.dart';
- import 'package:rxdart/subjects.dart';
- import 'package:shared_preferences/shared_preferences.dart';
- import 'package:sport/application.dart';
- import 'package:sport/bean/game.dart';
- import 'package:sport/bean/message.dart';
- import 'package:sport/bean/user_info.dart';
- import 'package:sport/db/message_db.dart';
- import 'package:sport/pages/game/game_detail.dart';
- import 'package:sport/pages/social/chat_page.dart';
- import 'package:sport/provider/game_model.dart';
- import 'package:sport/provider/user_model.dart';
- import 'package:sport/router/navigator_util.dart';
- import 'package:sport/services/api/inject_api.dart';
- import 'package:sport/services/api/request.dart';
- import 'package:sport/services/api/resp.dart';
- import 'package:sport/services/api/rest_client.dart';
- import 'package:sport/widgets/button_primary.dart';
- import 'package:sport/widgets/image.dart';
- final BehaviorSubject<ReceivedNotification> didReceiveLocalNotificationSubject = BehaviorSubject<ReceivedNotification>();
- final BehaviorSubject<String?> selectNotificationSubject = BehaviorSubject<String?>();
- const MethodChannel platform = MethodChannel('dexterx.dev/flutter_local_notifications_example');
- class ReceivedNotification {
- ReceivedNotification({
- required this.id,
- required this.title,
- required this.body,
- required this.payload,
- });
- final int id;
- final String? title;
- final String? body;
- final String? payload;
- }
- class MessageModel extends ChangeNotifier with InjectApi {
- // Message _message;
- int? _curId;
- AppLifecycleState? state;
- String? selfId;
- final StreamController<int> _queryController = StreamController.broadcast();
- Stream<int> get queryStream => _queryController.stream;
- ///事件订阅对象
- StreamSubscription? periodicSubscription, countPeriodicSubscription;
- final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
- push(BuildContext context) async {
- var user = Provider.of<UserModel>(context, listen: false);
- var userId = user.user.id;
- print("flutter push user $userId");
- if (userId == 0) return;
- final AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('app_icon');
- final IOSInitializationSettings initializationSettingsIOS = IOSInitializationSettings(
- requestAlertPermission: false,
- requestBadgePermission: false,
- requestSoundPermission: false,
- onDidReceiveLocalNotification: (int id, String? title, String? body, String? payload) async {
- didReceiveLocalNotificationSubject.add(ReceivedNotification(id: id, title: title, body: body, payload: payload));
- });
- final InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
- await flutterLocalNotificationsPlugin.initialize(initializationSettings, onSelectNotification: (String? payload) async {
- if (payload != null) {
- debugPrint('notification payload: $payload');
- UserInfo? info = (await api.getUserInfo("$payload")).data;
- if (info != null)
- await NavigatorUtil.goPage(
- context,
- (context) => ChatPage(
- info,
- fetch: true,
- ));
- }
- selectNotificationSubject.add(payload);
- });
- //
- // if (Platform.isAndroid) {
- // await FlutterPluginMipush.init(appId: "2882303761520111715", appKey: "5722011155715");
- // } else if (Platform.isIOS) {
- // await FlutterPluginMipush.init(appId: "2882303761520111481", appKey: "5942011177481·");
- // } else {
- // return;
- // }
- //
- // await FlutterPluginMipush.setAlias(alias: "$userId", category: "app");
- // FlutterPluginMipush.stream.listen((event) {
- // print("FlutterPluginMipush listen $event");
- // Map<String, dynamic> extra = json.decode(event);
- // _addPushMessage(context, extra);
- // });
- print("flutter initGetuiSdk");
- var getuiflut = Getuiflut();
- getuiflut.addEventHandler(
- // 注册收到 cid 的回调
- onReceiveClientId: (String message) async {
- print("flutter onReceiveClientId: $message");
- getuiflut.bindAlias("$userId", "app");
- },
- // 注册 DeviceToken 回调
- onRegisterDeviceToken: (String message) async {
- print("flutter onRegisterDeviceToken: $message");
- },
- // SDK收到透传消息回调
- onReceivePayload: (Map<String, dynamic> message) async {
- print("flutter onReceivePayload: $message");
- if (message.containsKey("payloadMsg")) {
- try {
- _addPushMessage(context, json.decode(message["payloadMsg"]));
- } catch (e) {
- print(e);
- }
- }
- },
- // 点击通知回调
- onReceiveNotificationResponse: (Map<String, dynamic> message) async {
- print("flutter onReceiveNotificationResponse: $message");
- },
- // APPLink中携带的透传payload信息
- onAppLinkPayload: (String message) async {},
- //通知服务开启\关闭回调
- onPushModeResult: (Map<String, dynamic> message) async {
- print("flutter onPushModeResult: $message");
- },
- // SetTag回调
- onSetTagResult: (Map<String, dynamic> message) async {
- print("flutter onSetTagResult: $message");
- },
- //设置别名回调
- onAliasResult: (Map<String, dynamic> message) async {
- print("flutter onAliasResult: $message");
- },
- //查询别名回调
- onQueryTagResult: (Map<String, dynamic> message) async {
- print("flutter onQueryTagResult: $message");
- },
- //APNs通知即将展示回调
- onWillPresentNotification: (Map<String, dynamic> message) async {
- print("flutter onWillPresentNotification: $message");
- },
- //APNs通知设置跳转回调
- onOpenSettingsForNotification: (Map<String, dynamic> message) async {
- print("flutter onOpenSettingsForNotification: $message");
- },
- onReceiveMessageData: (Map<String, dynamic> event) async {
- print("flutter onReceiveMessageData: $event");
- if (event.containsKey("payload")) {
- try {
- _addPushMessage(context, json.decode(event["payload"]));
- } catch (e) {
- print(e);
- }
- }
- },
- onNotificationMessageClicked: (Map<String, dynamic> event) async {
- print("flutter onNotificationMessageClicked: $event");
- if (event.containsKey("payload")) {
- try {
- _addPushMessage(context, json.decode(event["payload"]));
- } catch (e) {
- print(e);
- }
- }
- },
- onNotificationMessageArrived: (Map<String, dynamic> event) async {
- print("flutter onNotificationMessageArrived: $event");
- },
- );
- if (Platform.isAndroid) {
- try {
- await Getuiflut.initGetuiSdk;
- } catch (e) {
- print(e);
- print("flutter Getuiflut: $e");
- }
- } else if (Platform.isIOS) {
- getuiflut.startSdk(appId: "Rvnote7osU9Ntxk4tpEP46", appKey: "9bHdNmOfPu5KXKAVKKXUv4", appSecret: "aMP4ifBDUJAzvL7KUe2M33");
- }
- }
- Future<void> _showNotification(ReceivedNotification notification) async {
- final AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails('101', '趣动', importance: Importance.defaultImportance, priority: Priority.defaultPriority, ticker: '${DateTime.now().millisecondsSinceEpoch}');
- final NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics);
- await flutterLocalNotificationsPlugin.show(notification.id, '${notification.title}', '${notification.body}', platformChannelSpecifics, payload: '${notification.payload}');
- }
- Future<GameInfoData?> getGame(BuildContext context, int id) async {
- GameModel gameModel = GetIt.I<GameModel>();
- GameInfoData? game = await gameModel.getGame(id);
- return game;
- }
- _addPushMessage(BuildContext context, Map<String, dynamic> extra) async {
- print("_addPushMessage: $extra");
- GameInfoData? game = await getGame(context, extra['game_id']);
- if (game == null) return;
- RespData<UserInfo> user = await GetIt.I<RestClient>().getUserInfo("${extra['from_id']}");
- UserInfo? userInfo = user.data;
- if (userInfo == null) return;
- Map<String, dynamic> args = {
- 'invite': {"info": "${extra['invite_info']}", "user": userInfo.toJsonSimple(), "game_id": "${game.id}", "ts": DateTime.now().millisecondsSinceEpoch},
- };
- print("jpush broadcast: $args");
- Broadcast.broadcast("SHOE.SDK.GAME_INVITE", args: args);
- if (state == AppLifecycleState.inactive || state == AppLifecycleState.paused) {
- _showNotification(ReceivedNotification(id: 1, title: "趣动", body: "${userInfo.name}邀请您玩${game.name}", payload: "${userInfo.id}"));
- // jpush.sendLocalNotification(LocalNotification(buildId: 1, id: 1, title: "趣动", content: "${userInfo.name}邀请您玩${game.name}", fireTime: DateTime.now()));
- } else {
- bool _showing = true;
- OverlayEntry? entry;
- entry = OverlayEntry(builder: (context) {
- return Positioned(
- //top值,可以改变这个值来改变toast在屏幕中的位置
- top: 20,
- child: Material(
- color: Color(0x00000000),
- child: SafeArea(
- child: Container(
- width: MediaQuery.of(context).size.width,
- alignment: Alignment.center, //居中
- child: AnimatedOpacity(
- //目标透明度
- opacity: _showing ? 1.0 : 0.0,
- //执行时间
- duration: Duration(milliseconds: 1000),
- child: Container(
- padding: EdgeInsets.all(12.0),
- width: double.infinity,
- margin: EdgeInsets.symmetric(horizontal: 12.0),
- decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0), color: Color(0xff241D19).withOpacity(.8)),
- child: Row(
- children: [
- CircleAvatar(
- backgroundColor: Colors.black26,
- radius: 22,
- backgroundImage: userAvatarProvider("${userInfo.avatar}"),
- ),
- const SizedBox(
- width: 12,
- ),
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- "${userInfo.name}",
- style: TextStyle(color: Colors.white, fontSize: 14),
- ),
- SizedBox(
- height: 5,
- ),
- Row(
- children: [
- Text(
- "邀请您玩",
- style: TextStyle(color: Colors.white, fontSize: 12),
- ),
- Text(
- "${game.name}",
- style: TextStyle(color: Theme.of(context).accentColor, fontSize: 12),
- ),
- ],
- )
- ],
- ),
- ),
- const SizedBox(
- width: 6,
- ),
- GestureDetector(
- onTap: () {
- if (entry != null) {
- entry!.remove();
- }
- entry = null;
- },
- child: Container(
- child: Center(
- child: Text(
- "取消",
- style: TextStyle(color: Colors.white, fontSize: 12),
- )),
- height: 30.0,
- width: 60.0,
- decoration: BoxDecoration(
- border: Border.all(
- color: Colors.white,
- width: 1,
- ),
- borderRadius: BorderRadius.circular(50)),
- ),
- ),
- const SizedBox(
- width: 6,
- ),
- PrimaryButton(
- callback: () {
- if (entry != null) {
- _showing = false;
- if (!_showing) {
- entry!.remove();
- }
- }
- entry = null;
- startGame(context, game, invite: "${extra['invite_info']}", user: userInfo, skipGuide: true);
- },
- content: "继续",
- height: 30.0,
- width: 60.0,
- fontSize: 12,
- )
- ],
- ),
- ),
- )),
- ),
- ));
- });
- if (entry != null) Overlay.of(context)?.insert(entry!);
- await Future.delayed(Duration(milliseconds: 5000));
- if (entry != null) {
- _showing = false;
- //重新绘制UI,类似setState
- entry!.markNeedsBuild();
- //等待动画执行
- await Future.delayed(Duration(milliseconds: 1000));
- if (!_showing) {
- entry!.remove();
- }
- }
- entry = null;
- }
- }
- loop(BuildContext context) async {
- close();
- if (inProduction) {
- if (openSocial())
- periodicSubscription = Stream.periodic(Duration(seconds: 10)).listen((event) {
- if (state == AppLifecycleState.inactive || state == AppLifecycleState.paused) return;
- loopMessage(context);
- });
- countPeriodicSubscription = Stream.periodic(Duration(seconds: 60)).listen((event) {
- _loopCount();
- });
- selfId = "${Provider.of<UserModel>(context, listen: false).user.id}";
- _loopCount();
- }
- }
- loopMessage(BuildContext context) async {
- Message? data;
- SharedPreferences prefs = await SharedPreferences.getInstance();
- String? token = prefs.getString("token");
- if (token == null || token.isEmpty == true) return;
- if (_curId != null) {
- data = (await api.getMessageForPoll(curId: _curId)).data;
- } else {
- data = (await api.getMessageForPoll()).data;
- }
- if (data == null) return;
- // curId 这里一定是接口返回的 本地存 sqlite的 curId 全部都是 0
- _curId = data.curId;
- List<MessageInstance> messages = data.messages ?? [];
- // 没有新消息还处理流程吗?
- // if(_messages.length == 0)
- // return
- // var list = await MessageDB().findAll(); // 清空数字
- // print("[list]:$list--------------------------");
- // var userList = await MessageDB().findAllUser();
- // print("[list]:$userList--------------------------");
- // MessageDB().deleteTable(); //
- // 这里本来是做了去重操作的 现在不用了 ...
- // if (_messages.length > 0) {
- // var list = await MessageDB().findLatest();
- // print(list);
- // if (list.length != 0) {
- // int lastCurId = list[0]["curId"];
- // print('[lastCurId]:$lastCurId-------------------------');
- // // 可能会重复插入...;
- // if (lastCurId != _curId) {
- // add(data.messages, _curId);
- // }
- // } else {
- //// add(data.messages, _curId);
- // }
- // }
- int me = Provider.of<UserModel>(context, listen: false).user.id;
- _add(me, messages);
- }
- add(BuildContext context, List<MessageInstance> messages) async {
- int me = Provider.of<UserModel>(context, listen: false).user.id;
- _add(me, messages);
- }
- _add(int me, List<MessageInstance> messages) async {
- if (messages.isEmpty == true) return;
- List<Map<String, dynamic>> _items = [];
- int messageCount = 0;
- for (MessageInstance _instance in messages) {
- bool isMe = me == _instance.fromUser?.id;
- MessageUser? other = isMe ? _instance.toUser : _instance.fromUser;
- if (other == null) continue;
- var list = await MessageDB().findHasUserId(me, other.id!);
- int chatId = 0;
- if (list.length == 0) {
- chatId = await MessageDB().createChatUser(me, other);
- } else {
- var dbUser = list[0];
- chatId = dbUser['id'];
- if (other.name != dbUser['name'] || other.avatar != dbUser['avatar']) {
- MessageDB().updateChatUser(chatId, other);
- }
- }
- Map<String, dynamic> map = _instance.toDBJson();
- map['chat_id'] = chatId;
- // 插进去是 0: 已读, 1: 未读
- map['status'] = isMe ? 0 : 1;
- _items.add(map);
- messageCount += isMe ? 0 : 1;
- }
- // print("1111111111111111111 add message $_items");
- await MessageDB().insertAll(_items);
- notifierMessage.value = notifierMessage.value + messageCount;
- if (messages.isNotEmpty == true) _queryController.add(messages.length);
- }
- close() {
- ///关闭
- periodicSubscription?.cancel();
- countPeriodicSubscription?.cancel();
- // _queryController.close();
- }
- ValueNotifier<int> notifierComment = ValueNotifier(0);
- ValueNotifier<int> notifierLike = ValueNotifier(0);
- ValueNotifier<int> notifierSocial = ValueNotifier(0);
- ValueNotifier<int> notifierMessage = ValueNotifier(0);
- ValueNotifier<int> notifierFriendFansList = ValueNotifier(0);
- ValueNotifier<int> notifierFriendFollowList = ValueNotifier(0);
- ValueNotifier<int> notifierFriend = ValueNotifier(0);
- ValueNotifier<int> notifierSocialTotal = ValueNotifier(0);
- //
- // getSocialCount() async {
- // int count = 0;
- // try {
- // int _count = (await api.getNoticeCount("comment", "0")).data ?? 0;
- // notifierComment.value = _count;
- // count += _count;
- // } catch (e) {
- // print(e);
- // }
- // try {
- // int _count = (await api.getNoticeCount("like", "0")).data ?? 0;
- // notifierLike.value = _count;
- // count += _count;
- // } catch (e) {
- // print(e);
- // }
- //
- // List<int> result = messag
- //
- // notifierSocial.value = count + unRead;
- // }
- //
- // getFriendCount() async {
- // int count = 0;
- // // try {
- // // FriendList? list = (await api.userFollowList(limit: 1)).data;
- // // int _count = 0;
- // // list?.list?.forEach((element) {
- // // if(element.isIgnore == 0 && element.isFriends == "0")
- // // _count += 1;
- // // });
- // // notifierFriendFollowList.value = _count;
- // // count += _count;
- // // } catch (e) {
- // // print(e);
- // // }
- // try {
- // // FriendList? list = (await api.userFansList(limit: 1)).data;
- // // int _count = 0;
- // // list?.list?.forEach((element) {
- // // if(element.isIgnore == 0 && element.isFriends == "0")
- // // _count += 1;
- // // });
- // int _count = (await api.userFansList(limit: 1)).data?.noIgnoreCount ?? 0;
- // notifierFriendFansList.value = _count;
- // count += _count;
- // } catch (e) {
- // print(e);
- // }
- // notifierFriend.value = count;
- // }
- void getCount() async {
- List<int> result = await mergeMessageCount();
- // int count = result.fold(0, (previousValue, element) => previousValue + element);
- notifierLike.value = result[0];
- notifierComment.value = result[1];
- notifierFriendFansList.value = result[2];
- int unRead = 0;
- if (selfId != null) {
- var unReadList = await MessageDB().getMessageUnRead(selfId!);
- unRead = unReadList.fold(0, (previousValue, element) => previousValue + (element["cout"] as int));
- notifierMessage.value = unRead;
- }
- notifierSocial.value = result[0] + result[1] + unRead;
- notifierFriend.value = result[2];
- }
- void _loopCount() {
- SharedPreferences.getInstance().then((value) {
- if (value.containsKey("token")) {
- getCount();
- }
- });
- }
- void init() {
- notifierSocial.addListener(() {
- notifierSocialTotal.value = notifierSocial.value + notifierFriend.value;
- });
- notifierFriend.addListener(() {
- notifierSocialTotal.value = notifierSocial.value + notifierFriend.value;
- });
- notifierMessage.addListener(() {
- notifierSocial.value = notifierComment.value + notifierLike.value + notifierMessage.value;
- notifierSocialTotal.value = notifierSocial.value + notifierFriend.value;
- });
- if (inProduction && openSocial()) {
- _loopCount();
- }
- Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
- connectivityResult = result;
- });
- }
- }
|