mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:08:40 +00:00
local push notification
This commit is contained in:
parent
ee2dcd788a
commit
fb26379201
7 changed files with 196 additions and 73 deletions
|
|
@ -6,12 +6,10 @@ Don't be lonely, get twonly! Send pictures to a friend in real time and be sure
|
||||||
## TODOS bevor first beta
|
## TODOS bevor first beta
|
||||||
- Send a picture first to only one person -> Kamera button
|
- Send a picture first to only one person -> Kamera button
|
||||||
- Context Menu
|
- Context Menu
|
||||||
|
- Invitation codes
|
||||||
- Pro Invitation codes
|
|
||||||
- Push Notification (Android)
|
|
||||||
- Settings
|
- Settings
|
||||||
- Notification
|
|
||||||
- Real deployment aufsetzen, direkt auf Netcup?
|
- Real deployment aufsetzen, direkt auf Netcup?
|
||||||
|
- Firebase Push Notification
|
||||||
- MediaView:
|
- MediaView:
|
||||||
- Bei weiteren geladenen Bildern -> Direkt anzeigen ohne pop
|
- Bei weiteren geladenen Bildern -> Direkt anzeigen ohne pop
|
||||||
|
|
||||||
|
|
@ -21,6 +19,7 @@ Don't be lonely, get twonly! Send pictures to a friend in real time and be sure
|
||||||
## TODOS bevor first release
|
## TODOS bevor first release
|
||||||
- Settings
|
- Settings
|
||||||
- Subscription
|
- Subscription
|
||||||
|
- Notification
|
||||||
- Webpage
|
- Webpage
|
||||||
- Instagam & Marketing vorbereiten
|
- Instagam & Marketing vorbereiten
|
||||||
- IT-Startup der TU Darmstadt anschreiben
|
- IT-Startup der TU Darmstadt anschreiben
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class MyApp extends StatefulWidget {
|
||||||
State<MyApp> createState() => _MyAppState();
|
State<MyApp> createState() => _MyAppState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||||
Future<bool> _isUserCreated = isUserCreated();
|
Future<bool> _isUserCreated = isUserCreated();
|
||||||
bool _showOnboarding = true;
|
bool _showOnboarding = true;
|
||||||
bool _isConnected = false;
|
bool _isConnected = false;
|
||||||
|
|
@ -44,6 +44,7 @@ class _MyAppState extends State<MyApp> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addObserver(this);
|
||||||
_startColorAnimation();
|
_startColorAnimation();
|
||||||
|
|
||||||
// init change provider to load data from the database
|
// init change provider to load data from the database
|
||||||
|
|
@ -73,8 +74,18 @@ class _MyAppState extends State<MyApp> {
|
||||||
apiProvider.connect();
|
apiProvider.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
|
super.didChangeAppLifecycleState(state);
|
||||||
|
print("STATE: $state");
|
||||||
|
if (state == AppLifecycleState.resumed) {
|
||||||
|
apiProvider.connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
// disable globalCallbacks to the flutter tree
|
// disable globalCallbacks to the flutter tree
|
||||||
globalCallbackConnectionState = (a) {};
|
globalCallbackConnectionState = (a) {};
|
||||||
globalCallBackOnDownloadChange = (a, b) {};
|
globalCallBackOnDownloadChange = (a, b) {};
|
||||||
|
|
@ -143,29 +154,30 @@ class _MyAppState extends State<MyApp> {
|
||||||
home: Stack(
|
home: Stack(
|
||||||
children: [
|
children: [
|
||||||
FutureBuilder<bool>(
|
FutureBuilder<bool>(
|
||||||
future: _isUserCreated,
|
future: _isUserCreated,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
return snapshot.data!
|
return snapshot.data!
|
||||||
? HomeView()
|
? HomeView()
|
||||||
: _showOnboarding
|
: _showOnboarding
|
||||||
? OnboardingView(
|
? OnboardingView(
|
||||||
callbackOnSuccess: () {
|
callbackOnSuccess: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_showOnboarding = false;
|
_showOnboarding = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: RegisterView(
|
: RegisterView(
|
||||||
callbackOnSuccess: () {
|
callbackOnSuccess: () {
|
||||||
_isUserCreated = isUserCreated();
|
_isUserCreated = isUserCreated();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
if (!_isConnected)
|
if (!_isConnected)
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 3, // Position it at the top
|
top: 3, // Position it at the top
|
||||||
|
|
@ -178,7 +190,8 @@ class _MyAppState extends State<MyApp> {
|
||||||
color: Colors.red[600]!.withAlpha(redColorOpacity),
|
color: Colors.red[600]!.withAlpha(redColorOpacity),
|
||||||
width: 2.0), // Red border
|
width: 2.0), // Red border
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(
|
||||||
Radius.circular(10.0)), // Rounded top corners
|
Radius.circular(10.0),
|
||||||
|
), // Rounded top corners
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,53 @@ class DbContacts extends CvModelBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<Contact> _parseContacts(List<dynamic> users) {
|
||||||
|
List<Contact> parsedUsers = [];
|
||||||
|
for (int i = 0; i < users.length; i++) {
|
||||||
|
try {
|
||||||
|
int userId = users.cast()[i][columnUserId];
|
||||||
|
parsedUsers.add(
|
||||||
|
Contact(
|
||||||
|
userId: Int64(userId),
|
||||||
|
totalMediaCounter: users.cast()[i][columnTotalMediaCounter],
|
||||||
|
displayName: users.cast()[i][columnDisplayName],
|
||||||
|
accepted: users[i][columnAccepted] == 1,
|
||||||
|
blocked: users[i][columnBlocked] == 1,
|
||||||
|
verified: users[i][columnVerified] == 1,
|
||||||
|
requested: users[i][columnRequested] == 1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
Logger("contacts_model/parse_single_user").shout("$e");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parsedUsers;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Contact?> getUserById(int userId) async {
|
||||||
|
try {
|
||||||
|
var user = await dbProvider.db!.query(tableName,
|
||||||
|
columns: [
|
||||||
|
columnUserId,
|
||||||
|
columnDisplayName,
|
||||||
|
columnAccepted,
|
||||||
|
columnRequested,
|
||||||
|
columnBlocked,
|
||||||
|
columnVerified,
|
||||||
|
columnTotalMediaCounter,
|
||||||
|
columnCreatedAt
|
||||||
|
],
|
||||||
|
where: "$columnUserId = ?",
|
||||||
|
whereArgs: [userId]);
|
||||||
|
if (user.isEmpty) return null;
|
||||||
|
return _parseContacts(user)[0];
|
||||||
|
} catch (e) {
|
||||||
|
Logger("contacts_model/getUserById").shout("$e");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Future<List<Contact>> _getAllUsers() async {
|
static Future<List<Contact>> _getAllUsers() async {
|
||||||
try {
|
try {
|
||||||
var users = await dbProvider.db!.query(tableName, columns: [
|
var users = await dbProvider.db!.query(tableName, columns: [
|
||||||
|
|
@ -130,23 +177,7 @@ class DbContacts extends CvModelBase {
|
||||||
columnCreatedAt
|
columnCreatedAt
|
||||||
]);
|
]);
|
||||||
if (users.isEmpty) return [];
|
if (users.isEmpty) return [];
|
||||||
|
return _parseContacts(users);
|
||||||
List<Contact> parsedUsers = [];
|
|
||||||
for (int i = 0; i < users.length; i++) {
|
|
||||||
int userId = users.cast()[i][columnUserId];
|
|
||||||
parsedUsers.add(
|
|
||||||
Contact(
|
|
||||||
userId: Int64(userId),
|
|
||||||
totalMediaCounter: users.cast()[i][columnTotalMediaCounter],
|
|
||||||
displayName: users.cast()[i][columnDisplayName],
|
|
||||||
accepted: users[i][columnAccepted] == 1,
|
|
||||||
blocked: users[i][columnBlocked] == 1,
|
|
||||||
verified: users[i][columnVerified] == 1,
|
|
||||||
requested: users[i][columnRequested] == 1,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return parsedUsers;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger("contacts_model/getUsers").shout("$e");
|
Logger("contacts_model/getUsers").shout("$e");
|
||||||
return [];
|
return [];
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import 'package:twonly/src/proto/api/server_to_client.pb.dart' as server;
|
||||||
import 'package:twonly/src/proto/api/server_to_client.pbserver.dart';
|
import 'package:twonly/src/proto/api/server_to_client.pbserver.dart';
|
||||||
import 'package:twonly/src/providers/api/api.dart';
|
import 'package:twonly/src/providers/api/api.dart';
|
||||||
import 'package:twonly/src/providers/api/api_utils.dart';
|
import 'package:twonly/src/providers/api/api_utils.dart';
|
||||||
|
import 'package:twonly/src/services/notification_service.dart';
|
||||||
// ignore: library_prefixes
|
// ignore: library_prefixes
|
||||||
import 'package:twonly/src/utils/signal.dart' as SignalHelper;
|
import 'package:twonly/src/utils/signal.dart' as SignalHelper;
|
||||||
|
|
||||||
|
|
@ -103,6 +104,7 @@ Future<client.Response> handleNewMessage(
|
||||||
Uint8List name = username.value.userdata.username;
|
Uint8List name = username.value.userdata.username;
|
||||||
DbContacts.insertNewContact(
|
DbContacts.insertNewContact(
|
||||||
utf8.decode(name), fromUserId.toInt(), true);
|
utf8.decode(name), fromUserId.toInt(), true);
|
||||||
|
localPushNotificationNewMessage(fromUserId.toInt(), message, 999999);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MessageKind.opened:
|
case MessageKind.opened:
|
||||||
|
|
@ -117,6 +119,7 @@ Future<client.Response> handleNewMessage(
|
||||||
break;
|
break;
|
||||||
case MessageKind.acceptRequest:
|
case MessageKind.acceptRequest:
|
||||||
DbContacts.acceptUser(fromUserId.toInt());
|
DbContacts.acceptUser(fromUserId.toInt());
|
||||||
|
localPushNotificationNewMessage(fromUserId.toInt(), message, 8888888);
|
||||||
break;
|
break;
|
||||||
case MessageKind.ack:
|
case MessageKind.ack:
|
||||||
DbMessages.acknowledgeMessageByUser(
|
DbMessages.acknowledgeMessageByUser(
|
||||||
|
|
@ -164,6 +167,8 @@ Future<client.Response> handleNewMessage(
|
||||||
tryDownloadMedia(downloadToken);
|
tryDownloadMedia(downloadToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
localPushNotificationNewMessage(
|
||||||
|
fromUserId.toInt(), message, messageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
class ApiProvider {
|
class ApiProvider {
|
||||||
final String apiUrl;
|
final String apiUrl;
|
||||||
final String? backupApiUrl;
|
final String? backupApiUrl;
|
||||||
|
bool isAuthenticated = false;
|
||||||
ApiProvider({required this.apiUrl, required this.backupApiUrl});
|
ApiProvider({required this.apiUrl, required this.backupApiUrl});
|
||||||
|
|
||||||
final log = Logger("ApiProvider");
|
final log = Logger("ApiProvider");
|
||||||
|
|
@ -72,13 +73,13 @@ class ApiProvider {
|
||||||
|
|
||||||
log.info("Trying to connect to the backend $apiUrl!");
|
log.info("Trying to connect to the backend $apiUrl!");
|
||||||
if (await _connectTo(apiUrl)) {
|
if (await _connectTo(apiUrl)) {
|
||||||
onConnected();
|
await onConnected();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (backupApiUrl != null) {
|
if (backupApiUrl != null) {
|
||||||
log.info("Trying to connect to the backup backend $backupApiUrl!");
|
log.info("Trying to connect to the backup backend $backupApiUrl!");
|
||||||
if (await _connectTo(backupApiUrl!)) {
|
if (await _connectTo(backupApiUrl!)) {
|
||||||
onConnected();
|
await onConnected();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -90,12 +91,14 @@ class ApiProvider {
|
||||||
void _onDone() {
|
void _onDone() {
|
||||||
globalCallbackConnectionState(false);
|
globalCallbackConnectionState(false);
|
||||||
_channel = null;
|
_channel = null;
|
||||||
|
isAuthenticated = false;
|
||||||
tryToReconnect();
|
tryToReconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onError(dynamic e) {
|
void _onError(dynamic e) {
|
||||||
globalCallbackConnectionState(false);
|
globalCallbackConnectionState(false);
|
||||||
_channel = null;
|
_channel = null;
|
||||||
|
isAuthenticated = false;
|
||||||
tryToReconnect();
|
tryToReconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,12 +158,16 @@ class ApiProvider {
|
||||||
_channel!.sink.add(response.writeToBuffer());
|
_channel!.sink.add(response.writeToBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Result> _sendRequestV0(ClientToServer request) async {
|
Future<Result> _sendRequestV0(ClientToServer request,
|
||||||
|
{bool authenticated = true}) async {
|
||||||
if (_channel == null) {
|
if (_channel == null) {
|
||||||
if (!await connect()) {
|
if (!await connect()) {
|
||||||
return Result.error(ErrorCode.InternalError);
|
return Result.error(ErrorCode.InternalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (authenticated) {
|
||||||
|
await authenticate();
|
||||||
|
}
|
||||||
var seq = Int64(Random().nextInt(4294967296));
|
var seq = Int64(Random().nextInt(4294967296));
|
||||||
while (messagesV0.containsKey(seq)) {
|
while (messagesV0.containsKey(seq)) {
|
||||||
seq = Int64(Random().nextInt(4294967296));
|
seq = Int64(Random().nextInt(4294967296));
|
||||||
|
|
@ -175,6 +182,7 @@ class ApiProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future authenticate() async {
|
Future authenticate() async {
|
||||||
|
if (isAuthenticated) return;
|
||||||
if (await SignalHelper.getSignalIdentity() == null) {
|
if (await SignalHelper.getSignalIdentity() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +190,7 @@ class ApiProvider {
|
||||||
var handshake = Handshake()..getchallenge = Handshake_GetChallenge();
|
var handshake = Handshake()..getchallenge = Handshake_GetChallenge();
|
||||||
var req = createClientToServerFromHandshake(handshake);
|
var req = createClientToServerFromHandshake(handshake);
|
||||||
|
|
||||||
final result = await _sendRequestV0(req);
|
final result = await _sendRequestV0(req, authenticated: false);
|
||||||
if (result.isError) {
|
if (result.isError) {
|
||||||
log.shout("Error auth", result);
|
log.shout("Error auth", result);
|
||||||
return;
|
return;
|
||||||
|
|
@ -206,13 +214,14 @@ class ApiProvider {
|
||||||
|
|
||||||
var req2 = createClientToServerFromHandshake(opensession);
|
var req2 = createClientToServerFromHandshake(opensession);
|
||||||
|
|
||||||
final result2 = await _sendRequestV0(req2);
|
final result2 = await _sendRequestV0(req2, authenticated: false);
|
||||||
if (result2.isError) {
|
if (result2.isError) {
|
||||||
log.shout("send request failed: ${result2.error}");
|
log.shout("send request failed: ${result2.error}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Authenticated!");
|
log.info("Authenticated!");
|
||||||
|
isAuthenticated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Result> register(String username, String? inviteCode) async {
|
Future<Result> register(String username, String? inviteCode) async {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:twonly/src/model/contacts_model.dart';
|
||||||
|
import 'package:twonly/src/model/json/message.dart' as my;
|
||||||
|
|
||||||
/// Streams are created so that app can respond to notification-related events
|
/// Streams are created so that app can respond to notification-related events
|
||||||
/// since the plugin is initialized in the `main` function
|
/// since the plugin is initialized in the `main` function
|
||||||
|
|
@ -130,3 +134,86 @@ Future<void> setupPushNotification() async {
|
||||||
onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
|
onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getPushNotificationText(String key, String userName) {
|
||||||
|
String systemLanguage = Platform.localeName;
|
||||||
|
|
||||||
|
Map<String, String> pushNotificationText;
|
||||||
|
|
||||||
|
if (systemLanguage.contains("de")) {
|
||||||
|
pushNotificationText = {
|
||||||
|
"newTextMessage": "%userName% hat die eine Nachricht gesendet.",
|
||||||
|
"newTwonly": "%userName% hat dir einen twonly gesendet.",
|
||||||
|
"newVideo": "%userName% hat die eine Video gesendet.",
|
||||||
|
"newImage": "%userName% hat die eine Bild gesendet.",
|
||||||
|
"contactRequest": "%userName% möchte sich mir dir vernetzen.",
|
||||||
|
"acceptRequest": "%userName% ist jetzt mit dir vernetzt.",
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
pushNotificationText = {
|
||||||
|
"newTextMessage": "%userName% has sent you a message.",
|
||||||
|
"newTwonly": "%userName% has sent you a twonly.",
|
||||||
|
"newVideo": "%userName% has sent you a video.",
|
||||||
|
"newImage": "%userName% has sent you an image.",
|
||||||
|
"contactRequest": "%userName% wants to connect with you.",
|
||||||
|
"acceptRequest": "%userName% is now connected with you.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace %userName% with the actual user name
|
||||||
|
return pushNotificationText[key]?.replaceAll("%userName%", userName) ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Future localPushNotificationNewMessage(
|
||||||
|
int fromUserId, my.Message message, int messageId) async {
|
||||||
|
Contact? user = await DbContacts.getUserById(fromUserId);
|
||||||
|
if (user == null) return;
|
||||||
|
|
||||||
|
String msg = "";
|
||||||
|
|
||||||
|
final content = message.content;
|
||||||
|
|
||||||
|
if (content is my.TextMessageContent) {
|
||||||
|
msg = getPushNotificationText("newTextMessage", user.displayName);
|
||||||
|
} else if (content is my.MediaMessageContent) {
|
||||||
|
if (content.isRealTwonly) {
|
||||||
|
msg = getPushNotificationText("newTwonly", user.displayName);
|
||||||
|
} else if (content.isVideo) {
|
||||||
|
msg = getPushNotificationText("newVideo", user.displayName);
|
||||||
|
} else {
|
||||||
|
msg = getPushNotificationText("newImage", user.displayName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.kind == my.MessageKind.contactRequest) {
|
||||||
|
msg = getPushNotificationText("contactRequest", user.displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.kind == my.MessageKind.acceptRequest) {
|
||||||
|
msg = getPushNotificationText("acceptRequest", user.displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg == "") {
|
||||||
|
Logger("localPushNotificationNewMessage")
|
||||||
|
.shout("No push notification type defined!");
|
||||||
|
}
|
||||||
|
|
||||||
|
const AndroidNotificationDetails androidNotificationDetails =
|
||||||
|
AndroidNotificationDetails(
|
||||||
|
'0',
|
||||||
|
'Messages',
|
||||||
|
channelDescription: 'Messages from other users.',
|
||||||
|
importance: Importance.max,
|
||||||
|
priority: Priority.max,
|
||||||
|
ticker: 'You got a new message.',
|
||||||
|
);
|
||||||
|
const NotificationDetails notificationDetails =
|
||||||
|
NotificationDetails(android: androidNotificationDetails);
|
||||||
|
await flutterLocalNotificationsPlugin.show(
|
||||||
|
messageId,
|
||||||
|
user.displayName,
|
||||||
|
msg,
|
||||||
|
notificationDetails,
|
||||||
|
// payload: 'test',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:twonly/src/components/better_list_title.dart';
|
import 'package:twonly/src/components/better_list_title.dart';
|
||||||
import 'package:twonly/src/components/initialsavatar.dart';
|
import 'package:twonly/src/components/initialsavatar.dart';
|
||||||
import 'package:twonly/src/model/json/user_data.dart';
|
import 'package:twonly/src/model/json/user_data.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:twonly/src/services/notification_service.dart';
|
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/utils/storage.dart';
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
import 'package:twonly/src/views/settings/account_view.dart';
|
import 'package:twonly/src/views/settings/account_view.dart';
|
||||||
|
|
@ -119,26 +117,7 @@ class _ProfileViewState extends State<ProfileView> {
|
||||||
BetterListTile(
|
BetterListTile(
|
||||||
icon: FontAwesomeIcons.bell,
|
icon: FontAwesomeIcons.bell,
|
||||||
text: context.lang.settingsNotification,
|
text: context.lang.settingsNotification,
|
||||||
onTap: () async {
|
onTap: () async {},
|
||||||
const AndroidNotificationDetails
|
|
||||||
androidNotificationDetails = AndroidNotificationDetails(
|
|
||||||
'0',
|
|
||||||
'Messages',
|
|
||||||
channelDescription: 'Messages from other users.',
|
|
||||||
importance: Importance.max,
|
|
||||||
priority: Priority.max,
|
|
||||||
ticker: 'You got a new message.',
|
|
||||||
);
|
|
||||||
const NotificationDetails notificationDetails =
|
|
||||||
NotificationDetails(
|
|
||||||
android: androidNotificationDetails);
|
|
||||||
await flutterLocalNotificationsPlugin.show(
|
|
||||||
0,
|
|
||||||
'New message from x',
|
|
||||||
'You got a new message from XX',
|
|
||||||
notificationDetails,
|
|
||||||
payload: 'test');
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
BetterListTile(
|
BetterListTile(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue