diff --git a/artifacts/postiz-mobile/hooks/useNotifications.ts b/artifacts/postiz-mobile/hooks/useNotifications.ts index fcc9ae0..effe1e1 100644 --- a/artifacts/postiz-mobile/hooks/useNotifications.ts +++ b/artifacts/postiz-mobile/hooks/useNotifications.ts @@ -1,22 +1,20 @@ -import * as Notifications from "expo-notifications"; import { useCallback, useEffect, useRef } from "react"; import { Platform } from "react-native"; import { usePostiz } 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 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> { try { const { default: AsyncStorage } = await import( @@ -39,18 +37,22 @@ async function saveSeenStatuses(map: Record) { } async function sendStatusNotification(post: PostizPost) { - const isError = post.status === "ERROR"; - await Notifications.scheduleNotificationAsync({ - content: { - title: isError ? "Post failed to publish" : "Post published!", - body: - post.content.length > 80 - ? post.content.slice(0, 80) + "…" - : post.content, - data: { postId: post.id }, - }, - trigger: null, - }); + if (Platform.OS === "web" || isExpoGo()) return; + try { + const Notifications = require("expo-notifications"); + const isError = post.state === "ERROR"; + await Notifications.scheduleNotificationAsync({ + content: { + title: isError ? "Post failed to publish" : "Post published!", + body: + post.content.length > 80 + ? post.content.slice(0, 80) + "…" + : post.content, + data: { postId: post.id }, + }, + trigger: null, + }); + } catch {} } export function useNotifications() { @@ -59,57 +61,64 @@ export function useNotifications() { const permissionGranted = useRef(false); const requestPermissions = useCallback(async () => { - if (Platform.OS === "web") return false; - const { status: existing } = await Notifications.getPermissionsAsync(); - if (existing === "granted") { - permissionGranted.current = true; - return true; + 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(); + if (existing === "granted") { + permissionGranted.current = true; + return true; + } + const { status } = await Notifications.requestPermissionsAsync(); + permissionGranted.current = status === "granted"; + return permissionGranted.current; + } catch { + return false; } - const { status } = await Notifications.requestPermissionsAsync(); - permissionGranted.current = status === "granted"; - return permissionGranted.current; }, []); const checkForStatusChanges = useCallback(async () => { if (!client || !permissionGranted.current) return; - try { const now = new Date(); const from = new Date(now); from.setDate(from.getDate() - 7); - - const res = await client.get("/posts", { + const res = await client.get("posts", { params: { startDate: from.toISOString(), endDate: now.toISOString(), }, }); - const posts: PostizPost[] = Array.isArray(res.data) ? res.data : res.data?.posts ?? []; - const seen = await getSeenStatuses(); const updated: Record = { ...seen }; const toNotify: PostizPost[] = []; - for (const post of posts) { const prev = seen[post.id]; if (prev === undefined) { - updated[post.id] = post.status; + updated[post.id] = post.state; continue; } if ( - prev !== post.status && - (post.status === "PUBLISHED" || post.status === "ERROR") + prev !== post.state && + (post.state === "PUBLISHED" || post.state === "ERROR") ) { toNotify.push(post); } - updated[post.id] = post.status; + updated[post.id] = post.state; } - await saveSeenStatuses(updated); - for (const post of toNotify) { await sendStatusNotification(post); } @@ -117,21 +126,16 @@ export function useNotifications() { }, [client]); useEffect(() => { - if (!isConfigured || Platform.OS === "web") return; - + if (!isConfigured || Platform.OS === "web" || isExpoGo()) return; let mounted = true; - (async () => { const granted = await requestPermissions(); if (!granted || !mounted) return; - await checkForStatusChanges(); - intervalRef.current = setInterval(() => { checkForStatusChanges(); }, POLL_INTERVAL_MS); })(); - return () => { mounted = false; if (intervalRef.current) {