mirror of
https://github.com/Linloir/Simple-TCP-Client.git
synced 2025-12-18 17:28:11 +08:00
New Feature:
- Push notification!
This commit is contained in:
parent
5834bcaa58
commit
acc5f493af
@ -30,6 +30,7 @@ android {
|
|||||||
ndkVersion flutter.ndkVersion
|
ndkVersion flutter.ndkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
coreLibraryDesugaringEnabled true
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
@ -51,6 +52,7 @@ android {
|
|||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
|
multiDexEnabled true
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@ -68,4 +70,10 @@ flutter {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
|
||||||
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||||
|
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||||
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||||
}
|
}
|
||||||
|
|||||||
27
android/app/proguard-rules.pro
vendored
Normal file
27
android/app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
## Gson rules
|
||||||
|
# Gson uses generic type information stored in a class file when working with fields. Proguard
|
||||||
|
# removes such information by default, so configure it to keep all of it.
|
||||||
|
-keepattributes Signature
|
||||||
|
|
||||||
|
# For using GSON @Expose annotation
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
|
||||||
|
# Gson specific classes
|
||||||
|
-dontwarn sun.misc.**
|
||||||
|
#-keep class com.google.gson.stream.** { *; }
|
||||||
|
|
||||||
|
# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
|
||||||
|
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
|
||||||
|
-keep class * extends com.google.gson.TypeAdapter
|
||||||
|
-keep class * implements com.google.gson.TypeAdapterFactory
|
||||||
|
-keep class * implements com.google.gson.JsonSerializer
|
||||||
|
-keep class * implements com.google.gson.JsonDeserializer
|
||||||
|
|
||||||
|
# Prevent R8 from leaving Data object members always null
|
||||||
|
-keepclassmembers,allowobfuscation class * {
|
||||||
|
@com.google.gson.annotations.SerializedName <fields>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
|
||||||
|
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
|
||||||
|
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
|
||||||
@ -11,7 +11,9 @@
|
|||||||
android:theme="@style/LaunchTheme"
|
android:theme="@style/LaunchTheme"
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
android:windowSoftInputMode="adjustResize">
|
android:windowSoftInputMode="adjustResize"
|
||||||
|
android:showWhenLocked="true"
|
||||||
|
android:turnScreenOn="true">
|
||||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||||
the Android process has started. This theme is visible to the user
|
the Android process has started. This theme is visible to the user
|
||||||
while the Flutter UI initializes. After that, this theme continues
|
while the Flutter UI initializes. After that, this theme continues
|
||||||
@ -30,6 +32,11 @@
|
|||||||
<meta-data
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
|
<service
|
||||||
|
android:name="com.dexterous.flutterlocalnotifications.ForegroundService"
|
||||||
|
android:exported="false"
|
||||||
|
android:stopWithTask="false"/>
|
||||||
</application>
|
</application>
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
3
android/app/src/main/res/raw/keep.xml
Normal file
3
android/app/src/main/res/raw/keep.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:keep="@drawable/*" />
|
||||||
@ -7,7 +7,17 @@ import Flutter
|
|||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
|
// This is required to make any communication available in the action isolate.
|
||||||
|
FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
|
||||||
|
GeneratedPluginRegistrant.register(with: registry)
|
||||||
|
}
|
||||||
|
|
||||||
GeneratedPluginRegistrant.register(with: self)
|
GeneratedPluginRegistrant.register(with: self)
|
||||||
|
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
|
||||||
|
}
|
||||||
|
|
||||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-13 14:02:28
|
* @Date : 2022-10-13 14:02:28
|
||||||
* @LastEditTime : 2022-10-22 21:08:39
|
* @LastEditTime : 2022-10-23 22:37:55
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -9,18 +9,22 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tcp_client/home/cubit/home_state.dart';
|
import 'package:tcp_client/home/cubit/home_state.dart';
|
||||||
import 'package:tcp_client/repositories/local_service_repository/local_service_repository.dart';
|
import 'package:tcp_client/repositories/local_service_repository/local_service_repository.dart';
|
||||||
import 'package:tcp_client/repositories/tcp_repository/models/tcp_request.dart';
|
import 'package:tcp_client/repositories/tcp_repository/models/tcp_request.dart';
|
||||||
import 'package:tcp_client/repositories/tcp_repository/models/tcp_response.dart';
|
import 'package:tcp_client/repositories/tcp_repository/models/tcp_response.dart';
|
||||||
import 'package:tcp_client/repositories/tcp_repository/tcp_repository.dart';
|
import 'package:tcp_client/repositories/tcp_repository/tcp_repository.dart';
|
||||||
|
import 'package:tcp_client/repositories/user_repository/user_repository.dart';
|
||||||
|
|
||||||
class HomeCubit extends Cubit<HomeState> {
|
class HomeCubit extends Cubit<HomeState> {
|
||||||
HomeCubit({
|
HomeCubit({
|
||||||
required this.localServiceRepository,
|
required this.localServiceRepository,
|
||||||
required this.tcpRepository,
|
required this.tcpRepository,
|
||||||
required this.pageController
|
required this.pageController,
|
||||||
|
required this.localNotificationsPlugin,
|
||||||
|
required this.userRepository
|
||||||
}): super(const HomeState(page: HomePagePosition.message, status: HomePageStatus.initializing)) {
|
}): super(const HomeState(page: HomePagePosition.message, status: HomePageStatus.initializing)) {
|
||||||
pageController.addListener(() {
|
pageController.addListener(() {
|
||||||
emit(state.copyWith(page: HomePagePosition.fromValue((pageController.page ?? 0).round())));
|
emit(state.copyWith(page: HomePagePosition.fromValue((pageController.page ?? 0).round())));
|
||||||
@ -59,7 +63,9 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
final LocalServiceRepository localServiceRepository;
|
final LocalServiceRepository localServiceRepository;
|
||||||
final TCPRepository tcpRepository;
|
final TCPRepository tcpRepository;
|
||||||
final PageController pageController;
|
final PageController pageController;
|
||||||
|
final UserRepository userRepository;
|
||||||
late final StreamSubscription subscription;
|
late final StreamSubscription subscription;
|
||||||
|
final FlutterLocalNotificationsPlugin localNotificationsPlugin;
|
||||||
|
|
||||||
void switchPage(HomePagePosition newPage) {
|
void switchPage(HomePagePosition newPage) {
|
||||||
pageController.animateToPage(
|
pageController.animateToPage(
|
||||||
@ -77,6 +83,36 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
case TCPResponseType.forwardMessage: {
|
case TCPResponseType.forwardMessage: {
|
||||||
response as ForwardMessageResponse;
|
response as ForwardMessageResponse;
|
||||||
await localServiceRepository.storeMessages([response.message]);
|
await localServiceRepository.storeMessages([response.message]);
|
||||||
|
var curUser = (await SharedPreferences.getInstance()).getInt('userid');
|
||||||
|
if(response.message.senderID != curUser) {
|
||||||
|
//Push notification via flutter local notification
|
||||||
|
const androidNotificationDetails = AndroidNotificationDetails(
|
||||||
|
'0',
|
||||||
|
'New Messages',
|
||||||
|
channelDescription: 'New messages',
|
||||||
|
importance: Importance.max,
|
||||||
|
priority: Priority.max,
|
||||||
|
enableVibration: true,
|
||||||
|
enableLights: true,
|
||||||
|
visibility: NotificationVisibility.private
|
||||||
|
);
|
||||||
|
const iosNotificationDetails = DarwinNotificationDetails();
|
||||||
|
const linuxNotificationDetails = LinuxNotificationDetails();
|
||||||
|
const notificationDetails = NotificationDetails(
|
||||||
|
android: androidNotificationDetails,
|
||||||
|
iOS: iosNotificationDetails,
|
||||||
|
macOS: iosNotificationDetails,
|
||||||
|
linux: linuxNotificationDetails
|
||||||
|
);
|
||||||
|
var userName = userRepository.getUserInfo(userid: response.message.senderID).userName;
|
||||||
|
await localNotificationsPlugin.show(
|
||||||
|
response.message.contentmd5.hashCode,
|
||||||
|
'New Message',
|
||||||
|
'$userName: ${response.message.contentDecoded}',
|
||||||
|
notificationDetails,
|
||||||
|
payload: response.message.contentmd5
|
||||||
|
);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TCPResponseType.fetchMessage: {
|
case TCPResponseType.fetchMessage: {
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-11 11:05:08
|
* @Date : 2022-10-11 11:05:08
|
||||||
* @LastEditTime : 2022-10-23 12:14:36
|
* @LastEditTime : 2022-10-23 22:37:02
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tcp_client/home/cubit/home_cubit.dart';
|
import 'package:tcp_client/home/cubit/home_cubit.dart';
|
||||||
import 'package:tcp_client/home/cubit/home_state.dart';
|
import 'package:tcp_client/home/cubit/home_state.dart';
|
||||||
@ -27,6 +28,7 @@ class HomePage extends StatelessWidget with WindowListener {
|
|||||||
required this.userID,
|
required this.userID,
|
||||||
required this.localServiceRepository,
|
required this.localServiceRepository,
|
||||||
required this.tcpRepository,
|
required this.tcpRepository,
|
||||||
|
required this.localNotificationsPlugin,
|
||||||
super.key
|
super.key
|
||||||
});
|
});
|
||||||
//TODO: listen to file storage
|
//TODO: listen to file storage
|
||||||
@ -34,15 +36,18 @@ class HomePage extends StatelessWidget with WindowListener {
|
|||||||
final int userID;
|
final int userID;
|
||||||
final LocalServiceRepository localServiceRepository;
|
final LocalServiceRepository localServiceRepository;
|
||||||
final TCPRepository tcpRepository;
|
final TCPRepository tcpRepository;
|
||||||
|
final FlutterLocalNotificationsPlugin localNotificationsPlugin;
|
||||||
|
|
||||||
static Route<void> route({
|
static Route<void> route({
|
||||||
required int userID,
|
required int userID,
|
||||||
required LocalServiceRepository localServiceRepository,
|
required LocalServiceRepository localServiceRepository,
|
||||||
required TCPRepository tcpRepository
|
required TCPRepository tcpRepository,
|
||||||
|
required FlutterLocalNotificationsPlugin localNotificationsPlugin,
|
||||||
}) => MaterialPageRoute<void>(builder: (context) => HomePage(
|
}) => MaterialPageRoute<void>(builder: (context) => HomePage(
|
||||||
userID: userID,
|
userID: userID,
|
||||||
localServiceRepository: localServiceRepository,
|
localServiceRepository: localServiceRepository,
|
||||||
tcpRepository: tcpRepository,
|
tcpRepository: tcpRepository,
|
||||||
|
localNotificationsPlugin: localNotificationsPlugin,
|
||||||
));
|
));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -76,7 +81,9 @@ class HomePage extends StatelessWidget with WindowListener {
|
|||||||
create: (context) => HomeCubit(
|
create: (context) => HomeCubit(
|
||||||
localServiceRepository: localServiceRepository,
|
localServiceRepository: localServiceRepository,
|
||||||
tcpRepository: tcpRepository,
|
tcpRepository: tcpRepository,
|
||||||
pageController: PageController()
|
pageController: PageController(),
|
||||||
|
localNotificationsPlugin: localNotificationsPlugin,
|
||||||
|
userRepository: context.read<UserRepository>()
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-12 23:36:12
|
* @Date : 2022-10-12 23:36:12
|
||||||
* @LastEditTime : 2022-10-20 11:45:15
|
* @LastEditTime : 2022-10-23 22:10:44
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -57,7 +57,8 @@ class MyProfilePage extends StatelessWidget {
|
|||||||
Future.delayed(const Duration(seconds: 1)).then((_) {
|
Future.delayed(const Duration(seconds: 1)).then((_) {
|
||||||
Navigator.of(context).pushAndRemoveUntil(LoginPage.route(
|
Navigator.of(context).pushAndRemoveUntil(LoginPage.route(
|
||||||
localServiceRepository: context.read<LocalServiceRepository>(),
|
localServiceRepository: context.read<LocalServiceRepository>(),
|
||||||
tcpRepository: context.read<TCPRepository>()
|
tcpRepository: context.read<TCPRepository>(),
|
||||||
|
localNotificationsPlugin: context.read<HomeCubit>().localNotificationsPlugin
|
||||||
), (route) => false);
|
), (route) => false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-12 15:06:30
|
* @Date : 2022-10-12 15:06:30
|
||||||
* @LastEditTime : 2022-10-23 10:15:11
|
* @LastEditTime : 2022-10-23 22:12:07
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:formz/formz.dart';
|
import 'package:formz/formz.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tcp_client/home/home_page.dart';
|
import 'package:tcp_client/home/home_page.dart';
|
||||||
@ -21,19 +22,23 @@ class LoginPage extends StatelessWidget {
|
|||||||
const LoginPage({
|
const LoginPage({
|
||||||
required this.localServiceRepository,
|
required this.localServiceRepository,
|
||||||
required this.tcpRepository,
|
required this.tcpRepository,
|
||||||
|
required this.localNotificationsPlugin,
|
||||||
super.key
|
super.key
|
||||||
});
|
});
|
||||||
|
|
||||||
static Route<void> route({
|
static Route<void> route({
|
||||||
required LocalServiceRepository localServiceRepository,
|
required LocalServiceRepository localServiceRepository,
|
||||||
required TCPRepository tcpRepository
|
required TCPRepository tcpRepository,
|
||||||
|
required FlutterLocalNotificationsPlugin localNotificationsPlugin,
|
||||||
}) => MaterialPageRoute<void>(builder: (context) => LoginPage(
|
}) => MaterialPageRoute<void>(builder: (context) => LoginPage(
|
||||||
localServiceRepository: localServiceRepository,
|
localServiceRepository: localServiceRepository,
|
||||||
tcpRepository: tcpRepository
|
tcpRepository: tcpRepository,
|
||||||
|
localNotificationsPlugin: localNotificationsPlugin,
|
||||||
));
|
));
|
||||||
|
|
||||||
final LocalServiceRepository localServiceRepository;
|
final LocalServiceRepository localServiceRepository;
|
||||||
final TCPRepository tcpRepository;
|
final TCPRepository tcpRepository;
|
||||||
|
final FlutterLocalNotificationsPlugin localNotificationsPlugin;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -64,7 +69,8 @@ class LoginPage extends StatelessWidget {
|
|||||||
Navigator.of(context).pushReplacement(HomePage.route(
|
Navigator.of(context).pushReplacement(HomePage.route(
|
||||||
userID: userID,
|
userID: userID,
|
||||||
localServiceRepository: localServiceRepository,
|
localServiceRepository: localServiceRepository,
|
||||||
tcpRepository: tcpRepository
|
tcpRepository: tcpRepository,
|
||||||
|
localNotificationsPlugin: localNotificationsPlugin
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -96,7 +102,11 @@ class LoginPage extends StatelessWidget {
|
|||||||
const Text('Does not have an account?'),
|
const Text('Does not have an account?'),
|
||||||
const SizedBox(width: 8,),
|
const SizedBox(width: 8,),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).push(RegisterPage.route(localServiceRepository: localServiceRepository, tcpRepository: tcpRepository)),
|
onPressed: () => Navigator.of(context).push(RegisterPage.route(
|
||||||
|
localServiceRepository: localServiceRepository,
|
||||||
|
tcpRepository: tcpRepository,
|
||||||
|
localNotificationsPlugin: localNotificationsPlugin
|
||||||
|
)),
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
overlayColor: MaterialStateProperty.all(Colors.transparent),
|
overlayColor: MaterialStateProperty.all(Colors.transparent),
|
||||||
foregroundColor: MaterialStateProperty.all(Colors.blue[800])
|
foregroundColor: MaterialStateProperty.all(Colors.blue[800])
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-10 08:04:53
|
* @Date : 2022-10-10 08:04:53
|
||||||
* @LastEditTime : 2022-10-23 12:18:17
|
* @LastEditTime : 2022-10-23 22:26:44
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
@ -13,8 +13,33 @@ import 'package:tcp_client/initialization/cubit/initialization_cubit.dart';
|
|||||||
import 'package:tcp_client/initialization/cubit/initialization_state.dart';
|
import 'package:tcp_client/initialization/cubit/initialization_state.dart';
|
||||||
import 'package:tcp_client/initialization/initialization_page.dart';
|
import 'package:tcp_client/initialization/initialization_page.dart';
|
||||||
import 'package:tcp_client/login/login_page.dart';
|
import 'package:tcp_client/login/login_page.dart';
|
||||||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
|
|
||||||
|
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
|
||||||
|
FlutterLocalNotificationsPlugin();
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
|
// needed if you intend to initialize in the `main` function
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
const AndroidInitializationSettings initializationSettingsAndroid =
|
||||||
|
AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||||
|
const DarwinInitializationSettings initializationSettingsDarwin =
|
||||||
|
DarwinInitializationSettings();
|
||||||
|
const LinuxInitializationSettings initializationSettingsLinux =
|
||||||
|
LinuxInitializationSettings(
|
||||||
|
defaultActionName: 'Open notification'
|
||||||
|
);
|
||||||
|
const InitializationSettings initializationSettings =
|
||||||
|
InitializationSettings(
|
||||||
|
android: initializationSettingsAndroid,
|
||||||
|
iOS: initializationSettingsDarwin,
|
||||||
|
macOS: initializationSettingsDarwin,
|
||||||
|
linux: initializationSettingsLinux
|
||||||
|
);
|
||||||
|
await flutterLocalNotificationsPlugin.initialize(
|
||||||
|
initializationSettings
|
||||||
|
);
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +54,7 @@ class MyAppState extends State<MyApp> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Flutter Demo',
|
title: 'LChatClient',
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
primarySwatch: Colors.blue,
|
primarySwatch: Colors.blue,
|
||||||
),
|
),
|
||||||
@ -49,7 +74,7 @@ class SplashPage extends StatelessWidget {
|
|||||||
return BlocProvider<InitializationCubit>(
|
return BlocProvider<InitializationCubit>(
|
||||||
create: (context) {
|
create: (context) {
|
||||||
return InitializationCubit(
|
return InitializationCubit(
|
||||||
serverAddress: '127.0.0.1',
|
serverAddress: 'chat.linloir.cn',
|
||||||
serverPort: 20706
|
serverPort: 20706
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -65,13 +90,15 @@ class SplashPage extends StatelessWidget {
|
|||||||
Navigator.of(context).pushReplacement(HomePage.route(
|
Navigator.of(context).pushReplacement(HomePage.route(
|
||||||
userID: userID,
|
userID: userID,
|
||||||
localServiceRepository: state.localServiceRepository!,
|
localServiceRepository: state.localServiceRepository!,
|
||||||
tcpRepository: state.tcpRepository!
|
tcpRepository: state.tcpRepository!,
|
||||||
|
localNotificationsPlugin: flutterLocalNotificationsPlugin
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Navigator.of(context).pushReplacement(LoginPage.route(
|
Navigator.of(context).pushReplacement(LoginPage.route(
|
||||||
localServiceRepository: state.localServiceRepository!,
|
localServiceRepository: state.localServiceRepository!,
|
||||||
tcpRepository: state.tcpRepository!
|
tcpRepository: state.tcpRepository!,
|
||||||
|
localNotificationsPlugin: flutterLocalNotificationsPlugin
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-12 17:36:38
|
* @Date : 2022-10-12 17:36:38
|
||||||
* @LastEditTime : 2022-10-23 10:15:31
|
* @LastEditTime : 2022-10-23 22:12:12
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:formz/formz.dart';
|
import 'package:formz/formz.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tcp_client/home/home_page.dart';
|
import 'package:tcp_client/home/home_page.dart';
|
||||||
@ -26,19 +27,24 @@ class RegisterPage extends StatelessWidget {
|
|||||||
const RegisterPage({
|
const RegisterPage({
|
||||||
required this.localServiceRepository,
|
required this.localServiceRepository,
|
||||||
required this.tcpRepository,
|
required this.tcpRepository,
|
||||||
|
required this.localNotificationsPlugin,
|
||||||
super.key
|
super.key
|
||||||
});
|
});
|
||||||
|
|
||||||
static Route<void> route({
|
static Route<void> route({
|
||||||
required LocalServiceRepository localServiceRepository,
|
required LocalServiceRepository localServiceRepository,
|
||||||
required TCPRepository tcpRepository
|
required TCPRepository tcpRepository,
|
||||||
|
required FlutterLocalNotificationsPlugin localNotificationsPlugin,
|
||||||
}) => MaterialPageRoute<void>(builder: (context) => RegisterPage(
|
}) => MaterialPageRoute<void>(builder: (context) => RegisterPage(
|
||||||
localServiceRepository: localServiceRepository,
|
localServiceRepository: localServiceRepository,
|
||||||
tcpRepository: tcpRepository
|
tcpRepository: tcpRepository,
|
||||||
|
localNotificationsPlugin: localNotificationsPlugin,
|
||||||
|
|
||||||
));
|
));
|
||||||
|
|
||||||
final LocalServiceRepository localServiceRepository;
|
final LocalServiceRepository localServiceRepository;
|
||||||
final TCPRepository tcpRepository;
|
final TCPRepository tcpRepository;
|
||||||
|
final FlutterLocalNotificationsPlugin localNotificationsPlugin;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -74,7 +80,8 @@ class RegisterPage extends StatelessWidget {
|
|||||||
Navigator.of(context).pushAndRemoveUntil(HomePage.route(
|
Navigator.of(context).pushAndRemoveUntil(HomePage.route(
|
||||||
userID: userID,
|
userID: userID,
|
||||||
localServiceRepository: localServiceRepository,
|
localServiceRepository: localServiceRepository,
|
||||||
tcpRepository: tcpRepository
|
tcpRepository: tcpRepository,
|
||||||
|
localNotificationsPlugin: localNotificationsPlugin
|
||||||
), (route) => false);
|
), (route) => false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import flutter_local_notifications
|
||||||
import path_provider_macos
|
import path_provider_macos
|
||||||
import screen_retriever
|
import screen_retriever
|
||||||
import shared_preferences_macos
|
import shared_preferences_macos
|
||||||
@ -12,6 +13,7 @@ import sqflite
|
|||||||
import window_manager
|
import window_manager
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
|
|||||||
56
pubspec.lock
56
pubspec.lock
@ -1,6 +1,13 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
args:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: args
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.1"
|
||||||
async:
|
async:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -71,6 +78,13 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.5"
|
||||||
|
dbus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dbus
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.8"
|
||||||
easy_debounce:
|
easy_debounce:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -132,6 +146,27 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
|
flutter_local_notifications:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_local_notifications
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "12.0.2"
|
||||||
|
flutter_local_notifications_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_local_notifications_linux
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
|
flutter_local_notifications_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_local_notifications_platform_interface
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.0"
|
||||||
flutter_plugin_android_lifecycle:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -284,6 +319,13 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.3"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.0"
|
||||||
photo_view:
|
photo_view:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -485,6 +527,13 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.12"
|
version: "0.4.12"
|
||||||
|
timezone:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: timezone
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.0"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -520,6 +569,13 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0+2"
|
version: "0.2.0+2"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.18.2 <3.0.0"
|
dart: ">=2.18.2 <3.0.0"
|
||||||
flutter: ">=3.3.0-0"
|
flutter: ">=3.3.0-0"
|
||||||
|
|||||||
@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 2.2.0
|
version: 3.0.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.18.2 <3.0.0'
|
sdk: '>=2.18.2 <3.0.0'
|
||||||
@ -60,6 +60,7 @@ dependencies:
|
|||||||
window_manager: ^0.2.7
|
window_manager: ^0.2.7
|
||||||
# easy_image_viewer: ^1.1.0
|
# easy_image_viewer: ^1.1.0
|
||||||
photo_view: ^0.14.0
|
photo_view: ^0.14.0
|
||||||
|
flutter_local_notifications: ^12.0.2
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user