NotificationSettings to its own file
This commit is contained in:
parent
6dcad6225b
commit
b5ef7490c3
210
web/components/NotificationSettings.tsx
Normal file
210
web/components/NotificationSettings.tsx
Normal file
|
@ -0,0 +1,210 @@
|
|||
import { useUser } from 'web/hooks/use-user'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { notification_subscribe_types, PrivateUser } from 'common/lib/user'
|
||||
import { listenForPrivateUser, updatePrivateUser } from 'web/lib/firebase/users'
|
||||
import toast from 'react-hot-toast'
|
||||
import { track } from '@amplitude/analytics-browser'
|
||||
import { LoadingIndicator } from 'web/components/loading-indicator'
|
||||
import { Row } from 'web/components/layout/row'
|
||||
import clsx from 'clsx'
|
||||
import { CheckIcon, XIcon } from '@heroicons/react/outline'
|
||||
import { ChoicesToggleGroup } from 'web/components/choices-toggle-group'
|
||||
|
||||
export function NotificationSettings() {
|
||||
const user = useUser()
|
||||
const [notificationSettings, setNotificationSettings] =
|
||||
useState<notification_subscribe_types>('all')
|
||||
const [emailNotificationSettings, setEmailNotificationSettings] =
|
||||
useState<notification_subscribe_types>('all')
|
||||
const [privateUser, setPrivateUser] = useState<PrivateUser | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (user) listenForPrivateUser(user.id, setPrivateUser)
|
||||
}, [user])
|
||||
|
||||
useEffect(() => {
|
||||
if (!privateUser) return
|
||||
if (privateUser.notificationPreferences) {
|
||||
setNotificationSettings(privateUser.notificationPreferences)
|
||||
}
|
||||
if (
|
||||
privateUser.unsubscribedFromResolutionEmails &&
|
||||
privateUser.unsubscribedFromCommentEmails &&
|
||||
privateUser.unsubscribedFromAnswerEmails
|
||||
) {
|
||||
setEmailNotificationSettings('none')
|
||||
} else if (
|
||||
!privateUser.unsubscribedFromResolutionEmails &&
|
||||
!privateUser.unsubscribedFromCommentEmails &&
|
||||
!privateUser.unsubscribedFromAnswerEmails
|
||||
) {
|
||||
setEmailNotificationSettings('all')
|
||||
} else {
|
||||
setEmailNotificationSettings('less')
|
||||
}
|
||||
}, [privateUser])
|
||||
|
||||
const loading = 'Changing Notifications Settings'
|
||||
const success = 'Notification Settings Changed!'
|
||||
function changeEmailNotifications(newValue: notification_subscribe_types) {
|
||||
if (!privateUser) return
|
||||
if (newValue === 'all') {
|
||||
toast.promise(
|
||||
updatePrivateUser(privateUser.id, {
|
||||
unsubscribedFromResolutionEmails: false,
|
||||
unsubscribedFromCommentEmails: false,
|
||||
unsubscribedFromAnswerEmails: false,
|
||||
}),
|
||||
{
|
||||
loading,
|
||||
success,
|
||||
error: (err) => `${err.message}`,
|
||||
}
|
||||
)
|
||||
} else if (newValue === 'less') {
|
||||
toast.promise(
|
||||
updatePrivateUser(privateUser.id, {
|
||||
unsubscribedFromResolutionEmails: false,
|
||||
unsubscribedFromCommentEmails: true,
|
||||
unsubscribedFromAnswerEmails: true,
|
||||
}),
|
||||
{
|
||||
loading,
|
||||
success,
|
||||
error: (err) => `${err.message}`,
|
||||
}
|
||||
)
|
||||
} else if (newValue === 'none') {
|
||||
toast.promise(
|
||||
updatePrivateUser(privateUser.id, {
|
||||
unsubscribedFromResolutionEmails: true,
|
||||
unsubscribedFromCommentEmails: true,
|
||||
unsubscribedFromAnswerEmails: true,
|
||||
}),
|
||||
{
|
||||
loading,
|
||||
success,
|
||||
error: (err) => `${err.message}`,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function changeInAppNotificationSettings(
|
||||
newValue: notification_subscribe_types
|
||||
) {
|
||||
if (!privateUser) return
|
||||
track('In-App Notification Preferences Changed', {
|
||||
newPreference: newValue,
|
||||
oldPreference: privateUser.notificationPreferences,
|
||||
})
|
||||
toast.promise(
|
||||
updatePrivateUser(privateUser.id, {
|
||||
notificationPreferences: newValue,
|
||||
}),
|
||||
{
|
||||
loading,
|
||||
success,
|
||||
error: (err) => `${err.message}`,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (privateUser && privateUser.notificationPreferences)
|
||||
setNotificationSettings(privateUser.notificationPreferences)
|
||||
else setNotificationSettings('all')
|
||||
}, [privateUser])
|
||||
|
||||
if (!privateUser) {
|
||||
return <LoadingIndicator spinnerClassName={'border-gray-500 h-4 w-4'} />
|
||||
}
|
||||
|
||||
function NotificationSettingLine(props: {
|
||||
label: string
|
||||
highlight: boolean
|
||||
}) {
|
||||
const { label, highlight } = props
|
||||
return (
|
||||
<Row className={clsx('my-1 text-gray-300', highlight && '!text-black')}>
|
||||
{highlight ? <CheckIcon height={20} /> : <XIcon height={20} />}
|
||||
{label}
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={'p-2'}>
|
||||
<div>In App Notifications</div>
|
||||
<ChoicesToggleGroup
|
||||
currentChoice={notificationSettings}
|
||||
choicesMap={{ All: 'all', Less: 'less', None: 'none' }}
|
||||
setChoice={(choice) =>
|
||||
changeInAppNotificationSettings(
|
||||
choice as notification_subscribe_types
|
||||
)
|
||||
}
|
||||
className={'col-span-4 p-2'}
|
||||
toggleClassName={'w-24'}
|
||||
/>
|
||||
<div className={'mt-4 text-sm'}>
|
||||
<div>
|
||||
<div className={''}>
|
||||
You will receive notifications for:
|
||||
<NotificationSettingLine
|
||||
label={"Resolution of questions you've interacted with"}
|
||||
highlight={notificationSettings !== 'none'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
highlight={notificationSettings !== 'none'}
|
||||
label={'Activity on your own questions, comments, & answers'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
highlight={notificationSettings !== 'none'}
|
||||
label={"Activity on questions you're betting on"}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
highlight={notificationSettings !== 'none'}
|
||||
label={"Income & referral bonuses you've received"}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
label={"Activity on questions you've ever bet or commented on"}
|
||||
highlight={notificationSettings === 'all'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'mt-4'}>Email Notifications</div>
|
||||
<ChoicesToggleGroup
|
||||
currentChoice={emailNotificationSettings}
|
||||
choicesMap={{ All: 'all', Less: 'less', None: 'none' }}
|
||||
setChoice={(choice) =>
|
||||
changeEmailNotifications(choice as notification_subscribe_types)
|
||||
}
|
||||
className={'col-span-4 p-2'}
|
||||
toggleClassName={'w-24'}
|
||||
/>
|
||||
<div className={'mt-4 text-sm'}>
|
||||
<div>
|
||||
You will receive emails for:
|
||||
<NotificationSettingLine
|
||||
label={"Resolution of questions you're betting on"}
|
||||
highlight={emailNotificationSettings !== 'none'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
label={'Closure of your questions'}
|
||||
highlight={emailNotificationSettings !== 'none'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
label={'Activity on your questions'}
|
||||
highlight={emailNotificationSettings === 'all'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
label={"Activity on questions you've answered or commented on"}
|
||||
highlight={emailNotificationSettings === 'all'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { Tabs } from 'web/components/layout/tabs'
|
||||
import { usePrivateUser, useUser } from 'web/hooks/use-user'
|
||||
import { usePrivateUser } from 'web/hooks/use-user'
|
||||
import React, { useEffect, useMemo, useState } from 'react'
|
||||
import { Notification, notification_source_types } from 'common/notification'
|
||||
import { Avatar, EmptyAvatar } from 'web/components/avatar'
|
||||
|
@ -12,16 +12,10 @@ import { UserLink } from 'web/components/user-page'
|
|||
import {
|
||||
MANIFOLD_AVATAR_URL,
|
||||
MANIFOLD_USERNAME,
|
||||
notification_subscribe_types,
|
||||
PrivateUser,
|
||||
User,
|
||||
} from 'common/user'
|
||||
import { ChoicesToggleGroup } from 'web/components/choices-toggle-group'
|
||||
import {
|
||||
getUser,
|
||||
listenForPrivateUser,
|
||||
updatePrivateUser,
|
||||
} from 'web/lib/firebase/users'
|
||||
import { getUser } from 'web/lib/firebase/users'
|
||||
import { LoadingIndicator } from 'web/components/loading-indicator'
|
||||
import clsx from 'clsx'
|
||||
import { RelativeTimestamp } from 'web/components/relative-timestamp'
|
||||
|
@ -37,8 +31,7 @@ import {
|
|||
NotificationGroup,
|
||||
usePreferredGroupedNotifications,
|
||||
} from 'web/hooks/use-notifications'
|
||||
import { CheckIcon, TrendingUpIcon, XIcon } from '@heroicons/react/outline'
|
||||
import toast from 'react-hot-toast'
|
||||
import { TrendingUpIcon } from '@heroicons/react/outline'
|
||||
import { formatMoney } from 'common/util/format'
|
||||
import { groupPath } from 'web/lib/firebase/groups'
|
||||
import { UNIQUE_BETTOR_BONUS_AMOUNT } from 'common/numeric-constants'
|
||||
|
@ -53,6 +46,7 @@ import {
|
|||
redirectIfLoggedOut,
|
||||
} from 'web/lib/firebase/server-auth'
|
||||
import { SiteLink } from 'web/components/site-link'
|
||||
import { NotificationSettings } from 'web/components/NotificationSettings'
|
||||
|
||||
export const NOTIFICATIONS_PER_PAGE = 30
|
||||
const MULTIPLE_USERS_KEY = 'multipleUsers'
|
||||
|
@ -986,203 +980,3 @@ function getReasonForShowingNotification(
|
|||
}
|
||||
return reasonText
|
||||
}
|
||||
|
||||
// TODO: where should we put referral bonus notifications?
|
||||
function NotificationSettings() {
|
||||
const user = useUser()
|
||||
const [notificationSettings, setNotificationSettings] =
|
||||
useState<notification_subscribe_types>('all')
|
||||
const [emailNotificationSettings, setEmailNotificationSettings] =
|
||||
useState<notification_subscribe_types>('all')
|
||||
const [privateUser, setPrivateUser] = useState<PrivateUser | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (user) listenForPrivateUser(user.id, setPrivateUser)
|
||||
}, [user])
|
||||
|
||||
useEffect(() => {
|
||||
if (!privateUser) return
|
||||
if (privateUser.notificationPreferences) {
|
||||
setNotificationSettings(privateUser.notificationPreferences)
|
||||
}
|
||||
if (
|
||||
privateUser.unsubscribedFromResolutionEmails &&
|
||||
privateUser.unsubscribedFromCommentEmails &&
|
||||
privateUser.unsubscribedFromAnswerEmails
|
||||
) {
|
||||
setEmailNotificationSettings('none')
|
||||
} else if (
|
||||
!privateUser.unsubscribedFromResolutionEmails &&
|
||||
!privateUser.unsubscribedFromCommentEmails &&
|
||||
!privateUser.unsubscribedFromAnswerEmails
|
||||
) {
|
||||
setEmailNotificationSettings('all')
|
||||
} else {
|
||||
setEmailNotificationSettings('less')
|
||||
}
|
||||
}, [privateUser])
|
||||
|
||||
const loading = 'Changing Notifications Settings'
|
||||
const success = 'Notification Settings Changed!'
|
||||
function changeEmailNotifications(newValue: notification_subscribe_types) {
|
||||
if (!privateUser) return
|
||||
if (newValue === 'all') {
|
||||
toast.promise(
|
||||
updatePrivateUser(privateUser.id, {
|
||||
unsubscribedFromResolutionEmails: false,
|
||||
unsubscribedFromCommentEmails: false,
|
||||
unsubscribedFromAnswerEmails: false,
|
||||
}),
|
||||
{
|
||||
loading,
|
||||
success,
|
||||
error: (err) => `${err.message}`,
|
||||
}
|
||||
)
|
||||
} else if (newValue === 'less') {
|
||||
toast.promise(
|
||||
updatePrivateUser(privateUser.id, {
|
||||
unsubscribedFromResolutionEmails: false,
|
||||
unsubscribedFromCommentEmails: true,
|
||||
unsubscribedFromAnswerEmails: true,
|
||||
}),
|
||||
{
|
||||
loading,
|
||||
success,
|
||||
error: (err) => `${err.message}`,
|
||||
}
|
||||
)
|
||||
} else if (newValue === 'none') {
|
||||
toast.promise(
|
||||
updatePrivateUser(privateUser.id, {
|
||||
unsubscribedFromResolutionEmails: true,
|
||||
unsubscribedFromCommentEmails: true,
|
||||
unsubscribedFromAnswerEmails: true,
|
||||
}),
|
||||
{
|
||||
loading,
|
||||
success,
|
||||
error: (err) => `${err.message}`,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function changeInAppNotificationSettings(
|
||||
newValue: notification_subscribe_types
|
||||
) {
|
||||
if (!privateUser) return
|
||||
track('In-App Notification Preferences Changed', {
|
||||
newPreference: newValue,
|
||||
oldPreference: privateUser.notificationPreferences,
|
||||
})
|
||||
toast.promise(
|
||||
updatePrivateUser(privateUser.id, {
|
||||
notificationPreferences: newValue,
|
||||
}),
|
||||
{
|
||||
loading,
|
||||
success,
|
||||
error: (err) => `${err.message}`,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (privateUser && privateUser.notificationPreferences)
|
||||
setNotificationSettings(privateUser.notificationPreferences)
|
||||
else setNotificationSettings('all')
|
||||
}, [privateUser])
|
||||
|
||||
if (!privateUser) {
|
||||
return <LoadingIndicator spinnerClassName={'border-gray-500 h-4 w-4'} />
|
||||
}
|
||||
|
||||
function NotificationSettingLine(props: {
|
||||
label: string
|
||||
highlight: boolean
|
||||
}) {
|
||||
const { label, highlight } = props
|
||||
return (
|
||||
<Row className={clsx('my-1 text-gray-300', highlight && '!text-black')}>
|
||||
{highlight ? <CheckIcon height={20} /> : <XIcon height={20} />}
|
||||
{label}
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={'p-2'}>
|
||||
<div>In App Notifications</div>
|
||||
<ChoicesToggleGroup
|
||||
currentChoice={notificationSettings}
|
||||
choicesMap={{ All: 'all', Less: 'less', None: 'none' }}
|
||||
setChoice={(choice) =>
|
||||
changeInAppNotificationSettings(
|
||||
choice as notification_subscribe_types
|
||||
)
|
||||
}
|
||||
className={'col-span-4 p-2'}
|
||||
toggleClassName={'w-24'}
|
||||
/>
|
||||
<div className={'mt-4 text-sm'}>
|
||||
<div>
|
||||
<div className={''}>
|
||||
You will receive notifications for:
|
||||
<NotificationSettingLine
|
||||
label={"Resolution of questions you've interacted with"}
|
||||
highlight={notificationSettings !== 'none'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
highlight={notificationSettings !== 'none'}
|
||||
label={'Activity on your own questions, comments, & answers'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
highlight={notificationSettings !== 'none'}
|
||||
label={"Activity on questions you're betting on"}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
highlight={notificationSettings !== 'none'}
|
||||
label={"Income & referral bonuses you've received"}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
label={"Activity on questions you've ever bet or commented on"}
|
||||
highlight={notificationSettings === 'all'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'mt-4'}>Email Notifications</div>
|
||||
<ChoicesToggleGroup
|
||||
currentChoice={emailNotificationSettings}
|
||||
choicesMap={{ All: 'all', Less: 'less', None: 'none' }}
|
||||
setChoice={(choice) =>
|
||||
changeEmailNotifications(choice as notification_subscribe_types)
|
||||
}
|
||||
className={'col-span-4 p-2'}
|
||||
toggleClassName={'w-24'}
|
||||
/>
|
||||
<div className={'mt-4 text-sm'}>
|
||||
<div>
|
||||
You will receive emails for:
|
||||
<NotificationSettingLine
|
||||
label={"Resolution of questions you're betting on"}
|
||||
highlight={emailNotificationSettings !== 'none'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
label={'Closure of your questions'}
|
||||
highlight={emailNotificationSettings !== 'none'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
label={'Activity on your questions'}
|
||||
highlight={emailNotificationSettings === 'all'}
|
||||
/>
|
||||
<NotificationSettingLine
|
||||
label={"Activity on questions you've answered or commented on"}
|
||||
highlight={emailNotificationSettings === 'all'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user