It's alive... It's alive, it's moving, it's alive, it's alive, it's alive, it's alive, IT'S ALIVE'
This commit is contained in:
parent
9c8d4c8d94
commit
06467dc1d7
|
@ -1,4 +1,4 @@
|
|||
import { exhaustive_notification_subscribe_types } from 'common/user'
|
||||
import { notification_subscription_types } from 'common/user'
|
||||
|
||||
export type Notification = {
|
||||
id: string
|
||||
|
@ -55,26 +55,17 @@ export type notification_source_update_types =
|
|||
|
||||
export type notification_reason_types =
|
||||
| 'tagged_user'
|
||||
// | 'on_users_contract'
|
||||
// | 'on_contract_with_users_shares_in'
|
||||
// | 'on_contract_with_users_shares_out'
|
||||
// | 'on_contract_with_users_answer'
|
||||
// | 'on_contract_with_users_comment'
|
||||
| 'on_new_follow'
|
||||
| 'contract_from_followed_user'
|
||||
| 'added_you_to_group'
|
||||
| 'you_referred_user'
|
||||
| 'user_joined_to_bet_on_your_market'
|
||||
| 'unique_bettors_on_your_contract'
|
||||
// | 'on_group_you_are_member_of'
|
||||
| 'tip_received'
|
||||
| 'bet_fill'
|
||||
| 'user_joined_from_your_group_invite'
|
||||
| 'challenge_accepted'
|
||||
| 'betting_streak_incremented'
|
||||
| 'loan_income'
|
||||
// | 'you_follow_contract'
|
||||
| 'liked_your_contract'
|
||||
| 'liked_and_tipped_your_contract'
|
||||
| 'comment_on_your_contract'
|
||||
| 'answer_on_your_contract'
|
||||
|
@ -97,25 +88,19 @@ export type notification_reason_types =
|
|||
| 'reply_to_users_answer'
|
||||
| 'reply_to_users_comment'
|
||||
| 'your_contract_closed'
|
||||
| 'subsidized_your_market'
|
||||
|
||||
export const notificationReasonToSubscribeTypeMap: Record<
|
||||
notification_reason_types,
|
||||
keyof exhaustive_notification_subscribe_types
|
||||
// Adding a new key:value here is optional, you can also just use a key of exhaustive_notification_subscribe_types
|
||||
export const notificationReasonToSubscriptionType: Partial<
|
||||
Record<notification_reason_types, keyof notification_subscription_types>
|
||||
> = {
|
||||
tagged_user: 'user_tagged_you',
|
||||
on_new_follow: 'new_followers',
|
||||
contract_from_followed_user: 'new_markets_by_followed_users',
|
||||
added_you_to_group: 'group_adds',
|
||||
you_referred_user: 'referral_bonuses',
|
||||
user_joined_to_bet_on_your_market: 'referral_bonuses',
|
||||
unique_bettors_on_your_contract: 'unique_bettor_bonuses',
|
||||
tip_received: 'tips_on_your_comments',
|
||||
bet_fill: 'limit_order_fills',
|
||||
user_joined_from_your_group_invite: 'referral_bonuses',
|
||||
challenge_accepted: 'limit_order_fills',
|
||||
betting_streak_incremented: 'betting_streaks',
|
||||
loan_income: 'loan_income',
|
||||
liked_your_contract: 'tips_on_your_markets',
|
||||
liked_and_tipped_your_contract: 'tips_on_your_markets',
|
||||
comment_on_your_contract: 'all_comments_on_my_markets',
|
||||
answer_on_your_contract: 'all_answers_on_my_markets',
|
||||
|
@ -128,7 +113,7 @@ export const notificationReasonToSubscribeTypeMap: Record<
|
|||
answer_on_contract_with_users_shares_in:
|
||||
'all_answers_on_contracts_with_shares_in_on_watched_markets',
|
||||
update_on_contract_with_users_shares_in:
|
||||
'market_updates_with_shares_in_on_watched_markets',
|
||||
'market_updates_on_watched_markets_with_shares_in',
|
||||
resolution_on_contract_with_users_shares_in:
|
||||
'resolutions_on_watched_markets_with_shares_in',
|
||||
comment_on_contract_with_users_answer: 'all_comments_on_watched_markets',
|
||||
|
@ -141,5 +126,4 @@ export const notificationReasonToSubscribeTypeMap: Record<
|
|||
resolution_on_contract_with_users_comment: 'resolutions_on_watched_markets',
|
||||
reply_to_users_answer: 'all_replies_to_my_answers_on_watched_markets',
|
||||
reply_to_users_comment: 'all_replies_to_my_comments_on_watched_markets',
|
||||
your_contract_closed: 'my_markets_closed',
|
||||
}
|
||||
|
|
|
@ -66,12 +66,12 @@ export type PrivateUser = {
|
|||
initialIpAddress?: string
|
||||
apiKey?: string
|
||||
notificationPreferences?: notification_subscribe_types
|
||||
notificationSubscriptionTypes: exhaustive_notification_subscribe_types
|
||||
notificationSubscriptionTypes: notification_subscription_types
|
||||
}
|
||||
|
||||
export type notification_destination_types = 'email' | 'browser'
|
||||
|
||||
export type exhaustive_notification_subscribe_types = {
|
||||
export type notification_subscription_types = {
|
||||
// Watched Markets
|
||||
all_comments_on_watched_markets: notification_destination_types[] // Email currently - seems bad
|
||||
all_answers_on_watched_markets: notification_destination_types[] // Email currently - seems bad
|
||||
|
@ -89,31 +89,31 @@ export type exhaustive_notification_subscribe_types = {
|
|||
all_answers_on_contracts_with_shares_in_on_watched_markets: notification_destination_types[]
|
||||
|
||||
// On users' markets
|
||||
my_markets_closed: notification_destination_types[] // Email, Recommended
|
||||
your_contract_closed: notification_destination_types[] // Email, Recommended
|
||||
all_comments_on_my_markets: notification_destination_types[] // Email
|
||||
all_answers_on_my_markets: notification_destination_types[] // Email
|
||||
subsidized_your_market: notification_destination_types[] // Email
|
||||
|
||||
// Market updates
|
||||
resolutions_on_watched_markets: notification_destination_types[] // Email
|
||||
resolutions_on_watched_markets_with_shares_in: notification_destination_types[] // Email
|
||||
market_updates_on_watched_markets: notification_destination_types[]
|
||||
market_updates_with_shares_in_on_watched_markets: notification_destination_types[]
|
||||
market_updates_on_watched_markets_with_shares_in: notification_destination_types[]
|
||||
probability_updates_on_watched_markets: notification_destination_types[] // Email - would want persistent changes only though
|
||||
|
||||
// Balance Changes
|
||||
loan_income: notification_destination_types[]
|
||||
betting_streaks: notification_destination_types[]
|
||||
referral_bonuses: notification_destination_types[]
|
||||
unique_bettor_bonuses: notification_destination_types[]
|
||||
unique_bettors_on_your_contract: notification_destination_types[]
|
||||
tips_on_your_comments: notification_destination_types[]
|
||||
tips_on_your_markets: notification_destination_types[]
|
||||
limit_order_fills: notification_destination_types[]
|
||||
|
||||
// General
|
||||
user_tagged_you: notification_destination_types[] // Email
|
||||
new_followers: notification_destination_types[] // Email
|
||||
group_adds: notification_destination_types[] // Email
|
||||
new_markets_by_followed_users: notification_destination_types[] // Email
|
||||
tagged_user: notification_destination_types[] // Email
|
||||
on_new_follow: notification_destination_types[] // Email
|
||||
contract_from_followed_user: notification_destination_types[] // Email
|
||||
trending_markets: notification_destination_types[] // Email
|
||||
profit_loss_updates: notification_destination_types[] // Email
|
||||
}
|
||||
|
@ -169,15 +169,15 @@ export const getDefaultNotificationSettings = (
|
|||
comments_by_followed_users_on_watched_markets: constructPref(
|
||||
wantsAll,
|
||||
false
|
||||
), //wantsAll ? browserOnly : none,
|
||||
),
|
||||
all_replies_to_my_comments_on_watched_markets: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
!unsubscribedFromCommentEmails
|
||||
), //wantsAll || wantsLess ? both : none,
|
||||
),
|
||||
all_replies_to_my_answers_on_watched_markets: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
!unsubscribedFromCommentEmails
|
||||
), //wantsAll || wantsLess ? both : none,
|
||||
),
|
||||
all_comments_on_contracts_with_shares_in_on_watched_markets: constructPref(
|
||||
wantsAll,
|
||||
!unsubscribedFromCommentEmails
|
||||
|
@ -187,29 +187,30 @@ export const getDefaultNotificationSettings = (
|
|||
answers_by_followed_users_on_watched_markets: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
!unsubscribedFromAnswerEmails
|
||||
), //wantsAll || wantsLess ? both : none,
|
||||
),
|
||||
answers_by_market_creator_on_watched_markets: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
!unsubscribedFromAnswerEmails
|
||||
), //wantsAll || wantsLess ? both : none,
|
||||
),
|
||||
all_answers_on_contracts_with_shares_in_on_watched_markets: constructPref(
|
||||
wantsAll,
|
||||
!unsubscribedFromAnswerEmails
|
||||
),
|
||||
|
||||
// On users' markets
|
||||
my_markets_closed: constructPref(
|
||||
your_contract_closed: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
!unsubscribedFromResolutionEmails
|
||||
), //wantsAll || wantsLess ? both : none, // High priority
|
||||
), // High priority
|
||||
all_comments_on_my_markets: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
!unsubscribedFromCommentEmails
|
||||
), //wantsAll || wantsLess ? both : none,
|
||||
),
|
||||
all_answers_on_my_markets: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
!unsubscribedFromAnswerEmails
|
||||
), //wantsAll || wantsLess ? both : none,
|
||||
),
|
||||
subsidized_your_market: constructPref(wantsAll || wantsLess, true),
|
||||
|
||||
// Market updates
|
||||
resolutions_on_watched_markets: constructPref(
|
||||
|
@ -220,7 +221,7 @@ export const getDefaultNotificationSettings = (
|
|||
wantsAll || wantsLess,
|
||||
false
|
||||
),
|
||||
market_updates_with_shares_in_on_watched_markets: constructPref(
|
||||
market_updates_on_watched_markets_with_shares_in: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
false
|
||||
),
|
||||
|
@ -233,7 +234,10 @@ export const getDefaultNotificationSettings = (
|
|||
loan_income: constructPref(wantsAll || wantsLess, false),
|
||||
betting_streaks: constructPref(wantsAll || wantsLess, false),
|
||||
referral_bonuses: constructPref(wantsAll || wantsLess, true),
|
||||
unique_bettor_bonuses: constructPref(wantsAll || wantsLess, false),
|
||||
unique_bettors_on_your_contract: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
false
|
||||
),
|
||||
tipped_comments_on_watched_markets: constructPref(
|
||||
wantsAll || wantsLess,
|
||||
!unsubscribedFromCommentEmails
|
||||
|
@ -242,9 +246,9 @@ export const getDefaultNotificationSettings = (
|
|||
limit_order_fills: constructPref(wantsAll || wantsLess, false),
|
||||
|
||||
// General
|
||||
user_tagged_you: constructPref(wantsAll || wantsLess, true), //wantsAll || wantsLess ? both : none,
|
||||
new_followers: constructPref(wantsAll || wantsLess, true),
|
||||
new_markets_by_followed_users: constructPref(wantsAll || wantsLess, true), //wantsAll || wantsLess ? both : none,
|
||||
tagged_user: constructPref(wantsAll || wantsLess, true),
|
||||
on_new_follow: constructPref(wantsAll || wantsLess, true),
|
||||
contract_from_followed_user: constructPref(wantsAll || wantsLess, true),
|
||||
trending_markets: constructPref(
|
||||
false,
|
||||
!unsubscribedFromWeeklyTrendingEmails
|
||||
|
@ -254,6 +258,5 @@ export const getDefaultNotificationSettings = (
|
|||
wantsAll || wantsLess,
|
||||
false
|
||||
),
|
||||
group_adds: constructPref(wantsAll || wantsLess, true),
|
||||
} as exhaustive_notification_subscribe_types
|
||||
} as notification_subscription_types
|
||||
}
|
||||
|
|
|
@ -2,11 +2,9 @@ import * as admin from 'firebase-admin'
|
|||
import {
|
||||
Notification,
|
||||
notification_reason_types,
|
||||
notification_source_update_types,
|
||||
notification_source_types,
|
||||
notificationReasonToSubscribeTypeMap,
|
||||
notificationReasonToSubscriptionType,
|
||||
} from '../../common/notification'
|
||||
import { User } from '../../common/user'
|
||||
import { notification_subscription_types, User } from '../../common/user'
|
||||
import { Contract } from '../../common/contract'
|
||||
import { getPrivateUser, getValues } from './utils'
|
||||
import { Comment } from '../../common/comment'
|
||||
|
@ -20,6 +18,7 @@ import { Group } from '../../common/group'
|
|||
import { Challenge } from '../../common/challenge'
|
||||
import { Like } from '../../common/like'
|
||||
import {
|
||||
sendMarketCloseEmail,
|
||||
sendMarketResolutionEmail,
|
||||
sendNewAnswerEmail,
|
||||
sendNewCommentEmail,
|
||||
|
@ -32,8 +31,8 @@ type recipients_to_reason_texts = {
|
|||
|
||||
export const createNotification = async (
|
||||
sourceId: string,
|
||||
sourceType: notification_source_types,
|
||||
sourceUpdateType: notification_source_update_types,
|
||||
sourceType: 'contract' | 'liquidity' | 'follow',
|
||||
sourceUpdateType: 'closed' | 'created',
|
||||
sourceUser: User,
|
||||
idempotencyKey: string,
|
||||
sourceText: string,
|
||||
|
@ -56,15 +55,14 @@ export const createNotification = async (
|
|||
)
|
||||
}
|
||||
|
||||
const createUsersNotifications = async (
|
||||
const sendNotificationsIfSettingsPermit = async (
|
||||
userToReasonTexts: recipients_to_reason_texts
|
||||
) => {
|
||||
await Promise.all(
|
||||
Object.keys(userToReasonTexts).map(async (userId) => {
|
||||
for (const userId in userToReasonTexts) {
|
||||
const { reason } = userToReasonTexts[userId]
|
||||
const { sendToBrowser } = await getDestinationsForUser(userId, reason)
|
||||
if (!sendToBrowser) return Promise.resolve()
|
||||
|
||||
const { sendToBrowser, sendToEmail, privateUser } =
|
||||
await getDestinationsForUser(userId, reason)
|
||||
if (sendToBrowser) {
|
||||
const notificationRef = firestore
|
||||
.collection(`/users/${userId}/notifications`)
|
||||
.doc(idempotencyKey)
|
||||
|
@ -89,8 +87,22 @@ export const createNotification = async (
|
|||
sourceTitle: title ? title : sourceContract?.question,
|
||||
}
|
||||
await notificationRef.set(removeUndefinedProps(notification))
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (!sendToEmail) continue
|
||||
|
||||
if (reason === 'your_contract_closed' && privateUser && sourceContract) {
|
||||
await sendMarketCloseEmail(sourceUser, privateUser, sourceContract)
|
||||
} else if (reason === 'tagged_user') {
|
||||
// TODO: send email to tagged user in new contract
|
||||
} else if (reason === 'subsidized_your_market') {
|
||||
// TODO: send email to creator of market that was subsidized
|
||||
} else if (reason === 'contract_from_followed_user') {
|
||||
// TODO: send email to follower of user who created market
|
||||
} else if (reason === 'on_new_follow') {
|
||||
// TODO: send email to user who was followed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const notifyUsersFollowers = async (
|
||||
|
@ -146,31 +158,18 @@ export const createNotification = async (
|
|||
shouldGetNotification(sourceContract.creatorId, userToReasonTexts)
|
||||
)
|
||||
userToReasonTexts[sourceContract.creatorId] = {
|
||||
reason: 'your_contract_closed',
|
||||
reason:
|
||||
sourceType === 'liquidity'
|
||||
? 'subsidized_your_market'
|
||||
: 'your_contract_closed',
|
||||
}
|
||||
}
|
||||
|
||||
const notifyUserAddedToGroup = (
|
||||
userToReasonTexts: recipients_to_reason_texts,
|
||||
relatedUserId: string
|
||||
) => {
|
||||
if (shouldGetNotification(relatedUserId, userToReasonTexts))
|
||||
userToReasonTexts[relatedUserId] = {
|
||||
reason: 'added_you_to_group',
|
||||
}
|
||||
}
|
||||
|
||||
const userToReasonTexts: recipients_to_reason_texts = {}
|
||||
// The following functions modify the userToReasonTexts object in place.
|
||||
const userToReasonTexts: recipients_to_reason_texts = {}
|
||||
|
||||
if (sourceType === 'follow' && recipients?.[0]) {
|
||||
notifyFollowedUser(userToReasonTexts, recipients[0])
|
||||
} else if (
|
||||
sourceType === 'group' &&
|
||||
sourceUpdateType === 'created' &&
|
||||
recipients
|
||||
) {
|
||||
recipients.forEach((r) => notifyUserAddedToGroup(userToReasonTexts, r))
|
||||
} else if (
|
||||
sourceType === 'contract' &&
|
||||
sourceUpdateType === 'created' &&
|
||||
|
@ -194,27 +193,33 @@ export const createNotification = async (
|
|||
await notifyContractCreator(userToReasonTexts, sourceContract)
|
||||
}
|
||||
|
||||
await createUsersNotifications(userToReasonTexts)
|
||||
await sendNotificationsIfSettingsPermit(userToReasonTexts)
|
||||
}
|
||||
|
||||
const getDestinationsForUser = async (
|
||||
userId: string,
|
||||
reason: notification_reason_types
|
||||
reason: notification_reason_types | keyof notification_subscription_types
|
||||
) => {
|
||||
const privateUser = await getPrivateUser(userId)
|
||||
if (!privateUser) return { sendToEmail: false, sendToBrowser: false }
|
||||
if (!privateUser)
|
||||
return { sendToEmail: false, sendToBrowser: false, privateUser: null }
|
||||
|
||||
const notificationSettings = privateUser.notificationSubscriptionTypes
|
||||
console.log('notificationSettings', notificationSettings)
|
||||
console.log('reason', reason)
|
||||
console.log('notif reason to type map', notificationReasonToSubscribeTypeMap)
|
||||
const subscribeType = notificationReasonToSubscribeTypeMap[reason]
|
||||
console.log('subscribeType', subscribeType)
|
||||
const destinations =
|
||||
notificationSettings[notificationReasonToSubscribeTypeMap[reason]]
|
||||
console.log('destinations', destinations)
|
||||
let destinations
|
||||
if (Object.keys(notificationSettings).includes(reason)) {
|
||||
const key = reason as keyof notification_subscription_types
|
||||
destinations = notificationSettings[key]
|
||||
} else {
|
||||
const key = reason as notification_reason_types
|
||||
const subscriptionType = notificationReasonToSubscriptionType[key]
|
||||
destinations = subscriptionType
|
||||
? notificationSettings[subscriptionType]
|
||||
: []
|
||||
}
|
||||
return {
|
||||
sendToEmail: destinations.includes('email'),
|
||||
sendToBrowser: destinations.includes('browser'),
|
||||
privateUser,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,21 +468,20 @@ export const createCommentOrAnswerOrUpdatedContractNotification = async (
|
|||
)
|
||||
}
|
||||
|
||||
const notifyRepliedUser = async (
|
||||
relatedUserId: string,
|
||||
relatedSourceType: notification_source_types
|
||||
) => {
|
||||
const notifyRepliedUser = async () => {
|
||||
if (sourceType === 'comment' && repliedUserId && repliedToType)
|
||||
await sendNotificationsIfSettingsPermit(
|
||||
relatedUserId,
|
||||
relatedSourceType === 'answer'
|
||||
repliedUserId,
|
||||
repliedToType === 'answer'
|
||||
? 'reply_to_users_answer'
|
||||
: 'reply_to_users_comment'
|
||||
)
|
||||
}
|
||||
|
||||
const notifyTaggedUsers = async (userIds: string[]) => {
|
||||
const notifyTaggedUsers = async () => {
|
||||
if (sourceType === 'comment' && taggedUserIds && taggedUserIds.length > 0)
|
||||
await Promise.all(
|
||||
userIds.map((userId) =>
|
||||
taggedUserIds.map((userId) =>
|
||||
sendNotificationsIfSettingsPermit(userId, 'tagged_user')
|
||||
)
|
||||
)
|
||||
|
@ -506,11 +510,8 @@ export const createCommentOrAnswerOrUpdatedContractNotification = async (
|
|||
)
|
||||
}
|
||||
|
||||
if (sourceType === 'comment') {
|
||||
if (repliedUserId && repliedToType)
|
||||
await notifyRepliedUser(repliedUserId, repliedToType)
|
||||
await notifyTaggedUsers(taggedUserIds ?? [])
|
||||
}
|
||||
await notifyRepliedUser()
|
||||
await notifyTaggedUsers()
|
||||
await notifyContractCreator()
|
||||
await notifyOtherAnswerersOnContract()
|
||||
await notifyLiquidityProviders()
|
||||
|
@ -559,6 +560,8 @@ export const createTipNotification = async (
|
|||
sourceTitle: group?.name,
|
||||
}
|
||||
return await notificationRef.set(removeUndefinedProps(notification))
|
||||
|
||||
// maybe TODO: send email notification to bet creator
|
||||
}
|
||||
|
||||
export const createBetFillNotification = async (
|
||||
|
@ -597,6 +600,8 @@ export const createBetFillNotification = async (
|
|||
sourceContractId: contract.id,
|
||||
}
|
||||
return await notificationRef.set(removeUndefinedProps(notification))
|
||||
|
||||
// maybe TODO: send email notification to bet creator
|
||||
}
|
||||
|
||||
export const createReferralNotification = async (
|
||||
|
@ -650,6 +655,8 @@ export const createReferralNotification = async (
|
|||
: referredByContract?.question,
|
||||
}
|
||||
await notificationRef.set(removeUndefinedProps(notification))
|
||||
|
||||
// TODO send email notification
|
||||
}
|
||||
|
||||
export const createLoanIncomeNotification = async (
|
||||
|
@ -779,13 +786,16 @@ export const createLikeNotification = async (
|
|||
)
|
||||
if (!sendToBrowser) return
|
||||
|
||||
// not handling just likes, must include tip
|
||||
if (!tip) return
|
||||
|
||||
const notificationRef = firestore
|
||||
.collection(`/users/${toUser.id}/notifications`)
|
||||
.doc(idempotencyKey)
|
||||
const notification: Notification = {
|
||||
id: idempotencyKey,
|
||||
userId: toUser.id,
|
||||
reason: tip ? 'liked_and_tipped_your_contract' : 'liked_your_contract',
|
||||
reason: 'liked_and_tipped_your_contract',
|
||||
createdTime: Date.now(),
|
||||
isSeen: false,
|
||||
sourceId: like.id,
|
||||
|
@ -802,20 +812,8 @@ export const createLikeNotification = async (
|
|||
sourceTitle: contract.question,
|
||||
}
|
||||
return await notificationRef.set(removeUndefinedProps(notification))
|
||||
}
|
||||
|
||||
export async function filterUserIdsForOnlyFollowerIds(
|
||||
userIds: string[],
|
||||
contractId: string
|
||||
) {
|
||||
// get contract follower documents and check here if they're a follower
|
||||
const contractFollowersSnap = await firestore
|
||||
.collection(`contracts/${contractId}/follows`)
|
||||
.get()
|
||||
const contractFollowersIds = contractFollowersSnap.docs.map(
|
||||
(doc) => doc.data().id
|
||||
)
|
||||
return userIds.filter((id) => contractFollowersIds.includes(id))
|
||||
// TODO send email notification
|
||||
}
|
||||
|
||||
export const createUniqueBettorBonusNotification = async (
|
||||
|
@ -857,4 +855,6 @@ export const createUniqueBettorBonusNotification = async (
|
|||
sourceContractCreatorUsername: contract.creatorUsername,
|
||||
}
|
||||
return await notificationRef.set(removeUndefinedProps(notification))
|
||||
|
||||
// TODO send email notification
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import * as admin from 'firebase-admin'
|
|||
|
||||
import { Contract } from '../../common/contract'
|
||||
import { getPrivateUser, getUserByUsername } from './utils'
|
||||
import { sendMarketCloseEmail } from './emails'
|
||||
import { createNotification } from './create-notification'
|
||||
|
||||
export const marketCloseNotifications = functions
|
||||
|
@ -56,7 +55,6 @@ async function sendMarketCloseEmails() {
|
|||
const privateUser = await getPrivateUser(user.id)
|
||||
if (!privateUser) continue
|
||||
|
||||
await sendMarketCloseEmail(user, privateUser, contract)
|
||||
await createNotification(
|
||||
contract.id,
|
||||
'contract',
|
||||
|
|
|
@ -4,7 +4,7 @@ import { LoadingIndicator } from 'web/components/loading-indicator'
|
|||
import { Row } from 'web/components/layout/row'
|
||||
import clsx from 'clsx'
|
||||
import {
|
||||
exhaustive_notification_subscribe_types,
|
||||
notification_subscription_types,
|
||||
notification_destination_types,
|
||||
} from 'common/user'
|
||||
import { updatePrivateUser } from 'web/lib/firebase/users'
|
||||
|
@ -33,29 +33,42 @@ export function NotificationSettings() {
|
|||
return <LoadingIndicator spinnerClassName={'border-gray-500 h-4 w-4'} />
|
||||
}
|
||||
|
||||
// should be keyof Partial<exhaustive_notification_subscribe_types>[] 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',
|
||||
const emailsEnabled: Array<keyof notification_subscription_types> = [
|
||||
'all_comments_on_watched_markets',
|
||||
'all_replies_to_my_comments_on_watched_markets',
|
||||
'all_comments_on_contracts_with_shares_in_on_watched_markets',
|
||||
|
||||
'all_answers_on_watched_markets',
|
||||
'all_replies_to_my_answers_on_watched_markets',
|
||||
'all_answers_on_contracts_with_shares_in_on_watched_markets',
|
||||
|
||||
'your_contract_closed',
|
||||
'all_comments_on_my_markets',
|
||||
'all_answers_on_my_markets',
|
||||
'my_markets_closed',
|
||||
'probability_updates',
|
||||
'user_tagged_you',
|
||||
'new_markets_by_followed_users',
|
||||
|
||||
'resolutions_on_watched_markets_with_shares_in',
|
||||
'resolutions_on_watched_markets',
|
||||
|
||||
'tagged_user',
|
||||
'trending_markets',
|
||||
'profit_loss_updates',
|
||||
'all_comments_on_contracts_with_shares_in',
|
||||
'all_answers_on_contracts_with_shares_in',
|
||||
|
||||
// TODO: add these
|
||||
// 'contract_from_followed_user',
|
||||
// 'referral_bonuses',
|
||||
// 'unique_bettors_on_your_contract',
|
||||
// 'tips_on_your_markets',
|
||||
// 'tips_on_your_comments',
|
||||
// 'subsidized_your_market',
|
||||
// 'on_new_follow',
|
||||
// maybe the following?
|
||||
// 'profit_loss_updates',
|
||||
// 'probability_updates_on_watched_markets',
|
||||
// 'limit_order_fills',
|
||||
]
|
||||
const browserDisabled = ['trending_markets', 'profit_loss_updates']
|
||||
|
||||
const watched_markets_explanations_comments: {
|
||||
[key in keyof Partial<exhaustive_notification_subscribe_types>]: string
|
||||
[key in keyof Partial<notification_subscription_types>]: string
|
||||
} = {
|
||||
all_comments_on_watched_markets: 'All',
|
||||
all_replies_to_my_comments_on_watched_markets: 'Replies to your comments',
|
||||
|
@ -64,7 +77,7 @@ export function NotificationSettings() {
|
|||
// comments_by_followed_users_on_watched_markets: 'By followed users',
|
||||
}
|
||||
const watched_markets_explanations_answers: {
|
||||
[key in keyof Partial<exhaustive_notification_subscribe_types>]: string
|
||||
[key in keyof Partial<notification_subscription_types>]: string
|
||||
} = {
|
||||
all_answers_on_watched_markets: 'All',
|
||||
all_replies_to_my_answers_on_watched_markets: 'Replies to your answers',
|
||||
|
@ -74,45 +87,49 @@ export function NotificationSettings() {
|
|||
// answers_by_market_creator_on_watched_markets: 'By market creator',
|
||||
}
|
||||
const watched_markets_explanations_your_markets: {
|
||||
[key in keyof Partial<exhaustive_notification_subscribe_types>]: string
|
||||
[key in keyof Partial<notification_subscription_types>]: string
|
||||
} = {
|
||||
my_markets_closed: 'Your market has closed (and needs resolution)',
|
||||
your_contract_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',
|
||||
subsidized_your_market: 'Your market was subsidized',
|
||||
}
|
||||
const watched_markets_explanations_market_updates: {
|
||||
[key in keyof Partial<exhaustive_notification_subscribe_types>]: string
|
||||
[key in keyof Partial<notification_subscription_types>]: string
|
||||
} = {
|
||||
resolutions_on_watched_markets: 'Market resolutions',
|
||||
resolutions_on_watched_markets_with_shares_in:
|
||||
'Market resolutions you have shares in',
|
||||
market_updates_on_watched_markets: 'Updates made by the creator',
|
||||
market_updates_on_watched_markets_with_shares_in:
|
||||
'Updates made by the creator on markets you have shares in',
|
||||
// probability_updates_on_watched_markets: 'Probability updates',
|
||||
}
|
||||
|
||||
const balance_change_explanations: {
|
||||
[key in keyof Partial<exhaustive_notification_subscribe_types>]: string
|
||||
[key in keyof Partial<notification_subscription_types>]: 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',
|
||||
unique_bettors_on_your_contract: '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<exhaustive_notification_subscribe_types>]: string
|
||||
[key in keyof Partial<notification_subscription_types>]: string
|
||||
} = {
|
||||
user_tagged_you: 'A user tagged you',
|
||||
new_markets_by_followed_users: 'New markets created by users you follow',
|
||||
tagged_user: 'A user tagged you',
|
||||
contract_from_followed_user: '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',
|
||||
on_new_follow: 'New followers',
|
||||
// profit_loss_updates: 'Weekly profit/loss updates',
|
||||
}
|
||||
|
||||
const NotificationSettingLine = (
|
||||
description: string,
|
||||
key: string,
|
||||
key: keyof notification_subscription_types,
|
||||
value: notification_destination_types[]
|
||||
) => {
|
||||
const previousInAppValue = value.includes('browser')
|
||||
|
@ -217,22 +234,18 @@ export function NotificationSettings() {
|
|||
)
|
||||
}
|
||||
|
||||
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 getUsersSavedPreference = (
|
||||
key: keyof notification_subscription_types
|
||||
) => {
|
||||
return privateUser.notificationSubscriptionTypes[key] ?? []
|
||||
}
|
||||
|
||||
const Section = (
|
||||
icon: ReactNode,
|
||||
label: string,
|
||||
map: { [key: string]: string }
|
||||
subscriptionTypeToDescription: {
|
||||
[key in keyof Partial<notification_subscription_types>]: string
|
||||
}
|
||||
) => {
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
return (
|
||||
|
@ -255,8 +268,14 @@ export function NotificationSettings() {
|
|||
)}
|
||||
</Row>
|
||||
<Col className={clsx(expanded ? 'block' : 'hidden', 'gap-2 p-2')}>
|
||||
{Object.entries(map).map(([key, value]) =>
|
||||
NotificationSettingLine(value, key, getUsersSavedPreference(key))
|
||||
{Object.entries(subscriptionTypeToDescription).map(([key, value]) =>
|
||||
NotificationSettingLine(
|
||||
value,
|
||||
key as keyof notification_subscription_types,
|
||||
getUsersSavedPreference(
|
||||
key as keyof notification_subscription_types
|
||||
)
|
||||
)
|
||||
)}
|
||||
</Col>
|
||||
</Col>
|
||||
|
|
Loading…
Reference in New Issue
Block a user