From 13dad9a10c821c4248145d920c3e1028aeb88235 Mon Sep 17 00:00:00 2001 From: James Grugett Date: Tue, 27 Sep 2022 19:03:14 -0400 Subject: [PATCH 001/162] Date doc: Remove photo as first-class feature --- common/post.ts | 1 - functions/src/create-post.ts | 1 - web/pages/date-docs/[username].tsx | 7 +--- web/pages/date-docs/create.tsx | 57 +----------------------------- 4 files changed, 2 insertions(+), 64 deletions(-) diff --git a/common/post.ts b/common/post.ts index 13a90821..45503b22 100644 --- a/common/post.ts +++ b/common/post.ts @@ -12,7 +12,6 @@ export type Post = { export type DateDoc = Post & { bounty: number birthday: number - photoUrl: string type: 'date-doc' contractSlug: string } diff --git a/functions/src/create-post.ts b/functions/src/create-post.ts index a342dc05..675ce3e1 100644 --- a/functions/src/create-post.ts +++ b/functions/src/create-post.ts @@ -42,7 +42,6 @@ const postSchema = z.object({ // Date doc fields: bounty: z.number().optional(), birthday: z.number().optional(), - photoUrl: z.string().optional(), type: z.string().optional(), question: z.string().optional(), }) diff --git a/web/pages/date-docs/[username].tsx b/web/pages/date-docs/[username].tsx index d6ac37cd..2b6c4909 100644 --- a/web/pages/date-docs/[username].tsx +++ b/web/pages/date-docs/[username].tsx @@ -85,7 +85,7 @@ export function DateDocPost(props: { link?: boolean }) { const { dateDoc, creator, link } = props - const { content, birthday, photoUrl, contractSlug } = dateDoc + const { content, birthday, contractSlug } = dateDoc const { name, username } = creator const user = useUser() @@ -133,11 +133,6 @@ export function DateDocPost(props: { - {name} {user && user.id === creator.id ? ( diff --git a/web/pages/date-docs/create.tsx b/web/pages/date-docs/create.tsx index 5d72da42..6065796d 100644 --- a/web/pages/date-docs/create.tsx +++ b/web/pages/date-docs/create.tsx @@ -13,8 +13,6 @@ import { Button } from 'web/components/button' import dayjs from 'dayjs' import { MINUTE_MS } from 'common/util/time' import { Col } from 'web/components/layout/col' -import { uploadImage } from 'web/lib/firebase/storage' -import { LoadingIndicator } from 'web/components/loading-indicator' import { MAX_QUESTION_LENGTH } from 'common/contract' export default function CreateDateDocPage() { @@ -26,8 +24,6 @@ export default function CreateDateDocPage() { const title = `${user?.name}'s Date Doc` const [birthday, setBirthday] = useState(undefined) - const [photoUrl, setPhotoUrl] = useState('') - const [avatarLoading, setAvatarLoading] = useState(false) const [question, setQuestion] = useState( 'Will I find a partner in the next 3 months?' ) @@ -40,30 +36,7 @@ export default function CreateDateDocPage() { const birthdayTime = birthday ? dayjs(birthday).valueOf() : undefined const isValid = - user && - birthday && - photoUrl && - editor && - editor.isEmpty === false && - question - - const fileHandler = async (event: any) => { - if (!user) return - - const file = event.target.files[0] - - setAvatarLoading(true) - - await uploadImage(user.username, file) - .then(async (url) => { - setPhotoUrl(url) - setAvatarLoading(false) - }) - .catch(() => { - setAvatarLoading(false) - setPhotoUrl('') - }) - } + user && birthday && editor && editor.isEmpty === false && question async function saveDateDoc() { if (!user || !editor || !birthdayTime) return @@ -76,7 +49,6 @@ export default function CreateDateDocPage() { content: editor.getJSON(), bounty: 0, birthday: birthdayTime, - photoUrl, type: 'date-doc', question, } @@ -122,33 +94,6 @@ export default function CreateDateDocPage() { /> - -
Photo
- - {avatarLoading ? ( - - ) : ( - <> - {photoUrl && ( - - )} - - - )} - - -
Tell us about you! What are you looking for? From a7abdbb1dbf934b0893ff679f02044a3f35ecc30 Mon Sep 17 00:00:00 2001 From: James Grugett Date: Tue, 27 Sep 2022 19:10:35 -0400 Subject: [PATCH 002/162] Add to dating group --- functions/src/create-post.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/functions/src/create-post.ts b/functions/src/create-post.ts index 675ce3e1..e9d6ae8f 100644 --- a/functions/src/create-post.ts +++ b/functions/src/create-post.ts @@ -75,6 +75,8 @@ export const createpost = newEndpoint({}, async (req, auth) => { outcomeType: 'BINARY', visibility: 'unlisted', initialProb: 50, + // Dating group! + groupId: 'j3ZE8fkeqiKmRGumy3O1', }, auth ) From 9dc0d1696e2b15ada208f5aa49e67add42ed1081 Mon Sep 17 00:00:00 2001 From: James Grugett Date: Tue, 27 Sep 2022 19:36:32 -0400 Subject: [PATCH 003/162] Fix bug --- web/pages/date-docs/[username].tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/pages/date-docs/[username].tsx b/web/pages/date-docs/[username].tsx index 2b6c4909..17a41445 100644 --- a/web/pages/date-docs/[username].tsx +++ b/web/pages/date-docs/[username].tsx @@ -98,13 +98,13 @@ export function DateDocPost(props: { return ( - - + +
{name}, {age}
- + - )} -
+ return isEditable || (group.pinnedItems && group.pinnedItems.length > 0) ? ( + pinned.length > 0 || isEditable ? (
- - {pinned.length == 0 && !editMode && ( -
-

- No pinned items yet. Click the edit button to add some! -

-
- )} - {pinned.map((element, index) => ( -
- {element} - - {editMode && ( - { - const newPinned = group.pinnedItems.filter((item) => { - return item.itemId !== group.pinnedItems[index].itemId - }) - updateGroup(group, { pinnedItems: newPinned }) - }} - /> + + + {isEditable && ( +
- ))} - {editMode && group.pinnedItems && pinned.length < 6 && ( -
- - - -
+ )} -
+ +
+ + {pinned.length == 0 && !editMode && ( +
+

+ No pinned items yet. Click the edit button to add some! +

+
+ )} + {pinned.map((element, index) => ( +
+ {element} + + {editMode && ( + { + const newPinned = group.pinnedItems.filter((item) => { + return item.itemId !== group.pinnedItems[index].itemId + }) + updateGroup(group, { pinnedItems: newPinned }) + }} + /> + )} +
+ ))} + {editMode && group.pinnedItems && pinned.length < 6 && ( +
+ + + +
+ )} +
+
+ + Pin posts or markets to the overview of this group. +
+ } + onSubmit={onSubmit} + />
- - Pin posts or markets to the overview of this group. - - } - onSubmit={onSubmit} - /> - + ) : ( + + ) ) : ( <> ) From 370edec89052cc298b288ac6490a6364af11e8a2 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Mon, 3 Oct 2022 08:30:21 -0600 Subject: [PATCH 132/162] Remove unsubscribe options for market closure --- functions/src/email-templates/market-close.html | 6 +----- web/components/contract/contract-tabs.tsx | 2 ++ web/components/notification-settings.tsx | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/functions/src/email-templates/market-close.html b/functions/src/email-templates/market-close.html index 4abd225e..b742c533 100644 --- a/functions/src/email-templates/market-close.html +++ b/functions/src/email-templates/market-close.html @@ -483,11 +483,7 @@ color: #999; text-decoration: underline; margin: 0; - ">our Discord! Or, - click here to unsubscribe from this type of notification. + ">our Discord! diff --git a/web/components/contract/contract-tabs.tsx b/web/components/contract/contract-tabs.tsx index 0b3585ca..c4fddca5 100644 --- a/web/components/contract/contract-tabs.tsx +++ b/web/components/contract/contract-tabs.tsx @@ -136,6 +136,8 @@ const CommentsTabContent = memo(function CommentsTabContent(props: { ) } else { + // TODO: links to comments are broken because tips load after render and + // comments will reorganize themselves if there are tips/bounties awarded const tipsOrBountiesAwarded = Object.keys(tips).length > 0 || comments.some((c) => c.bountiesAwarded) diff --git a/web/components/notification-settings.tsx b/web/components/notification-settings.tsx index 1b5cac40..ad9adbdf 100644 --- a/web/components/notification-settings.tsx +++ b/web/components/notification-settings.tsx @@ -118,7 +118,7 @@ export function NotificationSettings(props: { const yourMarkets: SectionData = { label: 'Markets You Created', subscriptionTypes: [ - 'your_contract_closed', + // 'your_contract_closed', 'all_comments_on_my_markets', 'all_answers_on_my_markets', 'subsidized_your_market', From f92f098f829777a94b869a4255d62dc604786b5e Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Mon, 3 Oct 2022 09:26:39 -0600 Subject: [PATCH 133/162] Allo creators to unlist markets --- common/contract.ts | 1 + firestore.rules | 2 +- .../contract/contract-info-dialog.tsx | 43 +++++++++++-------- .../contract/extra-contract-actions-row.tsx | 2 +- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/common/contract.ts b/common/contract.ts index fb430067..1255874d 100644 --- a/common/contract.ts +++ b/common/contract.ts @@ -64,6 +64,7 @@ export type Contract = { likedByUserCount?: number flaggedByUsernames?: string[] openCommentBounties?: number + unlistedById?: string } & T export type BinaryContract = Contract & Binary diff --git a/firestore.rules b/firestore.rules index bf0375e6..50f93e1f 100644 --- a/firestore.rules +++ b/firestore.rules @@ -102,7 +102,7 @@ service cloud.firestore { allow update: if request.resource.data.diff(resource.data).affectedKeys() .hasOnly(['tags', 'lowercaseTags', 'groupSlugs', 'groupLinks']); allow update: if request.resource.data.diff(resource.data).affectedKeys() - .hasOnly(['description', 'closeTime', 'question']) + .hasOnly(['description', 'closeTime', 'question', 'visibility', 'unlistedById']) && resource.data.creatorId == request.auth.uid; allow update: if isAdmin(); match /comments/{commentId} { diff --git a/web/components/contract/contract-info-dialog.tsx b/web/components/contract/contract-info-dialog.tsx index df6695ed..1cae98f9 100644 --- a/web/components/contract/contract-info-dialog.tsx +++ b/web/components/contract/contract-info-dialog.tsx @@ -19,7 +19,7 @@ import { deleteField } from 'firebase/firestore' import ShortToggle from '../widgets/short-toggle' import { DuplicateContractButton } from '../copy-contract-button' import { Row } from '../layout/row' -import { BETTORS } from 'common/user' +import { BETTORS, User } from 'common/user' import { Button } from '../button' export const contractDetailsButtonClassName = @@ -27,9 +27,10 @@ export const contractDetailsButtonClassName = export function ContractInfoDialog(props: { contract: Contract + user: User | null | undefined className?: string }) { - const { contract, className } = props + const { contract, className, user } = props const [open, setOpen] = useState(false) const [featured, setFeatured] = useState( @@ -37,6 +38,10 @@ export function ContractInfoDialog(props: { ) const isDev = useDev() const isAdmin = useAdmin() + const isCreator = user?.id === contract.creatorId + const isUnlisted = contract.visibility === 'unlisted' + const wasUnlistedByCreator = + contract.unlistedById && contract.unlistedById === contract.creatorId const formatTime = (dt: number) => dayjs(dt).format('MMM DD, YYYY hh:mm a') @@ -175,21 +180,25 @@ export function ContractInfoDialog(props: { )} - {isAdmin && ( - - [ADMIN] Unlisted - - - updateContract(id, { - visibility: b ? 'unlisted' : 'public', - }) - } - /> - - - )} + {user && + (isAdmin || + (isCreator && + (isUnlisted ? wasUnlistedByCreator : true))) && ( + + {isAdmin ? '[ADMIN]' : ''} Unlisted + + + updateContract(id, { + visibility: b ? 'unlisted' : 'public', + unlistedById: b ? user.id : '', + }) + } + /> + + + )} diff --git a/web/components/contract/extra-contract-actions-row.tsx b/web/components/contract/extra-contract-actions-row.tsx index d9474806..809c6172 100644 --- a/web/components/contract/extra-contract-actions-row.tsx +++ b/web/components/contract/extra-contract-actions-row.tsx @@ -35,7 +35,7 @@ export function ExtraContractActionsRow(props: { contract: Contract }) { /> - + ) } From adb8bc476f25a4c555d59cb433fdb493ed968b85 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Mon, 3 Oct 2022 09:36:49 -0600 Subject: [PATCH 134/162] Show whether market is unlisted --- .../contract/contract-info-dialog.tsx | 49 ++++++++++--------- web/components/widgets/short-toggle.tsx | 21 +++++--- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/web/components/contract/contract-info-dialog.tsx b/web/components/contract/contract-info-dialog.tsx index 1cae98f9..306b2587 100644 --- a/web/components/contract/contract-info-dialog.tsx +++ b/web/components/contract/contract-info-dialog.tsx @@ -40,8 +40,9 @@ export function ContractInfoDialog(props: { const isAdmin = useAdmin() const isCreator = user?.id === contract.creatorId const isUnlisted = contract.visibility === 'unlisted' - const wasUnlistedByCreator = - contract.unlistedById && contract.unlistedById === contract.creatorId + const wasUnlistedByCreator = contract.unlistedById + ? contract.unlistedById === contract.creatorId + : true const formatTime = (dt: number) => dayjs(dt).format('MMM DD, YYYY hh:mm a') @@ -173,32 +174,34 @@ export function ContractInfoDialog(props: { [ADMIN] Featured )} - {user && - (isAdmin || - (isCreator && - (isUnlisted ? wasUnlistedByCreator : true))) && ( - - {isAdmin ? '[ADMIN]' : ''} Unlisted - - - updateContract(id, { - visibility: b ? 'unlisted' : 'public', - unlistedById: b ? user.id : '', - }) - } - /> - - - )} + {user && ( + + {isAdmin ? '[ADMIN]' : ''} Unlisted + + + updateContract(id, { + visibility: b ? 'unlisted' : 'public', + unlistedById: b ? user.id : '', + }) + } + /> + + + )} diff --git a/web/components/widgets/short-toggle.tsx b/web/components/widgets/short-toggle.tsx index 339de361..d8baeebe 100644 --- a/web/components/widgets/short-toggle.tsx +++ b/web/components/widgets/short-toggle.tsx @@ -3,22 +3,27 @@ import { Switch } from '@headlessui/react' import clsx from 'clsx' export default function ShortToggle(props: { - enabled: boolean - setEnabled: (enabled: boolean) => void + on: boolean + setOn: (enabled: boolean) => void + disabled?: boolean onChange?: (enabled: boolean) => void }) { - const { enabled, setEnabled } = props + const { on, setOn, disabled } = props return ( { - setEnabled(e) + setOn(e) if (props.onChange) { props.onChange(e) } }} - className="group relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center rounded-full focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2" + className={clsx( + 'group relative inline-flex h-5 w-10 flex-shrink-0 items-center justify-center rounded-full focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2', + !disabled ? 'cursor-pointer' : 'cursor-not-allowed opacity-50' + )} > Use setting