Show contract follow modal for first time following
This commit is contained in:
parent
597b208c28
commit
285ce1633a
|
@ -42,6 +42,7 @@ export type User = {
|
||||||
shouldShowWelcome?: boolean
|
shouldShowWelcome?: boolean
|
||||||
lastBetTime?: number
|
lastBetTime?: number
|
||||||
currentBettingStreak?: number
|
currentBettingStreak?: number
|
||||||
|
hasSeenContractFollowModal?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PrivateUser = {
|
export type PrivateUser = {
|
||||||
|
|
|
@ -23,7 +23,7 @@ service cloud.firestore {
|
||||||
allow read;
|
allow read;
|
||||||
allow update: if userId == request.auth.uid
|
allow update: if userId == request.auth.uid
|
||||||
&& request.resource.data.diff(resource.data).affectedKeys()
|
&& request.resource.data.diff(resource.data).affectedKeys()
|
||||||
.hasOnly(['bio', 'bannerUrl', 'website', 'twitterHandle', 'discordHandle', 'followedCategories', 'lastPingTime','shouldShowWelcome']);
|
.hasOnly(['bio', 'bannerUrl', 'website', 'twitterHandle', 'discordHandle', 'followedCategories', 'lastPingTime','shouldShowWelcome', 'hasSeenContractFollowModal']);
|
||||||
// User referral rules
|
// User referral rules
|
||||||
allow update: if userId == request.auth.uid
|
allow update: if userId == request.auth.uid
|
||||||
&& request.resource.data.diff(resource.data).affectedKeys()
|
&& request.resource.data.diff(resource.data).affectedKeys()
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { Row } from 'web/components/layout/row'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { CheckIcon, XIcon } from '@heroicons/react/outline'
|
import { CheckIcon, XIcon } from '@heroicons/react/outline'
|
||||||
import { ChoicesToggleGroup } from 'web/components/choices-toggle-group'
|
import { ChoicesToggleGroup } from 'web/components/choices-toggle-group'
|
||||||
|
import { Col } from 'web/components/layout/col'
|
||||||
|
import { FollowMarketModal } from 'web/components/contract/follow-market-modal'
|
||||||
|
|
||||||
export function NotificationSettings() {
|
export function NotificationSettings() {
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
|
@ -17,6 +19,7 @@ export function NotificationSettings() {
|
||||||
const [emailNotificationSettings, setEmailNotificationSettings] =
|
const [emailNotificationSettings, setEmailNotificationSettings] =
|
||||||
useState<notification_subscribe_types>('all')
|
useState<notification_subscribe_types>('all')
|
||||||
const [privateUser, setPrivateUser] = useState<PrivateUser | null>(null)
|
const [privateUser, setPrivateUser] = useState<PrivateUser | null>(null)
|
||||||
|
const [showModal, setShowModal] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user) listenForPrivateUser(user.id, setPrivateUser)
|
if (user) listenForPrivateUser(user.id, setPrivateUser)
|
||||||
|
@ -121,12 +124,20 @@ export function NotificationSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function NotificationSettingLine(props: {
|
function NotificationSettingLine(props: {
|
||||||
label: string
|
label: string | React.ReactNode
|
||||||
highlight: boolean
|
highlight: boolean
|
||||||
|
onClick?: () => void
|
||||||
}) {
|
}) {
|
||||||
const { label, highlight } = props
|
const { label, highlight, onClick } = props
|
||||||
return (
|
return (
|
||||||
<Row className={clsx('my-1 text-gray-300', highlight && '!text-black')}>
|
<Row
|
||||||
|
className={clsx(
|
||||||
|
'my-1 gap-1 text-gray-300',
|
||||||
|
highlight && '!text-black',
|
||||||
|
onClick ? 'cursor-pointer' : ''
|
||||||
|
)}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
{highlight ? <CheckIcon height={20} /> : <XIcon height={20} />}
|
{highlight ? <CheckIcon height={20} /> : <XIcon height={20} />}
|
||||||
{label}
|
{label}
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -148,31 +159,45 @@ export function NotificationSettings() {
|
||||||
toggleClassName={'w-24'}
|
toggleClassName={'w-24'}
|
||||||
/>
|
/>
|
||||||
<div className={'mt-4 text-sm'}>
|
<div className={'mt-4 text-sm'}>
|
||||||
<div>
|
<Col className={''}>
|
||||||
<div className={''}>
|
<Row className={'my-1'}>
|
||||||
You will receive notifications for:
|
You will receive notifications for these general events:
|
||||||
<NotificationSettingLine
|
</Row>
|
||||||
label={"Resolution of questions you've interacted with"}
|
<NotificationSettingLine
|
||||||
highlight={notificationSettings !== 'none'}
|
highlight={notificationSettings !== 'none'}
|
||||||
/>
|
label={"Income & referral bonuses you've received"}
|
||||||
<NotificationSettingLine
|
/>
|
||||||
highlight={notificationSettings !== 'none'}
|
<Row className={'my-1'}>
|
||||||
label={'Activity on your own questions, comments, & answers'}
|
You will receive new comment, answer, & resolution notifications on
|
||||||
/>
|
questions:
|
||||||
<NotificationSettingLine
|
</Row>
|
||||||
highlight={notificationSettings !== 'none'}
|
<NotificationSettingLine
|
||||||
label={"Activity on questions you're betting on"}
|
highlight={notificationSettings !== 'none'}
|
||||||
/>
|
label={
|
||||||
<NotificationSettingLine
|
<span>
|
||||||
highlight={notificationSettings !== 'none'}
|
That <span className={'font-bold'}>you follow </span>- you
|
||||||
label={"Income & referral bonuses you've received"}
|
auto-follow questions if:
|
||||||
/>
|
</span>
|
||||||
<NotificationSettingLine
|
}
|
||||||
label={"Activity on questions you've ever bet or commented on"}
|
onClick={() => setShowModal(true)}
|
||||||
highlight={notificationSettings === 'all'}
|
/>
|
||||||
/>
|
<Col
|
||||||
</div>
|
className={clsx(
|
||||||
</div>
|
'mb-2 ml-8',
|
||||||
|
'gap-1 text-gray-300',
|
||||||
|
notificationSettings !== 'none' && '!text-black'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Row>• You create it</Row>
|
||||||
|
<Row>• You bet, comment on, or answer it</Row>
|
||||||
|
<Row>• You add liquidity to it</Row>
|
||||||
|
<Row>
|
||||||
|
• If you select 'Less' and you've commented on or answered a
|
||||||
|
question, you'll only receive notification on direct replies to
|
||||||
|
your comments or answers
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
</Col>
|
||||||
</div>
|
</div>
|
||||||
<div className={'mt-4'}>Email Notifications</div>
|
<div className={'mt-4'}>Email Notifications</div>
|
||||||
<ChoicesToggleGroup
|
<ChoicesToggleGroup
|
||||||
|
@ -205,6 +230,7 @@ export function NotificationSettings() {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<FollowMarketModal setOpen={setShowModal} open={showModal} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
33
web/components/contract/follow-market-modal.tsx
Normal file
33
web/components/contract/follow-market-modal.tsx
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { Col } from 'web/components/layout/col'
|
||||||
|
import { Modal } from 'web/components/layout/modal'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export const FollowMarketModal = (props: {
|
||||||
|
open: boolean
|
||||||
|
setOpen: (b: boolean) => void
|
||||||
|
title?: string
|
||||||
|
}) => {
|
||||||
|
const { open, setOpen, title } = props
|
||||||
|
return (
|
||||||
|
<Modal open={open} setOpen={setOpen}>
|
||||||
|
<Col className="items-center gap-4 rounded-md bg-white px-8 py-6">
|
||||||
|
<span className={'text-8xl'}>❤️</span>
|
||||||
|
<span className="text-xl">{title ? title : 'Following questions'}</span>
|
||||||
|
<Col className={'gap-2'}>
|
||||||
|
<span className={'text-indigo-700'}>• What is following?</span>
|
||||||
|
<span className={'ml-2'}>
|
||||||
|
You can receive notifications on questions you're interested in by
|
||||||
|
clicking the ❤️ button on a question.
|
||||||
|
</span>
|
||||||
|
<span className={'text-indigo-700'}>
|
||||||
|
• What types of notifications will I receive?
|
||||||
|
</span>
|
||||||
|
<span className={'ml-2'}>
|
||||||
|
You'll receive in-app notifications for new comments, answers, and
|
||||||
|
updates to the question.
|
||||||
|
</span>
|
||||||
|
</Col>
|
||||||
|
</Col>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
|
@ -9,8 +9,10 @@ import { CheckIcon, HeartIcon } from '@heroicons/react/outline'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { useContractFollows } from 'web/hooks/use-follows'
|
import { useContractFollows } from 'web/hooks/use-follows'
|
||||||
import { firebaseLogin } from 'web/lib/firebase/users'
|
import { firebaseLogin, updateUser } from 'web/lib/firebase/users'
|
||||||
import { track } from 'web/lib/service/analytics'
|
import { track } from 'web/lib/service/analytics'
|
||||||
|
import { FollowMarketModal } from 'web/components/contract/follow-market-modal'
|
||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
export const FollowMarketButton = (props: {
|
export const FollowMarketButton = (props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
|
@ -18,6 +20,7 @@ export const FollowMarketButton = (props: {
|
||||||
}) => {
|
}) => {
|
||||||
const { contract, user } = props
|
const { contract, user } = props
|
||||||
const followers = useContractFollows(contract.id)
|
const followers = useContractFollows(contract.id)
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
@ -42,6 +45,12 @@ export const FollowMarketButton = (props: {
|
||||||
slug: contract.slug,
|
slug: contract.slug,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if (!user.hasSeenContractFollowModal) {
|
||||||
|
await updateUser(user.id, {
|
||||||
|
hasSeenContractFollowModal: true,
|
||||||
|
})
|
||||||
|
setOpen(true)
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{followers?.includes(user?.id ?? 'nope') ? (
|
{followers?.includes(user?.id ?? 'nope') ? (
|
||||||
|
@ -55,6 +64,13 @@ export const FollowMarketButton = (props: {
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<FollowMarketModal
|
||||||
|
open={open}
|
||||||
|
setOpen={setOpen}
|
||||||
|
title={`You ${
|
||||||
|
followers?.includes(user?.id ?? 'nope') ? 'followed' : 'unfollowed'
|
||||||
|
} a question!`}
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,6 +147,7 @@ export function useUnseenPreferredNotifications(
|
||||||
const lessPriorityReasons = [
|
const lessPriorityReasons = [
|
||||||
'on_contract_with_users_comment',
|
'on_contract_with_users_comment',
|
||||||
'on_contract_with_users_answer',
|
'on_contract_with_users_answer',
|
||||||
|
// Notifications not currently generated for users who've sold their shares
|
||||||
'on_contract_with_users_shares_out',
|
'on_contract_with_users_shares_out',
|
||||||
// Not sure if users will want to see these w/ less:
|
// Not sure if users will want to see these w/ less:
|
||||||
// 'on_contract_with_users_shares_in',
|
// 'on_contract_with_users_shares_in',
|
||||||
|
|
Loading…
Reference in New Issue
Block a user