import { usePrivateUser } from 'web/hooks/use-user' import React, { ReactNode, useEffect, useState } from 'react' import { LoadingIndicator } from 'web/components/loading-indicator' import { Row } from 'web/components/layout/row' import clsx from 'clsx' import { exhaustive_notification_subscribe_types, notification_destination_types, } from 'common/user' import { updatePrivateUser } from 'web/lib/firebase/users' import { Switch } from '@headlessui/react' import { Col } from 'web/components/layout/col' import { AdjustmentsIcon, CashIcon, ChatIcon, ChevronDownIcon, ChevronUpIcon, InformationCircleIcon, LightBulbIcon, TrendingUpIcon, UserIcon, } from '@heroicons/react/outline' import { WatchMarketModal } from 'web/components/contract/watch-market-modal' import { filterDefined } from 'common/util/array' import toast from 'react-hot-toast' export function NotificationSettings() { const privateUser = usePrivateUser() const [showWatchModal, setShowWatchModal] = useState(false) if (!privateUser || !privateUser.notificationSubscriptionTypes) { return } // should be keyof Partial[] but can't figure out how to make that work // TODO: re-enable emails for renamed subscribe types const emailsEnabled = [ // 'all_comments', // 'all_answers', // 'resolutions', 'all_replies_to_my_comments', 'all_replies_to_my_answers', 'all_comments_on_my_markets', 'all_answers_on_my_markets', 'my_markets_closed', 'probability_updates', 'user_tagged_you', 'new_markets_by_followed_users', 'trending_markets', 'profit_loss_updates', 'all_comments_on_contracts_with_shares_in', 'all_answers_on_contracts_with_shares_in', ] const browserDisabled = ['trending_markets', 'profit_loss_updates'] const watched_markets_explanations_comments: { [key in keyof Partial]: string } = { all_comments_on_watched_markets: 'All', all_replies_to_my_comments_on_watched_markets: 'Replies to your comments', all_comments_on_contracts_with_shares_in_on_watched_markets: 'On markets you have shares in', // comments_by_followed_users_on_watched_markets: 'By followed users', } const watched_markets_explanations_answers: { [key in keyof Partial]: string } = { all_answers_on_watched_markets: 'All', all_replies_to_my_answers_on_watched_markets: 'Replies to your answers', all_answers_on_contracts_with_shares_in_on_watched_markets: 'On markets you have shares in', // answers_by_followed_users_on_watched_markets: 'By followed users', // answers_by_market_creator_on_watched_markets: 'By market creator', } const watched_markets_explanations_your_markets: { [key in keyof Partial]: string } = { my_markets_closed: 'Your market has closed (and needs resolution)', all_comments_on_my_markets: 'Comments on your markets', all_answers_on_my_markets: 'Answers on your markets', } const watched_markets_explanations_market_updates: { [key in keyof Partial]: string } = { resolutions_on_watched_markets: 'Market resolutions', market_updates_on_watched_markets: 'Updates made by the creator', // probability_updates_on_watched_markets: 'Probability updates', } const balance_change_explanations: { [key in keyof Partial]: string } = { loan_income: 'Automatic loans from your profitable bets', betting_streaks: 'Betting streak bonuses', referral_bonuses: 'Referral bonuses from referring users', unique_bettor_bonuses: 'Unique bettor bonuses on your markets', tips_on_your_comments: 'Tips on your comments', limit_order_fills: 'Limit order fills', } const general_explanations: { [key in keyof Partial]: string } = { user_tagged_you: 'A user tagged you', new_markets_by_followed_users: 'New markets created by users you follow', trending_markets: 'Weekly trending markets', new_followers: 'New followers', group_adds: 'When someone adds you to a group', // profit_loss_updates: 'Weekly profit/loss updates', } const NotificationSettingLine = ( description: string, key: string, value: notification_destination_types[] ) => { const previousInAppValue = value.includes('browser') const previousEmailValue = value.includes('email') const [inAppEnabled, setInAppEnabled] = useState(previousInAppValue) const [emailEnabled, setEmailEnabled] = useState(previousEmailValue) const loading = 'Changing Notifications Settings' const success = 'Changed Notification Settings!' useEffect(() => { if ( inAppEnabled !== previousInAppValue || emailEnabled !== previousEmailValue ) { toast.promise( updatePrivateUser(privateUser.id, { notificationSubscriptionTypes: { ...privateUser.notificationSubscriptionTypes, [key]: filterDefined([ inAppEnabled ? 'browser' : undefined, emailEnabled ? 'email' : undefined, ]), }, }), { success, loading, error: 'Error changing notification settings. Try again?', } ) } }, [ inAppEnabled, emailEnabled, previousInAppValue, previousEmailValue, key, ]) // for each entry in the exhaustive_notification_subscribe_types we'll want to load whether the user // wants email, browser, both, or none return ( {description} {!browserDisabled.includes(key) && ( In-app )} {emailsEnabled.includes(key) && ( Emails )} ) } const getUsersSavedPreference = (key: string) => { return Object.keys(privateUser.notificationSubscriptionTypes).includes(key) ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore privateUser.notificationSubscriptionTypes[ Object.keys(privateUser.notificationSubscriptionTypes).filter( (x) => x === key )[0] ] : '' } const Section = ( icon: ReactNode, label: string, map: { [key: string]: string } ) => { const [expanded, setExpanded] = useState(false) return ( setExpanded(!expanded)} > {icon} {label} {expanded ? ( Hide ) : ( Show )} {Object.entries(map).map(([key, value]) => NotificationSettingLine(value, key, getUsersSavedPreference(key)) )} ) } return (
Notifications for Watched Markets setShowWatchModal(true)} /> {/*// TODO: add none option to each section*/} {Section( , 'New Comments', watched_markets_explanations_comments )} {Section( , 'New Answers', watched_markets_explanations_answers )} {Section( , 'On Markets You Created', watched_markets_explanations_your_markets )} {Section( , 'Market Updates', watched_markets_explanations_market_updates )} Balance Changes {Section( , 'Loans and Bonuses', balance_change_explanations )} Other {Section( , 'General', general_explanations )}
) }