added notifications for mobile

This commit is contained in:
PhilReact 2024-10-31 08:56:21 +02:00
parent 6ed45501f7
commit 77ef45345d
11 changed files with 428 additions and 338 deletions

View File

@ -11,7 +11,9 @@ apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies {
implementation project(':capacitor-browser')
implementation project(':capacitor-filesystem')
implementation project(':capacitor-local-notifications')
implementation project(':evva-capacitor-secure-storage-plugin')
implementation project(':transistorsoft-capacitor-background-fetch')
implementation "androidx.webkit:webkit:1.4.0"
}

View File

@ -8,7 +8,8 @@
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:requestLegacyExternalStorage="true">
android:requestLegacyExternalStorage="true"
android:usesCleartextTraffic="true">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
android:name=".MainActivity"
@ -40,4 +41,5 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
</manifest>

View File

@ -0,0 +1,31 @@
package com.example.app;
import android.content.Context;
import android.util.Log;
import com.transistorsoft.tsbackgroundfetch.BackgroundFetch;
import com.transistorsoft.tsbackgroundfetch.BGTask;
public class BackgroundFetchHeadlessTask{
public void onFetch(Context context, BGTask task) {
// Get a reference to the BackgroundFetch Android API.
BackgroundFetch backgroundFetch = BackgroundFetch.getInstance(context);
// Get the taskId.
String taskId = task.getTaskId();
// Log a message to adb logcat.
Log.d("MyHeadlessTask", "BackgroundFetchHeadlessTask onFetch -- CUSTOM IMPLEMENTATION: " + taskId);
boolean isTimeout = task.getTimedOut();
// Is this a timeout?
if (isTimeout) {
backgroundFetch.finish(taskId);
return;
}
// Do your work here...
//
//
// Signal finish just like the Javascript API.
backgroundFetch.finish(taskId);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -21,6 +21,10 @@ allprojects {
repositories {
google()
mavenCentral()
maven {
// capacitor-background-fetch
url("${project(':transistorsoft-capacitor-background-fetch').projectDir}/libs")
}
}
}

View File

@ -8,5 +8,11 @@ project(':capacitor-browser').projectDir = new File('../node_modules/@capacitor/
include ':capacitor-filesystem'
project(':capacitor-filesystem').projectDir = new File('../node_modules/@capacitor/filesystem/android')
include ':capacitor-local-notifications'
project(':capacitor-local-notifications').projectDir = new File('../node_modules/@capacitor/local-notifications/android')
include ':evva-capacitor-secure-storage-plugin'
project(':evva-capacitor-secure-storage-plugin').projectDir = new File('../node_modules/@evva/capacitor-secure-storage-plugin/android')
include ':transistorsoft-capacitor-background-fetch'
project(':transistorsoft-capacitor-background-fetch').projectDir = new File('../node_modules/@transistorsoft/capacitor-background-fetch/android')

View File

@ -3,7 +3,13 @@ import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'Qortal ',
webDir: 'dist'
webDir: 'dist',
"plugins": {
"LocalNotifications": {
"smallIcon": "qort",
"iconColor": "#09b6e8"
}
}
};
export default config;

18
package-lock.json generated
View File

@ -13,6 +13,7 @@
"@capacitor/cli": "^6.1.2",
"@capacitor/core": "^6.1.2",
"@capacitor/filesystem": "^6.0.1",
"@capacitor/local-notifications": "^6.1.0",
"@chatscope/chat-ui-kit-react": "^2.0.3",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/sortable": "^8.0.0",
@ -35,6 +36,7 @@
"@tiptap/pm": "^2.5.9",
"@tiptap/react": "^2.5.9",
"@tiptap/starter-kit": "^2.5.9",
"@transistorsoft/capacitor-background-fetch": "^6.0.1",
"@types/chrome": "^0.0.263",
"asmcrypto.js": "2.3.2",
"bcryptjs": "2.4.3",
@ -515,6 +517,14 @@
"@capacitor/core": "^6.0.0"
}
},
"node_modules/@capacitor/local-notifications": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@capacitor/local-notifications/-/local-notifications-6.1.0.tgz",
"integrity": "sha512-EjEnbApdFiZYeJgxKIDtgFRNSmeHySnyAeyoTn6HUTYMkTOaHFGAd7NU964k7gbX4al/CBp0cMA8iMG0c7kh1w==",
"peerDependencies": {
"@capacitor/core": "^6.0.0"
}
},
"node_modules/@chatscope/chat-ui-kit-react": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@chatscope/chat-ui-kit-react/-/chat-ui-kit-react-2.0.3.tgz",
@ -3041,6 +3051,14 @@
"url": "https://github.com/sponsors/ueberdosis"
}
},
"node_modules/@transistorsoft/capacitor-background-fetch": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@transistorsoft/capacitor-background-fetch/-/capacitor-background-fetch-6.0.1.tgz",
"integrity": "sha512-/OyQ4IVu1clWsqt0eKYAX8Ynj1X1Asw5HM94HyH1il3jL5lXe6CLmRFqicXDxabYge+ACXfVLim/P2EovQ1IIg==",
"peerDependencies": {
"@capacitor/core": "^6.0.0"
}
},
"node_modules/@types/aria-query": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",

View File

@ -17,6 +17,7 @@
"@capacitor/cli": "^6.1.2",
"@capacitor/core": "^6.1.2",
"@capacitor/filesystem": "^6.0.1",
"@capacitor/local-notifications": "^6.1.0",
"@chatscope/chat-ui-kit-react": "^2.0.3",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/sortable": "^8.0.0",
@ -39,6 +40,7 @@
"@tiptap/pm": "^2.5.9",
"@tiptap/react": "^2.5.9",
"@tiptap/starter-kit": "^2.5.9",
"@transistorsoft/capacitor-background-fetch": "^6.0.1",
"@types/chrome": "^0.0.263",
"asmcrypto.js": "2.3.2",
"bcryptjs": "2.4.3",

View File

@ -695,20 +695,18 @@ function App() {
executeEvent("openDirectMessage", {
from: message.payload.from,
});
} else if (message.action === "NOTIFICATION_OPEN_GROUP" && isMainWindow) {
} else if (message.action === "NOTIFICATION_OPEN_GROUP") {
executeEvent("openGroupMessage", {
from: message.payload.from,
});
} else if (
message.action === "NOTIFICATION_OPEN_ANNOUNCEMENT_GROUP" &&
isMainWindow
message.action === "NOTIFICATION_OPEN_ANNOUNCEMENT_GROUP"
) {
executeEvent("openGroupAnnouncement", {
from: message.payload.from,
});
} else if (
message.action === "NOTIFICATION_OPEN_THREAD_NEW_POST" &&
isMainWindow
message.action === "NOTIFICATION_OPEN_THREAD_NEW_POST"
) {
executeEvent("openThreadNewPost", {
data: message.payload.data,

View File

@ -1,5 +1,5 @@
// @ts-nocheck
// TODO
import "./qortalRequests";
import { isArray } from "lodash";
import {
@ -88,6 +88,16 @@ import {
versionCase,
} from "./background-cases";
import { getData, removeKeysAndLogout, storeData } from "./utils/chromeStorage";
import {BackgroundFetch} from '@transistorsoft/capacitor-background-fetch';
import { LocalNotifications } from '@capacitor/local-notifications';
LocalNotifications.requestPermissions().then(permission => {
if (permission.display === 'granted') {
console.log("Notifications enabled");
}
});
export function cleanUrl(url) {
return url?.replace(/^(https?:\/\/)?(www\.)?/, "");
@ -384,35 +394,21 @@ const handleNotificationDirect = async (directs) => {
(newestLatestTimestamp &&
newestLatestTimestamp?.timestamp > oldestLatestTimestamp?.timestamp)
) {
// const notificationId =
// "chat_notification_" +
// Date.now() +
// "_type=direct" +
// `_from=${newestLatestTimestamp.address}`;
// chrome.notifications.create(notificationId, {
// type: "basic",
// iconUrl: "qort.png", // Add an appropriate icon for chat notifications
// title: `New Direct message! ${
// newestLatestTimestamp?.name && `from ${newestLatestTimestamp.name}`
// }`,
// message: "You have received a new direct message",
// priority: 2, // Use the maximum priority to ensure it's noticeable
// });
// if (!isMobile) {
// setTimeout(() => {
// chrome.notifications.clear(notificationId);
// }, 7000);
// }
// chrome.runtime.sendMessage(
// {
// action: "notification",
// payload: {
// },
// }
// )
// audio.play();
playNotificationSound();
LocalNotifications.schedule({
notifications: [
{
title: `New Direct message! ${
newestLatestTimestamp?.name && `from ${newestLatestTimestamp.name}`
}`,
body: "You have received a new direct message",
id: notificationId,
schedule: { at: new Date(Date.now() + 1000) }, // 1 second from now
}
]
});
}
} catch (error) {
if (!isFocused) {
@ -431,32 +427,21 @@ const handleNotificationDirect = async (directs) => {
});
const notificationId = "chat_notification_" + Date.now();
// chrome.notifications.create(notificationId, {
// type: "basic",
// iconUrl: "qort.png", // Add an appropriate icon for chat notifications
// title: `New Direct message!`,
// message: "You have received a new direct message",
// priority: 2, // Use the maximum priority to ensure it's noticeable
// });
if (!isMobile) {
setTimeout(() => {
chrome.notifications.clear(notificationId);
}, 7000);
}
playNotificationSound();
// audio.play();
// }
LocalNotifications.schedule({
notifications: [
{
title: `New Direct message!`,
body: "You have received a new direct message",
id: notificationId,
schedule: { at: new Date(Date.now() + 1000) }, // 1 second from now
}
]
});
}
} finally {
setChatHeadsDirect(dataDirects);
// chrome.runtime.sendMessage(
// {
// action: "setChatHeads",
// payload: {
// data,
// },
// }
// );
}
};
async function getThreadActivity(): Promise<any | null> {
@ -625,28 +610,21 @@ const handleNotification = async (groups) => {
"_type=group" +
`_from=${newestLatestTimestamp.groupId}`;
// chrome.notifications.create(notificationId, {
// type: "basic",
// iconUrl: "qort.png", // Add an appropriate icon for chat notifications
// title: "New Group Message!",
// message: `You have received a new message from ${newestLatestTimestamp?.groupName}`,
// priority: 2, // Use the maximum priority to ensure it's noticeable
// });
LocalNotifications.schedule({
notifications: [
{
title: "New Group Message!",
body: `You have received a new message from ${newestLatestTimestamp?.groupName}`,
id: notificationId,
schedule: { at: new Date(Date.now() + 1000) }, // 1 second from now
}
]
});
if (!isMobile) {
setTimeout(() => {
chrome.notifications.clear(notificationId);
}, 7000);
}
// chrome.runtime.sendMessage(
// {
// action: "notification",
// payload: {
// },
// }
// )
// audio.play();
playNotificationSound();
lastGroupNotification = Date.now();
}
}
@ -667,277 +645,31 @@ const handleNotification = async (groups) => {
});
const notificationId = "chat_notification_" + Date.now();
// chrome.notifications.create(notificationId, {
// type: "basic",
// iconUrl: "qort.png", // Add an appropriate icon for chat notifications
// title: "New Group Message!",
// message: "You have received a new message from one of your groups",
// priority: 2, // Use the maximum priority to ensure it's noticeable
// });
if (!isMobile) {
setTimeout(() => {
chrome.notifications.clear(notificationId);
}, 7000);
}
playNotificationSound();
// audio.play();
LocalNotifications.schedule({
notifications: [
{
title: "New Group Message!",
body: "You have received a new message from one of your groups",
id: notificationId,
schedule: { at: new Date(Date.now() + 1000) }, // 1 second from now
}
]
});
lastGroupNotification = Date.now();
// }
}
} finally {
if (!data || data?.length === 0) return;
setChatHeads(dataWithUpdates);
// chrome.runtime.sendMessage(
// {
// action: "setChatHeads",
// payload: {
// data,
// },
// }
// );
}
};
export const checkThreads = async (bringBack) => {
try {
let myName = "";
const userData = await getUserInfo();
if (userData?.name) {
myName = userData.name;
}
let newAnnouncements = [];
let dataToBringBack = [];
const threadActivity = await getThreadActivity();
if (!threadActivity) return null;
const selectedThreads = [
...threadActivity.createdThreads.slice(0, 2),
...threadActivity.mostVisitedThreads.slice(0, 2),
...threadActivity.recentThreads.slice(0, 2),
];
if (selectedThreads?.length === 0) return null;
const tempData = {};
for (const thread of selectedThreads) {
try {
const identifier = `thmsg-${thread?.threadId}`;
const name = thread?.qortalName;
const endpoint = await getArbitraryEndpoint();
const url = await createEndpoint(
`${endpoint}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=1&includemetadata=false&offset=${0}&reverse=true&prefix=true`
);
const response = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const responseData = await response.json();
const latestMessage = responseData.filter(
(pub) => pub?.name !== myName
)[0];
// const latestMessage = responseData[0]
if (!latestMessage) {
continue;
}
if (
checkDifference(latestMessage.created) &&
latestMessage.created > thread?.lastVisited &&
(!thread?.lastNotified || thread?.lastNotified < thread?.created)
) {
tempData[thread.threadId] = latestMessage.created;
newAnnouncements.push(thread);
}
if (latestMessage.created > thread?.lastVisited) {
dataToBringBack.push(thread);
}
} catch (error) {
conosle.log({ error });
}
}
if (bringBack) {
return dataToBringBack;
}
const updateThreadWithLastNotified = {
...threadActivity,
createdThreads: (threadActivity?.createdThreads || [])?.map((item) => {
if (tempData[item.threadId]) {
return {
...item,
lastNotified: tempData[item.threadId],
};
} else {
return item;
}
}),
mostVisitedThreads: (threadActivity?.mostVisitedThreads || [])?.map(
(item) => {
if (tempData[item.threadId]) {
return {
...item,
lastNotified: tempData[item.threadId],
};
} else {
return item;
}
}
),
recentThreads: (threadActivity?.recentThreads || [])?.map((item) => {
if (tempData[item.threadId]) {
return {
...item,
lastNotified: tempData[item.threadId],
};
} else {
return item;
}
}),
};
const wallet = await getSaveWallet();
const address = wallet.address0;
storeData(`threadactivity-${address}`, updateThreadWithLastNotified).catch(() => null);
if (newAnnouncements.length > 0) {
const notificationId =
"chat_notification_" +
Date.now() +
"_type=thread-post" +
`_data=${JSON.stringify(newAnnouncements[0])}`;
let isDisableNotifications =
(await getUserSettings({ key: "disable-push-notifications" })) || false;
if (!isDisableNotifications) {
// chrome.notifications.create(notificationId, {
// type: "basic",
// iconUrl: "qort.png", // Add an appropriate icon for chat notifications
// title: `New thread post!`,
// message: `New post in ${newAnnouncements[0]?.thread?.threadData?.title}`,
// priority: 2, // Use the maximum priority to ensure it's noticeable
// });
// if (!isMobile) {
// setTimeout(() => {
// chrome.notifications.clear(notificationId);
// }, 7000);
// }
playNotificationSound();
}
}
const savedtimestampAfter = await getTimestampGroupAnnouncement();
window.postMessage({
action: "SET_GROUP_ANNOUNCEMENTS",
payload: savedtimestampAfter,
}, "*");
} catch (error) {
} finally {
}
};
export const checkNewMessages = async () => {
try {
let mutedGroups = (await getUserSettings({ key: "mutedGroups" })) || [];
if (!isArray(mutedGroups)) mutedGroups = [];
let myName = "";
const userData = await getUserInfo();
if (userData?.name) {
myName = userData.name;
}
let newAnnouncements = [];
const activeData = (await getStoredData("active-groups-directs")) || {
groups: [],
directs: [],
};
const groups = activeData?.groups;
if (!groups || groups?.length === 0) return;
const savedtimestamp = await getTimestampGroupAnnouncement();
await Promise.all(
groups.map(async (group) => {
try {
const identifier = `grp-${group.groupId}-anc-`;
const endpoint = await getArbitraryEndpoint();
const url = await createEndpoint(
`${endpoint}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=1&includemetadata=false&offset=0&reverse=true&prefix=true`
);
const response = await requestQueueAnnouncements.enqueue(() => {
return fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
});
const responseData = await response.json();
const latestMessage = responseData.filter(
(pub) => pub?.name !== myName
)[0];
if (!latestMessage) {
return; // continue to the next group
}
if (
checkDifference(latestMessage.created) &&
(!savedtimestamp[group.groupId] ||
latestMessage.created >
savedtimestamp?.[group.groupId]?.notification)
) {
newAnnouncements.push(group);
await addTimestampGroupAnnouncement({
groupId: group.groupId,
timestamp: Date.now(),
});
// save new timestamp
}
} catch (error) {
console.error(error); // Handle error if needed
}
})
);
let isDisableNotifications =
(await getUserSettings({ key: "disable-push-notifications" })) || false;
if (
newAnnouncements.length > 0 &&
!mutedGroups.includes(newAnnouncements[0]?.groupId) &&
!isDisableNotifications
) {
const notificationId =
"chat_notification_" +
Date.now() +
"_type=group-announcement" +
`_from=${newAnnouncements[0]?.groupId}`;
// chrome.notifications.create(notificationId, {
// type: "basic",
// iconUrl: "qort.png", // Add an appropriate icon for chat notifications
// title: `New group announcement!`,
// message: `You have received a new announcement from ${newAnnouncements[0]?.groupName}`,
// priority: 2, // Use the maximum priority to ensure it's noticeable
// });
// if (!isMobile) {
// setTimeout(() => {
// chrome.notifications.clear(notificationId);
// }, 7000);
// }
playNotificationSound();
}
const savedtimestampAfter = await getTimestampGroupAnnouncement();
window.postMessage({
action: "SET_GROUP_ANNOUNCEMENTS",
payload: savedtimestampAfter,
}, "*");
} catch (error) {
} finally {
}
};
const listenForNewGroupAnnouncements = async () => {
try {
@ -3146,10 +2878,299 @@ const checkGroupList = async () => {
};
export const checkNewMessages = async () => {
try {
let mutedGroups = await getUserSettings({key: 'mutedGroups'}) || []
if(!isArray(mutedGroups)) mutedGroups = []
let myName = "";
const userData = await getUserInfo();
if (userData?.name) {
myName = userData.name;
}
// Reconnect when service worker wakes up
let newAnnouncements = [];
const activeData = (await getStoredData("active-groups-directs")) || {
groups: [],
directs: [],
};
const groups = activeData?.groups;
if (!groups || groups?.length === 0) return;
const savedtimestamp = await getTimestampGroupAnnouncement();
await Promise.all(
groups.map(async (group) => {
try {
const identifier = `grp-${group.groupId}-anc-`;
const endpoint = await getArbitraryEndpoint();
const url = await createEndpoint(
`${endpoint}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=1&includemetadata=false&offset=0&reverse=true&prefix=true`
);
const response = await requestQueueAnnouncements.enqueue(() => {
return fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
});
const responseData = await response.json();
const latestMessage = responseData.filter(
(pub) => pub?.name !== myName
)[0];
if (!latestMessage) {
return; // continue to the next group
}
if (
checkDifference(latestMessage.created) &&
(!savedtimestamp[group.groupId] ||
latestMessage.created >
savedtimestamp?.[group.groupId]?.notification)
) {
newAnnouncements.push(group);
await addTimestampGroupAnnouncement({
groupId: group.groupId,
timestamp: Date.now(),
});
// save new timestamp
}
} catch (error) {
console.error(error); // Handle error if needed
}
})
);
let isDisableNotifications = await getUserSettings({key: 'disable-push-notifications'}) || false
if (newAnnouncements.length > 0 && !mutedGroups.includes(newAnnouncements[0]?.groupId) && !isDisableNotifications) {
const notificationId =
"chat_notification_" +
Date.now() +
"_type=group-announcement" +
`_from=${newAnnouncements[0]?.groupId}`;
LocalNotifications.schedule({
notifications: [
{
title: "New group announcement!",
body: `You have received a new announcement from ${newAnnouncements[0]?.groupName}`,
id: notificationId,
schedule: { at: new Date(Date.now() + 1000) }, // 1 second from now
}
]
});
}
const savedtimestampAfter = await getTimestampGroupAnnouncement();
window.postMessage({
action: "SET_GROUP_ANNOUNCEMENTS",
payload: savedtimestampAfter,
}, "*");
} catch (error) {
} finally {
}
};
const checkActiveChatsForNotifications = async () => {
try {
checkGroupList();
} catch (error) {}
};
export const checkThreads = async (bringBack) => {
try {
let myName = "";
const userData = await getUserInfo();
if (userData?.name) {
myName = userData.name;
}
let newAnnouncements = [];
let dataToBringBack = [];
const threadActivity = await getThreadActivity();
if (!threadActivity) return null;
const selectedThreads = [
...threadActivity.createdThreads.slice(0, 2),
...threadActivity.mostVisitedThreads.slice(0, 2),
...threadActivity.recentThreads.slice(0, 2),
];
if (selectedThreads?.length === 0) return null;
const tempData = {};
for (const thread of selectedThreads) {
try {
const identifier = `thmsg-${thread?.threadId}`;
const name = thread?.qortalName;
const endpoint = await getArbitraryEndpoint();
const url = await createEndpoint(
`${endpoint}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=1&includemetadata=false&offset=${0}&reverse=true&prefix=true`
);
const response = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const responseData = await response.json();
const latestMessage = responseData.filter(
(pub) => pub?.name !== myName
)[0];
// const latestMessage = responseData[0]
if (!latestMessage) {
continue;
}
if (
checkDifference(latestMessage.created) &&
latestMessage.created > thread?.lastVisited &&
(!thread?.lastNotified || thread?.lastNotified < thread?.created)
) {
tempData[thread.threadId] = latestMessage.created;
newAnnouncements.push(thread);
}
if (latestMessage.created > thread?.lastVisited) {
dataToBringBack.push(thread);
}
} catch (error) {
conosle.log({ error });
}
}
if (bringBack) {
return dataToBringBack;
}
const updateThreadWithLastNotified = {
...threadActivity,
createdThreads: (threadActivity?.createdThreads || [])?.map((item) => {
if (tempData[item.threadId]) {
return {
...item,
lastNotified: tempData[item.threadId],
};
} else {
return item;
}
}),
mostVisitedThreads: (threadActivity?.mostVisitedThreads || [])?.map(
(item) => {
if (tempData[item.threadId]) {
return {
...item,
lastNotified: tempData[item.threadId],
};
} else {
return item;
}
}
),
recentThreads: (threadActivity?.recentThreads || [])?.map((item) => {
if (tempData[item.threadId]) {
return {
...item,
lastNotified: tempData[item.threadId],
};
} else {
return item;
}
}),
};
const wallet = await getSaveWallet();
const address = wallet.address0;
const dataString = JSON.stringify(updateThreadWithLastNotified);
chrome.storage.local.set({ [`threadactivity-${address}`]: dataString });
if (newAnnouncements.length > 0) {
const notificationId =
"chat_notification_" +
Date.now() +
"_type=thread-post" +
`_data=${JSON.stringify(newAnnouncements[0])}`;
let isDisableNotifications = await getUserSettings({key: 'disable-push-notifications'}) || false
if(!isDisableNotifications){
LocalNotifications.schedule({
notifications: [
{
title: `New thread post!`,
body: `New post in ${newAnnouncements[0]?.thread?.threadData?.title}`,
id: notificationId,
schedule: { at: new Date(Date.now() + 1000) }, // 1 second from now
}
]
});
}
}
const savedtimestampAfter = await getTimestampGroupAnnouncement();
window.postMessage({
action: "SET_GROUP_ANNOUNCEMENTS",
payload: savedtimestampAfter,
}, "*");
} catch (error) {
} finally {
}
};
// Configure Background Fetch
BackgroundFetch.configure({
minimumFetchInterval: 15, // Minimum 15-minute interval
enableHeadless: true, // Enable headless mode for Android
}, async (taskId) => {
// This is where your background task logic goes
const wallet = await getSaveWallet();
const address = wallet.address0;
console.log('alarm', address)
if (!address) return;
checkActiveChatsForNotifications();
checkNewMessages();
checkThreads();
await new Promise((res)=> {
setTimeout(() => {
res()
}, 55000);
})
// Always finish the task when complete
BackgroundFetch.finish(taskId);
}, (taskId) => {
// Optional timeout callback
BackgroundFetch.finish(taskId);
});
LocalNotifications.addListener('localNotificationActionPerformed', async (notification) => {
const notificationId = notification.notification.id;
// Check the type of notification by parsing notificationId
const isDirect = notificationId.includes('_type=direct_');
const isGroup = notificationId.includes('_type=group_');
const isGroupAnnouncement = notificationId.includes('_type=group-announcement_');
const isNewThreadPost = notificationId.includes('_type=thread-post_');
// Handle specific notification types
if (isDirect) {
const fromValue = notificationId.split('_from=')[1];
handleDirectNotification(fromValue);
} else if (isGroup) {
const fromValue = notificationId.split('_from=')[1];
handleGroupNotification(fromValue);
} else if (isGroupAnnouncement) {
const fromValue = notificationId.split('_from=')[1];
handleAnnouncementNotification(fromValue);
} else if (isNewThreadPost) {
const dataValue = notificationId.split('_data=')[1];
const dataParsed = JSON.parse(dataValue);
handleThreadPostNotification(dataParsed);
}
});