diff --git a/src/app/components/ComposeMenu.svelte b/src/app/components/ComposeMenu.svelte
index 990728de..b7828d55 100644
--- a/src/app/components/ComposeMenu.svelte
+++ b/src/app/components/ComposeMenu.svelte
@@ -4,6 +4,7 @@
import StarFallMinimalistic from "@assets/icons/star-fall-minimalistic.svg?dataurl"
import NotesMinimalistic from "@assets/icons/notes-minimalistic.svg?dataurl"
import CaseMinimalistic from "@assets/icons/case-minimalistic.svg?dataurl"
+ import Revote from "@assets/icons/revote.svg?dataurl"
import Button from "@lib/components/Button.svelte"
import Icon from "@lib/components/Icon.svelte"
import {pushModal} from "@app/util/modal"
@@ -11,6 +12,7 @@
import ThreadCreate from "@app/components/ThreadCreate.svelte"
import ClassifiedCreate from "@app/components/ClassifiedCreate.svelte"
import GoalCreate from "@app/components/GoalCreate.svelte"
+ import PollCreate from "@app/components/PollCreate.svelte"
type Props = {
url: string
@@ -28,6 +30,8 @@
const createClassified = () => pushModal(ClassifiedCreate, {url, h})
+ const createPoll = () => pushModal(PollCreate, {url, h})
+
let ul: Element
onMount(() => {
@@ -60,4 +64,10 @@
Create Thread
+
+
+
+ Ask a Question
+
+
diff --git a/src/app/components/NoteContent.svelte b/src/app/components/NoteContent.svelte
index d14c6c47..8eca0dd9 100644
--- a/src/app/components/NoteContent.svelte
+++ b/src/app/components/NoteContent.svelte
@@ -1,10 +1,12 @@
+
+
+
+ {$results.voters} voter{$results.voters === 1 ? "" : "s"}
+
diff --git a/src/app/components/NoteContentPoll.svelte b/src/app/components/NoteContentPoll.svelte
new file mode 100644
index 00000000..a60ecda4
--- /dev/null
+++ b/src/app/components/NoteContentPoll.svelte
@@ -0,0 +1,29 @@
+
+
+
+
+
+ {#if props.url}
+
+ {/if}
+
diff --git a/src/app/components/PollCreate.svelte b/src/app/components/PollCreate.svelte
new file mode 100644
index 00000000..33d3cc3e
--- /dev/null
+++ b/src/app/components/PollCreate.svelte
@@ -0,0 +1,238 @@
+
+
+
+
+
+ Create a Poll
+ Ask a question and collect votes right in the feed.
+
+
+
+ {#snippet label()}
+ Question*
+ {/snippet}
+ {#snippet input()}
+
+
+
+
+ {/snippet}
+
+
+
+ {#snippet label()}
+ Options*
+ {/snippet}
+ {#snippet input()}
+
+ {#each options as option, index (option.id)}
+
onDragStart(e, option.id)}
+ ondragover={e => onDragOver(e, option.id)}
+ ondrop={e => onDrop(e, option.id)}
+ ondragend={onDragEnd}>
+
+
+
+
+ updateOption(option.id, e.currentTarget.value)} />
+
+
removeOption(option.id)}>
+
+
+
+ {/each}
+
+
+ Add option
+
+
+ {/snippet}
+
+
+
+
+ {#snippet label()}
+ Poll type
+ {/snippet}
+ {#snippet input()}
+
+ Single choice
+ Multiple choice
+
+ {/snippet}
+
+
+ {#snippet label()}
+ Ends at
+ {/snippet}
+ {#snippet input()}
+
+ {/snippet}
+
+
+
+
+
+
+
+ Go back
+
+ Create Poll
+
+
diff --git a/src/app/components/PollItem.svelte b/src/app/components/PollItem.svelte
new file mode 100644
index 00000000..1f96e96a
--- /dev/null
+++ b/src/app/components/PollItem.svelte
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ Posted by
+ {#if h}
+ in
+ {/if}
+
+
+
+
diff --git a/src/app/components/PollOption.svelte b/src/app/components/PollOption.svelte
new file mode 100644
index 00000000..784c1fde
--- /dev/null
+++ b/src/app/components/PollOption.svelte
@@ -0,0 +1,70 @@
+
+
+
diff --git a/src/app/components/PollVotes.svelte b/src/app/components/PollVotes.svelte
new file mode 100644
index 00000000..83448174
--- /dev/null
+++ b/src/app/components/PollVotes.svelte
@@ -0,0 +1,127 @@
+
+
+
+ {#each options as option (option.id)}
+
+ {/each}
+
+
+ {pollType === "multiplechoice" ? "Multiple choice" : "Single choice"}
+ {#if endsAt}
+ {#if closed}
+ • Ended {formatTimestampRelative(endsAt)}
+ {:else}
+ • Ends {formatTimestampRelative(endsAt)}
+ {/if}
+ {/if}
+
+
{results.voters} vote{results.voters === 1 ? "" : "s"}
+
+
diff --git a/src/app/components/SpaceMenu.svelte b/src/app/components/SpaceMenu.svelte
index d7b97c83..fd8d8a5d 100644
--- a/src/app/components/SpaceMenu.svelte
+++ b/src/app/components/SpaceMenu.svelte
@@ -1,6 +1,7 @@
+
+
+ {#snippet title()}
+
+ Polls
+ {/snippet}
+ {#snippet action()}
+
+
+ Create
+
+ {/snippet}
+
+
+
+ {#each items as event (event.id)}
+
+ {/each}
+
+
+ {#if loading}
+ Looking for polls...
+ {:else if items.length === 0}
+ No polls found.
+ {:else}
+ That's all!
+ {/if}
+
+
+
diff --git a/src/routes/spaces/[relay]/polls/[id]/+page.svelte b/src/routes/spaces/[relay]/polls/[id]/+page.svelte
new file mode 100644
index 00000000..976f9c36
--- /dev/null
+++ b/src/routes/spaces/[relay]/polls/[id]/+page.svelte
@@ -0,0 +1,107 @@
+
+
+
+ {#snippet title()}
+ {$event?.content || "Poll"}
+ {/snippet}
+
+
+
+ {#if $event}
+
+
+
+
+
+
+
+ {#if !showAll && $comments.length > 4}
+
+
+
+ Show all {$comments.length} comments
+
+
+ {/if}
+ {#each $comments.slice(0, showAll ? undefined : 4) as reply (reply.id)}
+
+
+
+
+
+
+ {/each}
+
+ {#if showReply}
+
+ {:else}
+
+ Comment on this poll
+
+ {/if}
+ {:else}
+ {#await sleep(5000)}
+ Loading poll...
+ {:then}
+ Failed to load poll.
+ {/await}
+ {/if}
+
diff --git a/src/routes/spaces/[relay]/recent/+page.svelte b/src/routes/spaces/[relay]/recent/+page.svelte
index 309a1296..d75ddbc0 100644
--- a/src/routes/spaces/[relay]/recent/+page.svelte
+++ b/src/routes/spaces/[relay]/recent/+page.svelte
@@ -46,9 +46,11 @@
import ClassifiedItem from "@app/components/ClassifiedItem.svelte"
import GoalItem from "@app/components/GoalItem.svelte"
import CalendarEventItem from "@app/components/CalendarEventItem.svelte"
+ import PollItem from "@app/components/PollItem.svelte"
import RecentConversation from "@app/components/RecentConversation.svelte"
import {decodeRelay, deriveEventsForUrl, CONTENT_KINDS} from "@app/core/state"
import {goToEvent} from "@app/util/routes"
+ import {Poll} from "nostr-tools/kinds"
const url = decodeRelay($page.params.relay!)
const since = ago(3, MONTH)
@@ -306,6 +308,8 @@
{:else if event.kind === EVENT_TIME}
+ {:else if event.kind === Poll}
+
{:else}
{/if}