diff --git a/js/src/forum/components/PollView.tsx b/js/src/forum/components/PollView.tsx index c725e93d..58523ca1 100644 --- a/js/src/forum/components/PollView.tsx +++ b/js/src/forum/components/PollView.tsx @@ -43,6 +43,7 @@ export default class PollView extends Component { view(): Mithril.Children { const poll = this.attrs.poll; const state = this.state; + // @ts-expect-error const controls = PollControls.controls(poll, this); (poll.publicPoll() || poll.canEdit()) && diff --git a/js/src/forum/components/PostPoll.tsx b/js/src/forum/components/PostPoll.tsx index 37878a24..bf7e20ca 100644 --- a/js/src/forum/components/PostPoll.tsx +++ b/js/src/forum/components/PostPoll.tsx @@ -18,6 +18,7 @@ import PollImage from './Poll/PollImage'; export interface PostPollAttrs extends ComponentAttrs { poll: Poll; post?: Post; + tooltipVisible?: boolean; } export default class PostPoll extends Component { @@ -25,6 +26,7 @@ export default class PostPoll extends Component { useSubmitUI!: boolean; pendingSubmit: boolean = false; pendingOptions: any; + updateVisibility: () => void = () => {}; oninit(vnode: Mithril.Vnode) { super.oninit(vnode); @@ -206,11 +208,13 @@ export default class PostPoll extends Component { changeVote(option: PollOption, evt: Event) { if (!app.session.user) { app.modal.show(LogInModal); - evt.target.checked = false; + if (evt.target instanceof HTMLInputElement) { + evt.target.checked = false; + } return; } - const optionIds = this.pendingOptions || new Set(this.attrs.poll.myVotes().map?.((v) => v.option().id())); + const optionIds = this.pendingOptions || new Set(this.attrs.poll.myVotes().map?.((v) => v.option()?.id())); const isUnvoting = optionIds.delete(option.id()); const allowsMultiple = this.attrs.poll.allowMultipleVotes(); @@ -228,42 +232,49 @@ export default class PostPoll extends Component { return; } - return this.submit(optionIds, null, () => (evt.target.checked = isUnvoting)); + return this.submit(optionIds, null, () => { + if (evt.target instanceof HTMLInputElement) { + evt.target.checked = isUnvoting; + } + }); } onsubmit() { - return this.submit(this.pendingOptions, () => { - this.pendingOptions = null; - this.pendingSubmit = false; - }); + return this.submit( + this.pendingOptions, + () => { + this.pendingOptions = null; + this.pendingSubmit = false; + }, + null + ); } - submit(optionIds, cb, onerror) { + async submit(optionIds: Iterable | ArrayLike, cb: { (): void; (): void } | null, onerror: any) { this.loadingOptions = true; m.redraw(); - return app - .request({ - method: 'PATCH', - url: `${app.forum.attribute('apiUrl')}/fof/polls/${this.attrs.poll.id()}/votes`, - body: { - data: { - optionIds: Array.from(optionIds), + try { + try { + const res = await app.request({ + method: 'PATCH', + url: `${app.forum.attribute('apiUrl')}/fof/polls/${this.attrs.poll.id()}/votes`, + body: { + data: { + optionIds: Array.from(optionIds), + }, }, - }, - }) - .then((res) => { - app.store.pushPayload(res); + }); + app.store.pushPayload(res as any); cb?.(); - }) - .catch((err) => { + } catch (err) { onerror?.(err); - }) - .finally(() => { - this.loadingOptions = false; + } + } finally { + this.loadingOptions = false; - m.redraw(); - }); + m.redraw(); + } } showVoters() { @@ -295,10 +306,11 @@ export default class PostPoll extends Component { /** * Alert before navigating away using browser's 'beforeunload' event */ - preventClose(e) { + preventClose(e: Event) { if (this.pendingOptions) { e.preventDefault(); return true; } + return undefined; } } diff --git a/js/src/forum/components/UploadPollImageButton.tsx b/js/src/forum/components/UploadPollImageButton.tsx index b239c3ca..cda10835 100644 --- a/js/src/forum/components/UploadPollImageButton.tsx +++ b/js/src/forum/components/UploadPollImageButton.tsx @@ -26,6 +26,7 @@ export default class UploadPollImageButton extends Button | undefined; + // @ts-expect-error view(vnode: Mithril.Vnode) { this.attrs.loading = this.loading; this.attrs.className = classList(this.attrs.className, 'Button', 'Button--inverted'); @@ -70,6 +71,7 @@ export default class UploadPollImageButton extends Button { const body = new FormData(); + // @ts-expect-error body.append(this.attrs.name, $(e.target)[0].files[0]); this.loading = true; @@ -79,7 +81,7 @@ export default class UploadPollImageButton extends Button({ method: 'POST', url: this.resourceUrl(), - serialize: (raw) => raw, + serialize: (raw: any) => raw, body, }) .then(this.success.bind(this), this.failure.bind(this)); diff --git a/js/src/forum/utils/PollControls.tsx b/js/src/forum/utils/PollControls.tsx index 6621be7f..4427610f 100644 --- a/js/src/forum/utils/PollControls.tsx +++ b/js/src/forum/utils/PollControls.tsx @@ -19,8 +19,9 @@ export default { controls(poll: Poll, context: Component): ItemList { const items = new ItemList(); - ['poll', 'moderation', 'destructive'].forEach((section) => { - const controls = (this[section + 'Controls'](poll, context) as ItemList).toArray(); + const sections: ('poll' | 'moderation' | 'destructive')[] = ['poll', 'moderation', 'destructive']; + sections.forEach((section) => { + const controls = (this[`${section}Controls`](poll, context) as ItemList).toArray(); if (controls.length) { controls.forEach((item) => items.add(item.itemName, item)); items.add(section + 'Separator', );