diff --git a/common/contract.ts b/common/contract.ts index c414a332..2a8f897a 100644 --- a/common/contract.ts +++ b/common/contract.ts @@ -31,7 +31,7 @@ export type Contract = { description: string | JSONContent // More info about what the contract is about tags: string[] lowercaseTags: string[] - visibility: 'public' | 'unlisted' + visibility: visibility createdTime: number // Milliseconds since epoch lastUpdatedTime?: number // Updated on new bet or comment @@ -143,3 +143,6 @@ export const MAX_DESCRIPTION_LENGTH = 16000 export const MAX_TAG_LENGTH = 60 export const CPMM_MIN_POOL_QTY = 0.01 + +export type visibility = 'public' | 'unlisted' +export const VISIBILITIES = ['public', 'unlisted'] as const diff --git a/common/new-contract.ts b/common/new-contract.ts index ad7dc5a2..17b872ab 100644 --- a/common/new-contract.ts +++ b/common/new-contract.ts @@ -9,6 +9,7 @@ import { Numeric, outcomeType, PseudoNumeric, + visibility, } from './contract' import { User } from './user' import { parseTags, richTextToString } from './util/parse' @@ -34,7 +35,8 @@ export function getNewContract( isLogScale: boolean, // for multiple choice - answers: string[] + answers: string[], + visibility: visibility ) { const tags = parseTags( [ @@ -70,7 +72,7 @@ export function getNewContract( description, tags, lowercaseTags, - visibility: 'public', + visibility, isResolved: false, createdTime: Date.now(), closeTime, diff --git a/functions/src/create-market.ts b/functions/src/create-market.ts index 3e9998ed..eb3a19eb 100644 --- a/functions/src/create-market.ts +++ b/functions/src/create-market.ts @@ -10,6 +10,7 @@ import { MultipleChoiceContract, NumericContract, OUTCOME_TYPES, + VISIBILITIES, } from '../../common/contract' import { slugify } from '../../common/util/slugify' import { randomString } from '../../common/util/random' @@ -69,6 +70,7 @@ const bodySchema = z.object({ ), outcomeType: z.enum(OUTCOME_TYPES), groupId: z.string().min(1).max(MAX_ID_LENGTH).optional(), + visibility: z.enum(VISIBILITIES).optional(), }) const binarySchema = z.object({ @@ -90,8 +92,15 @@ const multipleChoiceSchema = z.object({ }) export const createmarket = newEndpoint({}, async (req, auth) => { - const { question, description, tags, closeTime, outcomeType, groupId } = - validate(bodySchema, req.body) + const { + question, + description, + tags, + closeTime, + outcomeType, + groupId, + visibility = 'public', + } = validate(bodySchema, req.body) let min, max, initialProb, isLogScale, answers @@ -196,7 +205,8 @@ export const createmarket = newEndpoint({}, async (req, auth) => { min ?? 0, max ?? 0, isLogScale ?? false, - answers ?? [] + answers ?? [], + visibility ) if (ante) await chargeUser(user.id, ante, true) diff --git a/functions/src/scripts/unlist-contracts.ts b/functions/src/scripts/unlist-contracts.ts index 12adcedd..63307653 100644 --- a/functions/src/scripts/unlist-contracts.ts +++ b/functions/src/scripts/unlist-contracts.ts @@ -22,7 +22,7 @@ async function unlistContracts() { const contractRef = firestore.doc(`contracts/${contract.id}`) console.log('Updating', contract.question) - await contractRef.update({ visibility: 'soft-unlisted' }) + await contractRef.update({ visibility: 'unlisted' }) } } diff --git a/web/components/contract-search.tsx b/web/components/contract-search.tsx index 5cb819a9..1b55fe97 100644 --- a/web/components/contract-search.tsx +++ b/web/components/contract-search.tsx @@ -255,13 +255,12 @@ function ContractSearchControls(props: { ? additionalFilters : [ ...additionalFilters, + 'visibility:public', + filter === 'open' ? 'isResolved:false' : '', filter === 'closed' ? 'isResolved:false' : '', filter === 'resolved' ? 'isResolved:true' : '', - // Newest sort requires public visibility. - sort === 'newest' ? 'visibility:public' : '', - pillFilter && pillFilter !== 'personal' && pillFilter !== 'your-bets' ? `groupLinks.slug:${pillFilter}` : '', diff --git a/web/pages/create.tsx b/web/pages/create.tsx index ab566c9e..8a9e363b 100644 --- a/web/pages/create.tsx +++ b/web/pages/create.tsx @@ -15,6 +15,7 @@ import { MAX_DESCRIPTION_LENGTH, MAX_QUESTION_LENGTH, outcomeType, + visibility, } from 'common/contract' import { formatMoney } from 'common/util/format' import { removeUndefinedProps } from 'common/util/object' @@ -150,6 +151,7 @@ export function NewContract(props: { undefined ) const [showGroupSelector, setShowGroupSelector] = useState(true) + const [visibility, setVisibility] = useState('public') const closeTime = closeDate ? dayjs(`${closeDate}T${closeHoursMinutes}`).valueOf() @@ -234,6 +236,7 @@ export function NewContract(props: { isLogScale, answers, groupId: selectedGroup?.id, + visibility, }) ) track('create market', { @@ -367,17 +370,32 @@ export function NewContract(props: { )} -
- + + setVisibility(choice as visibility)} + choicesMap={{ + Public: 'public', + Unlisted: 'unlisted', + }} + isSubmitting={isSubmitting} />
+ + + +