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 }) { /> - + ) }