Skip to content
Merged
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
46 changes: 23 additions & 23 deletions src/Modals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ import W3iContext from '@/contexts/W3iContext/context'
import { SignatureModal } from '@/pages/Login/SignatureModal'
import { useModals } from '@/utils/hooks'
import { useNotificationPermissionState } from '@/utils/hooks/notificationHooks'
import { notificationsEnabledInBrowser } from '@/utils/notifications'
import { isMobileButNotInstalledOnHomescreen } from '@/utils/pwa'
import {
checkIfNotificationModalClosed,
notificationsEnabledInBrowser
} from '@/utils/notifications'
import { isMobileButNotInstalledOnHomeScreen } from '@/utils/pwa'
import { notificationPwaModalService, signatureModalService } from '@/utils/store'
import { isMobile } from '@/utils/ui'

Expand All @@ -29,18 +32,17 @@ export const Modals = () => {

const notificationsEnabled = useNotificationPermissionState()

const notificationModalClosed = checkIfNotificationModalClosed()
const explicitlyDeniedOnDesktop = !isMobile() && window.Notification?.permission === 'denied'

const shouldShowNotificationModal = useMemo(
() =>
notificationsEnabledInBrowser() &&
!explicitlyDeniedOnDesktop &&
!isMobileButNotInstalledOnHomescreen() &&
!notificationsEnabled &&
Boolean(notifyRegisteredKey) &&
!isSignatureModalOpen,
[explicitlyDeniedOnDesktop, notificationsEnabled, notifyRegisteredKey, isSignatureModalOpen]
)
const shouldShowNotificationModal =
notificationsEnabledInBrowser() &&
!explicitlyDeniedOnDesktop &&
!isMobileButNotInstalledOnHomeScreen() &&
!notificationsEnabled &&
Boolean(notifyRegisteredKey) &&
!isSignatureModalOpen &&
!notificationModalClosed

useEffect(() => {
const notifySignatureRequired = Boolean(notifyRegisterMessage) && !notifyRegisteredKey
Expand All @@ -64,20 +66,18 @@ export const Modals = () => {
}, [shouldShowNotificationModal])

return (
<>
<AnimatePresence mode="popLayout">
{isUnsubscribeModalOpen && <UnsubscribeModal />}
<AnimatePresence mode="popLayout">
{isUnsubscribeModalOpen && <UnsubscribeModal />}

{isPreferencesModalOpen && <PreferencesModal />}
{isPreferencesModalOpen && <PreferencesModal />}

{isSignatureModalOpen && (
<SignatureModal message={notifyRegisterMessage ?? ''} sender={'notify'} />
)}
{isSignatureModalOpen && (
<SignatureModal message={notifyRegisterMessage ?? ''} sender={'notify'} />
)}

{isMobileButNotInstalledOnHomescreen() && <PwaModal />}
{isMobileButNotInstalledOnHomeScreen() && <PwaModal />}

{isNotificationPwaModalOpen && <NotificationPwaModal />}
</AnimatePresence>
</>
{isNotificationPwaModalOpen && <NotificationPwaModal />}
</AnimatePresence>
)
}
2 changes: 1 addition & 1 deletion src/components/general/Icon/CrossIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const CrossIcon: React.FC = () => {
<svg fill="none" viewBox="0 0 16 16">
<path
fill="currentColor"
fill-rule="evenodd"
fillRule="evenodd"
d="M2.54 2.54a1 1 0 0 1 1.42 0L8 6.6l4.04-4.05a1 1 0 1 1 1.42 1.42L9.4 8l4.05 4.04a1 1 0 0 1-1.42 1.42L8 9.4l-4.04 4.05a1 1 0 0 1-1.42-1.42L6.6 8 2.54 3.96a1 1 0 0 1 0-1.42Z"
clipRule="evenodd"
></path>
Expand Down
2 changes: 1 addition & 1 deletion src/components/general/Icon/SignatureIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const SignatureIcon: React.FC = () => {
fill="#3ABDF2"
d="M39.83 62.83a20.35 20.35 0 0 1 28.34 0l.95.92c.39.39.39 1 0 1.4l-3.23 3.15a.5.5 0 0 1-.7 0l-1.3-1.27a14.2 14.2 0 0 0-19.78 0l-1.39 1.36a.5.5 0 0 1-.7 0l-3.23-3.16c-.39-.38-.39-1 0-1.39l1.04-1Zm35 6.53 2.88 2.8c.39.39.39 1 0 1.4L64.77 86.21c-.39.38-1.02.38-1.41 0l-9.18-9a.25.25 0 0 0-.36 0l-9.18 9c-.39.38-1.02.38-1.41 0L30.29 73.55c-.39-.38-.39-1 0-1.39l2.87-2.8c.4-.39 1.03-.39 1.42 0l9.18 8.98c.1.1.26.1.35 0l9.18-8.98c.4-.39 1.03-.39 1.42 0l9.18 8.98c.1.1.25.1.35 0l9.18-8.98c.4-.39 1.03-.39 1.42 0Z"
/>
<circle cx="53.9" cy="72" r="39.5" stroke="#062B2B" stroke-opacity=".02" />
<circle cx="53.9" cy="72" r="39.5" stroke="#062B2B" strokeOpacity=".02" />
<defs>
<clipPath id="a">
<path fill="#fff" d="M85.9 33.9h76.2v76.2H85.9z" />
Expand Down
1 change: 0 additions & 1 deletion src/components/general/Modal/Modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
align-items: center;
border-radius: 30px;
background: var(--bg-color-1);
border: 1px solid var(--border-color-2);
box-shadow:
0px 8px 22px -6px rgba(0, 0, 0, 0.12),
0px 14px 64px -4px rgba(0, 0, 0, 0.12);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@
gap: 2em;
position: relative;

&__close-button {
svg {
color: var(--fg-color-3);
}
}

&__header {
display: flex;
justify-content: flex-end;
width: 100%;
align-items: center;
}

&__background {
position: absolute;
z-index: -999;
Expand Down
39 changes: 21 additions & 18 deletions src/components/utils/NotificationPwaModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ import React, { Fragment, useContext } from 'react'

import BackgroundImage from '@/assets/IntroBackground.png'
import Button from '@/components/general/Button'
import WalletConnectIcon from '@/components/general/Icon/WalletConnectIcon'
import CrossIcon from '@/components/general/Icon/CrossIcon'
import { Modal } from '@/components/general/Modal/Modal'
import Text from '@/components/general/Text'
import W3iContext from '@/contexts/W3iContext/context'
import { requireNotifyPermission } from '@/utils/notifications'
import { closeNotificationModal, requireNotifyPermission } from '@/utils/notifications'
import { pwaModalService } from '@/utils/store'

import './NotificationPwaModal.scss'

export const NotificationPwaModal: React.FC = () => {
const { notifyClientProxy } = useContext(W3iContext)

const explicitlyDeniedPermissionForNotifications = window.Notification?.permission === 'denied'

const handleEnableNotifications = async () => {
const notificationPermissionGranted = await requireNotifyPermission()

Expand All @@ -26,37 +28,38 @@ export const NotificationPwaModal: React.FC = () => {
}
}

const explicitlyDeniedPermissionForNotifications = window.Notification?.permission === 'denied'

return (
<Modal onCloseModal={pwaModalService.closeModal}>
<div className="NotificationPwaModal">
<div className="NotificationPwaModal__header">
<Button
className="NotificationPwaModal__close-button"
customType="action-icon"
onClick={closeNotificationModal}
>
<CrossIcon />
</Button>
</div>
<div className="NotificationPwaModal__background">
<img src={BackgroundImage} />
</div>
<div className="NotificationPwaModal__icon">
<img alt="Web3Inbox icon" className="wc-icon" src="/icon.png" />
</div>
<div className="NotificationPwaModal__header">
<Text variant={'large-500'}>Enable Notifications</Text>
</div>
<div className="NotificationPwaModal__description">
<Text variant="small-500">
To use Web3Inbox and receive notifications from your subscribed apps, please enable push
notifications.
</Text>
</div>
<Text variant={'large-500'}>Enable Notifications</Text>
<Text variant="small-500">
To use Web3Inbox and receive notifications from your subscribed apps, please enable push
notifications.
</Text>
{explicitlyDeniedPermissionForNotifications ? (
<Text variant="small-700" className="NotificationPwaModal__warning">
You have explicitly denied notification permissions. Please adjust in OS settings.
</Text>
) : (
<Fragment>
<div className="NotificationPwaModal_subtitle">
<Text variant="small-500">
You can always adjust your permissions in your OS settings.
</Text>
</div>
<Text variant="small-500">
You can always adjust your permissions in your OS settings.
</Text>
<Button onClick={handleEnableNotifications} size="small">
Enable Notifications
</Button>
Expand Down
3 changes: 3 additions & 0 deletions src/constants/localStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const localStorageKeys = {
notificationModalClosed: 'w3i:notification_modal_closed'
}
16 changes: 16 additions & 0 deletions src/utils/localStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export class LocalStorage {
static get(key: string) {
if (typeof localStorage === 'undefined') {
return undefined
}

return localStorage.getItem(key)
}
static set(key: string, value: string) {
if (typeof localStorage === 'undefined') {
return undefined
}

return localStorage.setItem(key, value)
}
}
16 changes: 14 additions & 2 deletions src/utils/notifications.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useEffect, useState } from 'react'

import { NotifyClient } from '@walletconnect/notify-client'

import { localStorageKeys } from '@/constants/localStorage'
import { LocalStorage } from '@/utils/localStorage'
import { notificationPwaModalService } from '@/utils/store'

import { getFirebaseToken } from './firebase'
import { getDbEchoRegistrations, getDbSymkeyStore } from './idb'

Expand Down Expand Up @@ -61,6 +63,16 @@ export const setupSubscriptionsSymkeys = async (topicSymkeyEntries: [string, str
}
}

export const closeNotificationModal = () => {
LocalStorage.set(localStorageKeys.notificationModalClosed, 'true')
notificationPwaModalService.closeModal()
}

export const checkIfNotificationModalClosed = () => {
const storageValue = LocalStorage.get(localStorageKeys.notificationModalClosed)
return storageValue === 'true'
}

export const notificationsEnabledInBrowser = () => {
return 'Notification' in window
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/pwa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export const isInstalledOnHomescreen = () => {

export const isMobileBrowser = () => /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)

export const isMobileButNotInstalledOnHomescreen = () =>
export const isMobileButNotInstalledOnHomeScreen = () =>
isMobileBrowser() && !isInstalledOnHomescreen()