correction notifications
This commit is contained in:
@@ -1,22 +1,20 @@
|
|||||||
import * as Notifications from "expo-notifications";
|
|
||||||
import { useCallback, useEffect, useRef } from "react";
|
import { useCallback, useEffect, useRef } from "react";
|
||||||
import { Platform } from "react-native";
|
import { Platform } from "react-native";
|
||||||
import { usePostiz } from "@/context/PostizContext";
|
import { usePostiz } from "@/context/PostizContext";
|
||||||
import { PostizPost } from "@/context/PostizContext";
|
import { PostizPost } from "@/context/PostizContext";
|
||||||
|
|
||||||
Notifications.setNotificationHandler({
|
|
||||||
handleNotification: async () => ({
|
|
||||||
shouldShowAlert: true,
|
|
||||||
shouldPlaySound: true,
|
|
||||||
shouldSetBadge: true,
|
|
||||||
shouldShowBanner: true,
|
|
||||||
shouldShowList: true,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const POLL_INTERVAL_MS = 15 * 60 * 1000;
|
const POLL_INTERVAL_MS = 15 * 60 * 1000;
|
||||||
const SEEN_KEY = "postiz_seen_statuses";
|
const SEEN_KEY = "postiz_seen_statuses";
|
||||||
|
|
||||||
|
function isExpoGo(): boolean {
|
||||||
|
try {
|
||||||
|
const Constants = require("expo-constants").default;
|
||||||
|
return Constants?.executionEnvironment === "storeClient";
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getSeenStatuses(): Promise<Record<string, string>> {
|
async function getSeenStatuses(): Promise<Record<string, string>> {
|
||||||
try {
|
try {
|
||||||
const { default: AsyncStorage } = await import(
|
const { default: AsyncStorage } = await import(
|
||||||
@@ -39,7 +37,10 @@ async function saveSeenStatuses(map: Record<string, string>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function sendStatusNotification(post: PostizPost) {
|
async function sendStatusNotification(post: PostizPost) {
|
||||||
const isError = post.status === "ERROR";
|
if (Platform.OS === "web" || isExpoGo()) return;
|
||||||
|
try {
|
||||||
|
const Notifications = require("expo-notifications");
|
||||||
|
const isError = post.state === "ERROR";
|
||||||
await Notifications.scheduleNotificationAsync({
|
await Notifications.scheduleNotificationAsync({
|
||||||
content: {
|
content: {
|
||||||
title: isError ? "Post failed to publish" : "Post published!",
|
title: isError ? "Post failed to publish" : "Post published!",
|
||||||
@@ -51,6 +52,7 @@ async function sendStatusNotification(post: PostizPost) {
|
|||||||
},
|
},
|
||||||
trigger: null,
|
trigger: null,
|
||||||
});
|
});
|
||||||
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useNotifications() {
|
export function useNotifications() {
|
||||||
@@ -59,7 +61,18 @@ export function useNotifications() {
|
|||||||
const permissionGranted = useRef(false);
|
const permissionGranted = useRef(false);
|
||||||
|
|
||||||
const requestPermissions = useCallback(async () => {
|
const requestPermissions = useCallback(async () => {
|
||||||
if (Platform.OS === "web") return false;
|
if (Platform.OS === "web" || isExpoGo()) return false;
|
||||||
|
try {
|
||||||
|
const Notifications = require("expo-notifications");
|
||||||
|
Notifications.setNotificationHandler({
|
||||||
|
handleNotification: async () => ({
|
||||||
|
shouldShowAlert: true,
|
||||||
|
shouldPlaySound: true,
|
||||||
|
shouldSetBadge: true,
|
||||||
|
shouldShowBanner: true,
|
||||||
|
shouldShowList: true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
const { status: existing } = await Notifications.getPermissionsAsync();
|
const { status: existing } = await Notifications.getPermissionsAsync();
|
||||||
if (existing === "granted") {
|
if (existing === "granted") {
|
||||||
permissionGranted.current = true;
|
permissionGranted.current = true;
|
||||||
@@ -68,48 +81,44 @@ export function useNotifications() {
|
|||||||
const { status } = await Notifications.requestPermissionsAsync();
|
const { status } = await Notifications.requestPermissionsAsync();
|
||||||
permissionGranted.current = status === "granted";
|
permissionGranted.current = status === "granted";
|
||||||
return permissionGranted.current;
|
return permissionGranted.current;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const checkForStatusChanges = useCallback(async () => {
|
const checkForStatusChanges = useCallback(async () => {
|
||||||
if (!client || !permissionGranted.current) return;
|
if (!client || !permissionGranted.current) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const from = new Date(now);
|
const from = new Date(now);
|
||||||
from.setDate(from.getDate() - 7);
|
from.setDate(from.getDate() - 7);
|
||||||
|
const res = await client.get("posts", {
|
||||||
const res = await client.get("/posts", {
|
|
||||||
params: {
|
params: {
|
||||||
startDate: from.toISOString(),
|
startDate: from.toISOString(),
|
||||||
endDate: now.toISOString(),
|
endDate: now.toISOString(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const posts: PostizPost[] = Array.isArray(res.data)
|
const posts: PostizPost[] = Array.isArray(res.data)
|
||||||
? res.data
|
? res.data
|
||||||
: res.data?.posts ?? [];
|
: res.data?.posts ?? [];
|
||||||
|
|
||||||
const seen = await getSeenStatuses();
|
const seen = await getSeenStatuses();
|
||||||
const updated: Record<string, string> = { ...seen };
|
const updated: Record<string, string> = { ...seen };
|
||||||
const toNotify: PostizPost[] = [];
|
const toNotify: PostizPost[] = [];
|
||||||
|
|
||||||
for (const post of posts) {
|
for (const post of posts) {
|
||||||
const prev = seen[post.id];
|
const prev = seen[post.id];
|
||||||
if (prev === undefined) {
|
if (prev === undefined) {
|
||||||
updated[post.id] = post.status;
|
updated[post.id] = post.state;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
prev !== post.status &&
|
prev !== post.state &&
|
||||||
(post.status === "PUBLISHED" || post.status === "ERROR")
|
(post.state === "PUBLISHED" || post.state === "ERROR")
|
||||||
) {
|
) {
|
||||||
toNotify.push(post);
|
toNotify.push(post);
|
||||||
}
|
}
|
||||||
updated[post.id] = post.status;
|
updated[post.id] = post.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
await saveSeenStatuses(updated);
|
await saveSeenStatuses(updated);
|
||||||
|
|
||||||
for (const post of toNotify) {
|
for (const post of toNotify) {
|
||||||
await sendStatusNotification(post);
|
await sendStatusNotification(post);
|
||||||
}
|
}
|
||||||
@@ -117,21 +126,16 @@ export function useNotifications() {
|
|||||||
}, [client]);
|
}, [client]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isConfigured || Platform.OS === "web") return;
|
if (!isConfigured || Platform.OS === "web" || isExpoGo()) return;
|
||||||
|
|
||||||
let mounted = true;
|
let mounted = true;
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const granted = await requestPermissions();
|
const granted = await requestPermissions();
|
||||||
if (!granted || !mounted) return;
|
if (!granted || !mounted) return;
|
||||||
|
|
||||||
await checkForStatusChanges();
|
await checkForStatusChanges();
|
||||||
|
|
||||||
intervalRef.current = setInterval(() => {
|
intervalRef.current = setInterval(() => {
|
||||||
checkForStatusChanges();
|
checkForStatusChanges();
|
||||||
}, POLL_INTERVAL_MS);
|
}, POLL_INTERVAL_MS);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
mounted = false;
|
mounted = false;
|
||||||
if (intervalRef.current) {
|
if (intervalRef.current) {
|
||||||
|
|||||||
Reference in New Issue
Block a user