a tool for shared writing and social publishing
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

pull out poll ui state and remove empty options on save

+61 -20
+17 -2
components/Blocks/BlockCommands.tsx
··· 22 22 import { keepFocus } from "components/Toolbar/TextBlockTypeToolbar"; 23 23 import { useEditorStates } from "src/state/useEditorState"; 24 24 import { elementId } from "src/utils/elementId"; 25 + import { usePollBlockUIState } from "./PollBlock"; 25 26 26 27 type Props = { 27 28 parent: string; ··· 209 210 icon: <BlockMailboxSmall />, 210 211 type: "block", 211 212 onSelect: async (rep, props) => { 212 - let entity; 213 - createBlockWithType(rep, props, "poll"); 213 + let entity = await createBlockWithType(rep, props, "poll"); 214 + await rep.mutate.addPollOption({ 215 + pollEntity: entity, 216 + pollOptionEntity: v7(), 217 + pollOptionName: "", 218 + factID: v7(), 219 + permission_set: props.entity_set, 220 + }); 221 + await rep.mutate.addPollOption({ 222 + pollEntity: entity, 223 + pollOptionEntity: v7(), 224 + pollOptionName: "", 225 + factID: v7(), 226 + permission_set: props.entity_set, 227 + }); 228 + usePollBlockUIState.setState((s) => ({ [entity]: { state: "editing" } })); 214 229 }, 215 230 }, 216 231
+44 -18
components/Blocks/PollBlock.tsx
··· 1 1 import { useUIState } from "src/useUIState"; 2 2 import { BlockProps } from "./Block"; 3 3 import { ButtonPrimary, ButtonSecondary } from "components/Buttons"; 4 - import { useEffect, useState } from "react"; 4 + import { useCallback, useEffect, useState } from "react"; 5 5 import { Input } from "components/Input"; 6 6 import { CheckTiny, CloseTiny, InfoSmall } from "components/Icons"; 7 7 import { Separator } from "components/Layout"; ··· 11 11 import { v7 } from "uuid"; 12 12 import { usePollData } from "components/PageSWRDataProvider"; 13 13 import { voteOnPoll } from "actions/pollActions"; 14 + import { create } from "zustand"; 14 15 16 + export let usePollBlockUIState = create( 17 + () => 18 + ({}) as { 19 + [entity: string]: { state: "editing" | "voting" | "results" } | undefined; 20 + }, 21 + ); 15 22 export const PollBlock = (props: BlockProps) => { 16 23 let { rep } = useReplicache(); 17 24 let isSelected = useUIState((s) => ··· 19 26 ); 20 27 let { permissions } = useEntitySetContext(); 21 28 22 - let [pollState, setPollState] = useState<"editing" | "voting" | "results">( 23 - !permissions.write ? "voting" : "editing", 24 - ); 25 - 26 29 let dataPollOptions = useEntity(props.entityID, "poll/options"); 27 30 let { data: pollData } = usePollData(); 31 + let hasVoted = 32 + pollData?.voter_token && 33 + pollData.polls.find( 34 + (v) => 35 + v.poll_votes_on_entity.voter_token === pollData.voter_token && 36 + v.poll_votes_on_entity.poll_entity === props.entityID, 37 + ); 38 + 39 + let pollState = usePollBlockUIState((s) => s[props.entityID]?.state); 40 + if (!pollState) { 41 + if (hasVoted) pollState = "results"; 42 + else pollState = "voting"; 43 + } 44 + 45 + const setPollState = useCallback( 46 + (state: "editing" | "voting" | "results") => { 47 + usePollBlockUIState.setState((s) => ({ [props.entityID]: { state } })); 48 + }, 49 + [], 50 + ); 28 51 29 52 let [localPollOptionNames, setLocalPollOptionNames] = useState<{ 30 53 [k: string]: string; ··· 99 122 onMouseDown={() => { 100 123 setPollState("voting"); 101 124 102 - // Update the poll option names 103 - // rep?.mutate.assertFact( 104 - // Object.entries(localPollOptionNames).map(([entity, name]) => ({ 105 - // entity, 106 - // attribute: "poll-option/name", 107 - // data: { type: "string", value: name }, 108 - // })), 109 - // ); 110 - 111 125 // remove any poll options that have no name 112 126 // look through the localPollOptionNames object and remove any options that have no name 113 127 let emptyOptions = Object.entries(localPollOptionNames).filter( 114 - ([optionEntity, optionName]) => { 115 - optionName === ""; 116 - }, 128 + ([optionEntity, optionName]) => optionName === "", 129 + ); 130 + emptyOptions.forEach(([entity]) => 131 + rep?.mutate.removePollOption({ optionEntity: entity }), 132 + ); 133 + 134 + console.log(emptyOptions, Object.entries(localPollOptionNames)); 135 + 136 + rep?.mutate.assertFact( 137 + Object.entries(localPollOptionNames) 138 + .filter(([, name]) => !!name) 139 + .map(([entity, name]) => ({ 140 + entity, 141 + attribute: "poll-option/name", 142 + data: { type: "string", value: name }, 143 + })), 117 144 ); 118 - console.log(emptyOptions); 119 145 }} 120 146 > 121 147 Save <CheckTiny />