Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enh: Grant Statuses #44

Open
wants to merge 23 commits into
base: enh/show-push-status
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions Events.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

namespace humhub\modules\fcmPush;


use humhub\components\mail\Message;
use humhub\modules\fcmPush\assets\FcmPushAsset;
use humhub\modules\fcmPush\assets\FirebaseAsset;
use humhub\modules\fcmPush\components\MailerMessage;
use humhub\modules\fcmPush\components\NotificationTargetProvider;
use humhub\modules\notification\widgets\UserInfoWidget;
use humhub\modules\fcmPush\helpers\MobileAppHelper;
use humhub\modules\fcmPush\services\DriverService;
use humhub\modules\fcmPush\widgets\PushNotificationInfoWidget;
Expand Down Expand Up @@ -84,19 +84,10 @@ public static function onServiceWorkerControllerInit($event): void
JS;
}

public static function onNotificationInfoWidget($event)
{
/** @var BaseStack $baseStack */
$baseStack = $event->sender;

$baseStack->addWidget(PushNotificationInfoWidget::class);

}

public static function onLayoutAddonInit($event)
{
if (Yii::$app->session->has(self::SESSION_VAR_LOGOUT)) {
MobileAppHelper::unregisterNotificationScript(); // Before Logout
MobileAppHelper::unregisterNotificationScript();
MobileAppHelper::registerLogoutScript();
Yii::$app->session->remove(self::SESSION_VAR_LOGOUT);
}
Expand All @@ -123,6 +114,14 @@ public static function onLayoutAddonInit($event)

}

public static function onInitUserInfoWidget($event)
{
/* @var UserInfoWidget $widget */
$widget = $event->sender;

$widget->addWidget(widgets\PushNotificationInfoWidget::class);
}

public static function onAfterLogout()
{
Yii::$app->session->set(self::SESSION_VAR_LOGOUT, 1);
Expand All @@ -144,7 +143,6 @@ public static function onAuthChoiceBeforeRun(Event $event) {
$sender->setClients([]);
}


}

}
6 changes: 2 additions & 4 deletions assets/FcmPushAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

namespace humhub\modules\fcmPush\assets;

use humhub\modules\fcmPush\Module;
use humhub\modules\fcmPush\services\DriverService;
use Yii;
use yii\helpers\Url;
use yii\web\AssetBundle;
use humhub\modules\fcmPush\Module;
use humhub\modules\fcmPush\services\DriverService;

class FcmPushAsset extends AssetBundle
{
Expand Down Expand Up @@ -36,7 +36,5 @@ public static function register($view)

return parent::register($view);
}


}
}
6 changes: 2 additions & 4 deletions config.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
<?php


/** @noinspection MissedFieldInspection */

use humhub\modules\fcmPush\Events;
use humhub\components\Controller;

//use humhub\modules\notification\widgets\NotificationInfoWidget;
use humhub\modules\user\widgets\AuthChoice;
use humhub\widgets\LayoutAddons;
use yii\base\Application;
use humhub\modules\user\components\User;
use humhub\modules\notification\widgets\UserInfoWidget;

return [
'id' => 'fcm-push',
Expand All @@ -24,7 +22,7 @@
[User::class, User::EVENT_AFTER_LOGOUT, [Events::class, 'onAfterLogout']],
[User::class, User::EVENT_AFTER_LOGIN, [Events::class, 'onAfterLogin']],
[AuthChoice::class, AuthChoice::EVENT_BEFORE_RUN, [Events::class, 'onAuthChoiceBeforeRun']],
//[NotificationInfoWidget::class, \humhub\widgets\BaseStack::EVENT_RUN, [Events::class, 'onNotificationInfoWidget']]
[UserInfoWidget::class, UserInfoWidget::EVENT_INIT, [Events::class, 'onInitUserInfoWidget']],
],
'consoleControllerMap' => [
'firebase' => 'humhub\modules\fcmPush\commands\SendController',
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog
2.0.4 (Unreleased)
---------------------
- Fix #41: Fix go service for multiline links
- Enh #24: Notification Grant Status

2.0.3 (June 24, 2024)
---------------------
Expand Down
110 changes: 91 additions & 19 deletions resources/js/humhub.firebase.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
/**
* @fileoverview HumHub Firebase Module
* This module handles Firebase Cloud Messaging (FCM) integration for HumHub.
* It manages notification permissions, token handling, and message reception.
* @module firebase
*/

humhub.module('firebase', function (module, require, $) {
let messaging;

/**
* Initializes the Firebase module.
* Sets up the Firebase app and messaging, and defines behavior for message reception and token refresh.
* @function
*/
const init = function () {
if (!firebase.apps.length) {
firebase.initializeApp({messagingSenderId: this.senderId()});
firebase.initializeApp({ messagingSenderId: this.senderId() });
this.messaging = firebase.messaging();

this.messaging.onMessage(function (payload) {
module.log.info("Received FCM Push Notification", payload);
});

// Callback fired if Instance ID token is updated.
this.messaging.onTokenRefresh(function () {
this.messaging.getToken().then(function (refreshedToken) {
this.deleteTokenLocalStore();
Expand All @@ -22,21 +33,49 @@ humhub.module('firebase', function (module, require, $) {
}
};

/**
* Gets the content to display for notification permission status.
* @function
* @returns {string} The message corresponding to the current notification permission status.
*/
const getNotificationPermissionContent = function () {
if (!("Notification" in window)) {
return module.text('status.not-supported');
}
switch (Notification.permission) {
case "granted":
return module.text('status.granted');
case "denied":
return module.text('status.denied');
default:
return module.text('status.default');
}
}

/**
* Adds information about push notification permissions to the UI.
* @function
*/
const addPushNotificationPermissionsInfo = function () {
let content = getNotificationPermissionContent();
$('#pushNotificationPermissionInfo').html(content);
}

/**
* Handles actions after the service worker registration.
* @function
* @param {ServiceWorkerRegistration} registration - The service worker registration object.
*/
const afterServiceWorkerRegistration = function (registration) {
//console.log("After Service Worker Registration");
//console.log(registration);

const that = this;

this.messaging.useServiceWorker(registration);

// Request for permission
this.messaging.requestPermission().then(function () {
//console.log('Notification permission granted.');
addPushNotificationPermissionsInfo('granted');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter here isn't also not longer used?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am also not sure if we need these calls addPushNotificationPermissionsInfo in the afterServiceWorkerRegistration at all.
Because usually the ServiceWorkerRegistration takes place very early, e.g. at login, and the PermissionInfo is not displayed anywhere here. In addition, the registration is only once.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have to look into this more when I have the time to do so. 🤔


that.messaging.getToken().then(function (currentToken) {
if (currentToken) {
//console.log('Token: ' + currentToken);
that.sendTokenToServer(currentToken);
} else {
module.log.info('No Instance ID token available. Request permission to generate one.');
Expand All @@ -48,20 +87,23 @@ humhub.module('firebase', function (module, require, $) {
});
}).catch(function (err) {
module.log.info('Could not get Push Notification permission!', err);
addPushNotificationPermissionsInfo(Notification.permission);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, the parameter is not required right?

});
};

// Send the Instance ID token your application server, so that it can:
// - send messages back to this app
// - subscribe/unsubscribe the token from topics
/**
* Sends the FCM token to the server.
* @function
* @param {string} token - The FCM token.
*/
const sendTokenToServer = function (token) {
const that = this;
if (!that.isTokenSentToServer(token)) {
module.log.info("Send FCM Push Token to Server");
$.ajax({
method: "POST",
url: that.tokenUpdateUrl(),
data: {token: token},
data: { token: token },
success: function (data) {
that.setTokenLocalStore(token);
}
Expand All @@ -71,14 +113,29 @@ humhub.module('firebase', function (module, require, $) {
}
};

/**
* Checks if the token has already been sent to the server.
* @function
* @param {string} token - The FCM token.
* @returns {boolean} Whether the token has been sent to the server.
*/
const isTokenSentToServer = function (token) {
return (this.getTokenLocalStore() === token);
};

/**
* Deletes the locally stored FCM token.
* @function
*/
const deleteTokenLocalStore = function () {
window.localStorage.removeItem('fcmPushToken_' + this.senderId())
};

/**
* Sets the FCM token in local storage.
* @function
* @param {string} token - The FCM token.
*/
const setTokenLocalStore = function (token) {
const item = {
value: token,
Expand All @@ -87,10 +144,14 @@ humhub.module('firebase', function (module, require, $) {
window.localStorage.setItem('fcmPushToken_' + this.senderId(), JSON.stringify(item))
};

/**
* Gets the FCM token from local storage.
* @function
* @returns {string|null} The FCM token or null if it doesn't exist or is expired.
*/
const getTokenLocalStore = function () {
const itemStr = window.localStorage.getItem('fcmPushToken_' + this.senderId())

// if the item doesn't exist, return null
if (!itemStr) {
return null
}
Expand All @@ -103,32 +164,43 @@ humhub.module('firebase', function (module, require, $) {
return item.value;
};

/**
* Gets the URL for updating the token on the server.
* @function
* @returns {string} The token update URL.
*/
const tokenUpdateUrl = function () {
return module.config.tokenUpdateUrl;
};

/**
* Gets the sender ID from the module configuration.
* @function
* @returns {string} The sender ID.
*/
const senderId = function () {
return module.config.senderId;
};

module.export({
init: init,

isTokenSentToServer: isTokenSentToServer,
sendTokenToServer: sendTokenToServer,
afterServiceWorkerRegistration: afterServiceWorkerRegistration,

// Config Vars
senderId: senderId,
tokenUpdateUrl: tokenUpdateUrl,

// LocalStore Helper
setTokenLocalStore: setTokenLocalStore,
getTokenLocalStore: getTokenLocalStore,
deleteTokenLocalStore: deleteTokenLocalStore,
addPushNotificationPermissionsInfo: addPushNotificationPermissionsInfo
});
});

/**
* Handles actions after the service worker registration (global scope).
* @function
* @param {ServiceWorkerRegistration} registration - The service worker registration object.
*/
function afterServiceWorkerRegistration(registration) {
humhub.modules.firebase.afterServiceWorkerRegistration(registration);
}
}
29 changes: 24 additions & 5 deletions widgets/PushNotificationInfoWidget.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
<?php

namespace humhub\modules\fcmPush\widgets;
class PushNotificationInfoWidget extends \humhub\components\Widget
{

use Yii;
use yii\helpers\Url;
use humhub\components\Widget;
use humhub\modules\fcmPush\Module;
use humhub\modules\fcmPush\services\DriverService;

class PushNotificationInfoWidget extends Widget
{
/**
* @inheritdoc
*/
public function run()
{
//return $this->render('push-notification-info');
}
/** @var Module $module */
$module = Yii::$app->getModule('fcm-push');
$pushDriver = (new DriverService($module->getConfigureForm()))->getWebDriver();

if ($pushDriver === null) {
return '';
}

}
return $this->render('push-notification-info', [
'tokenUpdateUrl' => Url::to(['/fcm-push/token/update']),
'senderId' => $pushDriver->getSenderId(),
]);
}
}
Loading