diff --git a/modules/napplet-host/android/src/main/java/org/nostrocket/hypergolic/host/NappletHostModule.kt b/modules/napplet-host/android/src/main/java/org/nostrocket/hypergolic/host/NappletHostModule.kt index e4ae6b8..25227f2 100644 --- a/modules/napplet-host/android/src/main/java/org/nostrocket/hypergolic/host/NappletHostModule.kt +++ b/modules/napplet-host/android/src/main/java/org/nostrocket/hypergolic/host/NappletHostModule.kt @@ -5,12 +5,31 @@ import expo.modules.kotlin.modules.ModuleDefinition import com.facebook.react.common.LifecycleState import android.util.Base64 import expo.modules.kotlin.functions.Coroutine +import expo.modules.kotlin.functions.Queues +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsControllerCompat import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.withContext class NappletHostModule : Module() { + private var workspaceFullscreen = false + + private fun updateWorkspaceBars() { + val window = appContext.currentActivity?.window ?: return + val controller = WindowCompat.getInsetsController(window, window.decorView) + val bars = WindowInsetsCompat.Type.systemBars() + if (workspaceFullscreen) { + controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + controller.hide(bars) + } else { + controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_DEFAULT + controller.show(bars) + } + } + override fun definition() = ModuleDefinition { Name("HypergolicNappletHost") Events("onRelayStream", "onRelayLifecycle", "onUploadProgress", "onRoutingLifecycle") @@ -32,7 +51,12 @@ class NappletHostModule : Module() { ResourceHttpsRequestOwner.INSTANCE.setForeground(foreground) PublishedRelayWssRequestOwner.INSTANCE.setForeground(foreground) } + AsyncFunction("setWorkspaceFullscreen") { fullscreen: Boolean -> + workspaceFullscreen = fullscreen + updateWorkspaceBars() + }.runOnQueue(Queues.MAIN) OnActivityEntersForeground { + if (workspaceFullscreen) updateWorkspaceBars() SelectedFilePicker.foreground(true) UploadTransport.foreground(true) CvmTransport.foreground(true) diff --git a/src/shell/Notifications.tsx b/src/shell/Notifications.tsx index 73e1f19..927bdd2 100644 --- a/src/shell/Notifications.tsx +++ b/src/shell/Notifications.tsx @@ -1,6 +1,7 @@ import {publishedAppLabel} from '../napplets/published-identity'; import { TrustedBand } from './TrustedBand'; -import {useCallback, useEffect, useMemo, useState, useSyncExternalStore} from 'react'; +import {WorkspaceFullscreenContext} from './WorkspaceFullscreen'; +import {useCallback, useContext, useEffect, useMemo, useState, useSyncExternalStore} from 'react'; import {AppState, FlatList, ScrollView, StyleSheet, Text, View} from 'react-native'; import { ShellModal as Modal } from './ShellModal'; import { ShellPressable as Pressable } from './ShellPressable'; @@ -35,6 +36,7 @@ function NotificationPermission({review, service}: {review: NotifyReview; servic type CentreEntry = Readonly<{kind: 'card'; card: NotificationCard}> | Readonly<{kind: 'badge'; badge: NotificationBadge}>; export function Notifications({service, blocked}: {service: NotifyBroker; blocked: boolean}) { const { styles } = useShellStyles(createStyles); + const fullscreen = useContext(WorkspaceFullscreenContext); const snapshot = useSyncExternalStore(service.subscribe, service.getSnapshot), [opened, setOpened] = useState(false), insets = useSafeAreaInsets(); useEffect(() => { const timer = setInterval(() => service.refresh(), 250), listener = AppState.addEventListener('change', state => {if (state !== 'active') setOpened(false); service.refresh();}); @@ -43,7 +45,7 @@ export function Notifications({service, blocked}: {service: NotifyBroker; blocke const entries = useMemo(() => [...snapshot.cards.map(card => ({kind: 'card' as const, card})), ...snapshot.attributedBadges.map(badge => ({kind: 'badge' as const, badge}))], [snapshot.cards, snapshot.attributedBadges]); const renderEntry = useCallback(({item}: {item: CentreEntry}) => item.kind === 'card' ? : {publishedAppLabel(item.badge.origin.appId)}{formatNpub(item.badge.origin.publisher)}Badge count: {item.badge.count}, [service, styles]); if (blocked) return null; - const toast = !opened && !snapshot.review ? snapshot.toast : undefined; + const toast = !fullscreen && !opened && !snapshot.review ? snapshot.toast : undefined; const badge = Object.values(snapshot.badges).reduce((sum, count) => sum + count, 0); return <> {toast && @@ -51,7 +53,7 @@ export function Notifications({service, blocked}: {service: NotifyBroker; blocke {toast.title}{toast.body !== '' && {toast.body}}