Skip to content

Commit

Permalink
Merge pull request #41 from Crequency/dev=cranyozen
Browse files Browse the repository at this point in the history
[Pull Request] Simple notification service
  • Loading branch information
Dynesshely authored Mar 31, 2024
2 parents 964ed37 + 26d34d1 commit dd6c307
Show file tree
Hide file tree
Showing 18 changed files with 346 additions and 165 deletions.
1 change: 1 addition & 0 deletions kitx_mobile/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,5 @@
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</manifest>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions kitx_mobile/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}

dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:gradle:7.3.0'
}
}

allprojects {
repositories {
google()
Expand Down
19 changes: 13 additions & 6 deletions kitx_mobile/lib/instances.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:kitx_mobile/data/local_device_info.dart';
import 'package:kitx_mobile/data/local_network_info.dart';
import 'package:kitx_mobile/services/devices_discovery_service.dart';
import 'package:kitx_mobile/services/devices_service.dart';
import 'package:kitx_mobile/services/notification.dart';
import 'package:kitx_mobile/utils/config.dart';
import 'package:kitx_mobile/utils/handlers/tasks/delayed_task.dart';
import 'package:kitx_mobile/utils/handlers/url_handler.dart';
Expand Down Expand Up @@ -53,6 +54,9 @@ class Instances {
/// Instance for [DeviceService] class
var devicesService = DeviceService();

/// Instance for [NotificationService] class
var notificationService = NotificationService();

/// Is in debug mode
var isDebugMode = kDebugMode.obs;

Expand All @@ -62,19 +66,22 @@ class Instances {
deviceInfo = await LocalDeviceInfo.get();
networkInfo = await LocalNetworkInfo.get();

// Init WebService
await devicesDiscoveryService.init();

// Init DeviceService
await devicesService.init();

// Init NotificationService
await notificationService.initAsync();

connectivity.onConnectivityChanged.listen(
(result) async {
instances.deviceInfo = await LocalDeviceInfo.get();
instances.networkInfo = await LocalNetworkInfo.get();
restartDevicesServer();
},
);

// Init WebService
await devicesDiscoveryService.init();

// Init DeviceService
await devicesService.init();
}

/// Restart [devicesService] and [devicesDiscoveryService]
Expand Down
2 changes: 1 addition & 1 deletion kitx_mobile/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:kitx_mobile/pages/pages.dart';
import 'package:kitx_mobile/utils/config.dart';
import 'package:kitx_mobile/utils/log.dart';
import 'package:kitx_mobile/utils/themes/themes.dart';
import 'package:kitx_mobile/utils/translation.dart';
import 'package:kitx_mobile/utils/translation/translation.dart';

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
Expand Down
51 changes: 28 additions & 23 deletions kitx_mobile/lib/pages/about_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -203,29 +203,34 @@ class _AboutPageState extends State<AboutPage> {
).createShader(rect);
},
blendMode: BlendMode.dstOut,
child: ListView(shrinkWrap: true, scrollDirection: Axis.horizontal, physics: BouncingScrollPhysics(), children: [
GraduallySmallerSpacer(duration: 1200, width: contentEntering ? 15 : 800),
const ContributorChip(
name: 'Dynesshely',
url: 'https://github.com/Dynesshely',
),
const SizedBox(width: 10),
const ContributorChip(
name: 'Cranyozen',
url: 'https://github.com/Cranyozen',
),
const SizedBox(width: 10),
const ContributorChip(
name: 'orzMaster',
url: 'https://github.com/orzMaster',
),
const SizedBox(width: 10),
const ContributorChip(
name: 'Cronyet',
url: 'https://github.com/Cronyet',
),
const SizedBox(width: 15),
]),
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
children: [
GraduallySmallerSpacer(duration: 1200, width: contentEntering ? 15 : 800),
const ContributorChip(
name: 'Dynesshely',
url: 'https://github.com/Dynesshely',
),
const SizedBox(width: 10),
const ContributorChip(
name: 'Cranyozen',
url: 'https://github.com/Cranyozen',
),
const SizedBox(width: 10),
const ContributorChip(
name: 'orzMaster',
url: 'https://github.com/orzMaster',
),
const SizedBox(width: 10),
const ContributorChip(
name: 'Cronyet',
url: 'https://github.com/Cronyet',
),
const SizedBox(width: 15),
],
),
),
),
),
Expand Down
2 changes: 1 addition & 1 deletion kitx_mobile/lib/pages/controls/device_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class _DeviceCard extends State<DeviceCard> with TickerProviderStateMixin {
padding: EdgeInsets.only(bottom: width == null ? 20 : 8),
child: badges.Badge(
badgeContent: Text(
'DevicesPage_PluginsCountText'.tr.replaceAll('%count%', (info.pluginsCount).toString()),
'DevicesPage_PluginsCountText'.trParams({'count': info.pluginsCount.toString()}),
style: const TextStyle(color: Colors.white),
),
position: badges.BadgePosition.topEnd(top: 70, end: 15),
Expand Down
4 changes: 1 addition & 3 deletions kitx_mobile/lib/services/devices_discovery_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ class DevicesDiscoveryService implements Service {
socket.broadcastEnabled = true;
socket.joinMulticast(InternetAddress(_udpBroadcastAddress));

Timer.periodic(Duration(seconds: config.webServiceUdpSendFrequency), (timer) {
sendTimer = timer;

sendTimer = Timer.periodic(Duration(seconds: config.webServiceUdpSendFrequency), (timer) {
try {
deviceInfo = deviceInfo.rebuild(
(b) => b
Expand Down
6 changes: 6 additions & 0 deletions kitx_mobile/lib/services/devices_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ class DeviceService implements Service {
}

deviceInfoList.refresh();

// Update notification service.
instances.notificationService.updateStatusNotification(
deviceCount: deviceInfoList.length,
serviceStatus: serviceStatus.value,
);
});

serviceStatus.value = ServiceStatus.running;
Expand Down
96 changes: 96 additions & 0 deletions kitx_mobile/lib/services/notification.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import 'dart:io';

import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:kitx_mobile/services/public/service_status.dart';
import 'package:kitx_mobile/utils/extensions/service_status_to_string.dart';
import 'package:kitx_mobile/instances.dart';
// import 'package:flutter/material.dart';

/// [NotificationService] class
class NotificationService {
/// Status notification id
var statusNotificationId = 10;

/// Status channel key
var statusChannelKey = "status_channel";

/// Initialize the notification service
Future<void> initAsync() async {
// TODO: Adapt to iOS
AwesomeNotifications().initialize(
'resource://drawable/app_icon',
[
// KitX status channel
NotificationChannel(
channelKey: statusChannelKey,
channelName: 'KitX Status Notifications',
channelDescription: 'KitX status',
locked: true, // Prevents the user from deleting the channel
playSound: false, // Do NOT play sound when the notification is displayed
enableVibration: false, // Do NOT vibrate when the notification is displayed
onlyAlertOnce: true, // Only alert once
// defaultColor: Color(0xFF9D50DD),
// ledColor: Colors.white,
),
],
);
AwesomeNotifications().setListeners(onActionReceivedMethod: onActionReceivedMethod);
}

/// On action received method
@pragma('vm:entry-point')
static Future<void> onActionReceivedMethod(ReceivedAction receivedAction) async {
var key = receivedAction.buttonKeyPressed;
if (key == 'action_view_button') {
if (instances.devicesService.serviceStatus == ServiceStatus.running) {
// Stop service
instances.shutdownDevicesServer();
} else {
// Start service
instances.restartDevicesServer();
}
} else if (key == 'action_view_exit') {
// Exit app
instances.shutdownDevicesServer();

// Delete all notifications
AwesomeNotifications().cancelAll();

await SystemNavigator.pop(); // Probably not working on iOS (by Copilot)
exit(0);
}
}

/// Update status notification
Future<void> updateStatusNotification({
required int deviceCount,
required ServiceStatus serviceStatus,
}) async {
AwesomeNotifications().createNotification(
content: NotificationContent(
id: statusNotificationId,
channelKey: statusChannelKey,
title: 'NotificationService_StatusNotificationTitle'.trParams({"status": serviceStatus.toText()}),
body: 'NotificationService_StatusNotificationBody'.trParams({'device_count': deviceCount.toString()}),
locked: true,
autoDismissible: false,
category: NotificationCategory.Status,
),
actionButtons: [
NotificationActionButton(
key: 'action_view_button',
label: (serviceStatus == ServiceStatus.running) ? 'Public_Stop'.tr : 'Public_Launch'.tr,
actionType: ActionType.KeepOnTop,
autoDismissible: false,
),
NotificationActionButton(
key: 'action_view_exit',
label: 'Public_Quit'.tr,
actionType: ActionType.SilentAction,
autoDismissible: false,
),
]);
}
}
23 changes: 23 additions & 0 deletions kitx_mobile/lib/utils/extensions/service_status_to_string.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'package:get/get.dart';
import 'package:kitx_mobile/services/public/service_status.dart';

/// [ServiceStatus] Extensions
extension ServiceStatusExtensions on ServiceStatus {
/// Convert [ServiceStatus] to [String]
String toText() {
switch (this) {
case ServiceStatus.error:
return 'Public_Error'.tr;
case ServiceStatus.starting:
return 'Public_Launching'.tr;
case ServiceStatus.stopping:
return 'Public_Stopping'.tr;
case ServiceStatus.running:
return 'Public_Running'.tr;
case ServiceStatus.pending:
return 'Public_Pending'.tr;
default:
return 'Unknown';
}
}
}
7 changes: 6 additions & 1 deletion kitx_mobile/lib/utils/log.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:f_logs/model/flog/flog_config.dart';
import 'package:f_logs/model/flog/log_level.dart';
import 'package:f_logs/utils/formatter/formate_type.dart';
import 'package:f_logs/utils/timestamp/timestamp_format.dart';
import 'package:stack_trace/stack_trace.dart';

var _config = LogsConfig()
..isDebuggable = true
Expand All @@ -26,7 +27,11 @@ class Log {
void info(String message) => FLog.info(text: message);

/// Log a message at level [LogLevel.ERROR].
void error(String message) => FLog.error(text: message);
void error(String message) {
var trace = Trace.current().frames;
var filteredTrace = trace.where((frame) => !frame.library.contains('package:kitx_mobile/utils/log.dart'));
FLog.error(text: message, stacktrace: Trace(filteredTrace));
}

/// Log a message at level [LogLevel.WARNING].
void warning(String message) => FLog.warning(text: message);
Expand Down
Loading

0 comments on commit dd6c307

Please sign in to comment.