together_mobile/lib/screens/home/home_screen.dart

293 lines
9.4 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get_it_mixin/get_it_mixin.dart';
import 'package:go_router/go_router.dart';
import 'package:badges/badges.dart' as badges;
import 'package:hive_flutter/hive_flutter.dart';
import '/database/box_type.dart';
import '/database/hive_database.dart';
import '/models/apply_list_model.dart';
import '/models/init_get_it.dart';
import '/models/route_state_model.dart';
import '/models/user_model.dart';
import '/notification_api.dart';
class HomeScreenWithNavBar extends StatefulWidget
with GetItStatefulWidgetMixin {
HomeScreenWithNavBar({
super.key,
required this.notificationAppLaunchDetails,
required this.initIndex,
required this.child,
this.listController,
});
final int initIndex;
final Widget child;
// used to get back to top
final ScrollController? listController;
final NotificationAppLaunchDetails? notificationAppLaunchDetails;
bool get didNotificationLanunchApp =>
notificationAppLaunchDetails?.didNotificationLaunchApp ?? false;
@override
State<HomeScreenWithNavBar> createState() => _HomeScreenWithNavBarState();
}
class _HomeScreenWithNavBarState extends State<HomeScreenWithNavBar>
with GetItStateMixin, WidgetsBindingObserver {
Future<bool> _openBox() async {
if (!getIt.get<UserProfile>().isInitialised) {
await HiveDatabase.init();
}
return Future(() => true);
}
// ignore: unused_field
bool _notificationsEnabled = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_isAndroidPermissionGranted();
_requestPermissions();
_configureDidReceiveLocalNotificationSubject();
_configureSelectNotificationSubject();
}
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
NotificationAPI.didReceiveNotificationStream.close();
NotificationAPI.selectNotificationStream.close();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
switch (state) {
case AppLifecycleState.resumed:
print('应用进入前台==================');
NotificationAPI.messages.clear();
NotificationAPI.flutterLocalNotificationsPlugin.cancelAll();
getIt.get<RouteState>().changeVisibility(true);
break;
case AppLifecycleState.inactive:
print('应用处于闲置状态,切换到后台触发====================');
getIt.get<RouteState>().changeVisibility(false);
break;
case AppLifecycleState.paused:
print('应用处于不可见状态========================');
getIt.get<RouteState>().changeVisibility(false);
break;
case AppLifecycleState.detached:
print('当前页面即将退出===================');
getIt.get<RouteState>().changeVisibility(false);
break;
case AppLifecycleState.hidden:
print("当前应用被隐藏=======================");
}
}
Future<void> _isAndroidPermissionGranted() async {
if (Platform.isAndroid) {
final bool granted = await NotificationAPI.flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.areNotificationsEnabled() ??
false;
setState(() {
_notificationsEnabled = granted;
});
}
}
Future<void> _requestPermissions() async {
if (Platform.isIOS || Platform.isMacOS) {
await NotificationAPI.flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
await NotificationAPI.flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
MacOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
} else if (Platform.isAndroid) {
final AndroidFlutterLocalNotificationsPlugin? androidImplementation =
NotificationAPI.flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>();
final bool? grantedNotificationPermission =
await androidImplementation?.requestNotificationsPermission();
setState(() {
_notificationsEnabled = grantedNotificationPermission ?? false;
});
}
}
void _configureDidReceiveLocalNotificationSubject() {
NotificationAPI.didReceiveNotificationStream.stream.listen(
(ReceivedNotification? receivedNotification) async {
await showDialog(
context: context,
builder: (BuildContext context) => AlertDialog(
title: receivedNotification!.title != null
? Text(receivedNotification.title!)
: null,
content: receivedNotification.body != null
? Text(receivedNotification.body!)
: null,
actions: <Widget>[
TextButton(
onPressed: () {},
child: const Text('ok'),
),
],
),
);
},
);
}
void _configureSelectNotificationSubject() {
// this listener will be call after taps a notification
NotificationAPI.selectNotificationStream.stream
.listen((String? payload) async {
NotificationAPI.messages.clear();
if (payload != null) {
Map<String, dynamic> payloadData = json.decode(payload);
switch (payloadData['event']) {
case 'friend-message':
String friendId = payloadData['friendId']!;
context.goNamed(
'Message',
queryParameters: {
'friendId': friendId,
'type': '0',
},
);
break;
case 'group-chat-message':
String groupChatId = payloadData['groupChatId']!;
context.goNamed(
'Message',
queryParameters: {
'groupChatId': groupChatId,
'type': '1',
},
);
}
}
});
}
@override
Widget build(BuildContext context) {
int applyCount = watchOnly((ApplyList applyList) => applyList.count);
return Scaffold(
body: widget.child,
bottomNavigationBar: BottomNavigationBar(
backgroundColor:
Theme.of(context).bottomNavigationBarTheme.backgroundColor,
items: [
BottomNavigationBarItem(
icon: FutureBuilder(
future: _openBox(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ValueListenableBuilder(
valueListenable:
Hive.box<ChatSetting>('chat_setting').listenable(),
builder: (context, chatSettingBox, _) {
final values = chatSettingBox.values;
int unreadCount = 0;
for (var value in values) {
unreadCount += value.unreadCount;
}
return badges.Badge(
badgeContent: Text(
unreadCount > 99 ? '$unreadCount+' : '$unreadCount',
style: TextStyle(
fontSize: 11,
color: Theme.of(context).colorScheme.inversePrimary,
),
),
position:
badges.BadgePosition.topEnd(top: -8, end: -12),
showBadge: unreadCount > 0,
child: const Icon(Icons.message),
);
},
);
} else {
return const Icon(Icons.message);
}
},
),
label: '消息',
),
BottomNavigationBarItem(
icon: badges.Badge(
badgeContent: Text(
applyCount > 99 ? '$applyCount+' : '$applyCount',
style: TextStyle(
fontSize: 11,
color: Theme.of(context).colorScheme.inversePrimary,
),
),
position: badges.BadgePosition.topStart(top: -8, start: -12),
showBadge: applyCount > 0,
child: const Icon(Icons.contacts),
),
label: '通讯录',
),
const BottomNavigationBarItem(
icon: Icon(Icons.star),
label: '更多',
),
],
onTap: (int index) => _onItemTapped(index, context),
currentIndex: widget.initIndex,
),
);
}
void _onItemTapped(int index, BuildContext context) {
switch (index) {
case 0:
NotificationAPI.messages.clear();
NotificationAPI.flutterLocalNotificationsPlugin.cancelAll();
GoRouter.of(context).go('/chat');
break;
case 1:
GoRouter.of(context).go('/contact');
break;
case 2:
GoRouter.of(context).go('/more');
break;
}
}
}