@@ -256,6 +268,8 @@ export default class CreatePollModal extends Modal {
question: this.question(),
endDate: this.dateToTimestamp(this.endDate()),
publicPoll: this.publicPoll(),
+ hideVotes: this.hideVotes(),
+ allowChangeVote: this.allowChangeVote(),
allowMultipleVotes: this.allowMultipleVotes(),
maxVotes: this.maxVotes(),
options: [],
@@ -301,6 +315,7 @@ export default class CreatePollModal extends Modal {
promise.then(this.hide.bind(this), (err) => {
console.error(err);
+ this.onerror(err);
this.loaded();
});
} else {
diff --git a/js/src/forum/components/EditPollModal.js b/js/src/forum/components/EditPollModal.js
index 0fc47669..23203a35 100755
--- a/js/src/forum/components/EditPollModal.js
+++ b/js/src/forum/components/EditPollModal.js
@@ -19,6 +19,7 @@ export default class EditPollModal extends CreatePollModal {
this.publicPoll = Stream(this.poll.publicPoll());
this.allowMultipleVotes = Stream(this.poll.allowMultipleVotes());
this.hideVotes = Stream(this.poll.hideVotes());
+ this.allowChangeVote = Stream(this.poll.allowChangeVote());
this.maxVotes = Stream(this.poll.maxVotes() || 0);
if (this.endDate() && dayjs(this.poll.endDate()).isAfter(dayjs())) {
@@ -97,6 +98,7 @@ export default class EditPollModal extends CreatePollModal {
endDate: this.dateToTimestamp(this.endDate()),
publicPoll: this.publicPoll(),
hideVotes: this.hideVotes(),
+ allowChangeVote: this.allowChangeVote(),
allowMultipleVotes: this.allowMultipleVotes(),
maxVotes: this.maxVotes(),
options,
diff --git a/js/src/forum/components/PostPoll.js b/js/src/forum/components/PostPoll.js
index 83dc2d1f..1ed159ce 100644
--- a/js/src/forum/components/PostPoll.js
+++ b/js/src/forum/components/PostPoll.js
@@ -5,6 +5,7 @@ import Button from 'flarum/common/components/Button';
import LogInModal from 'flarum/forum/components/LogInModal';
import ListVotersModal from './ListVotersModal';
import classList from 'flarum/common/utils/classList';
+import ItemList from 'flarum/common/utils/ItemList';
import Tooltip from 'flarum/common/components/Tooltip';
import EditPollModal from './EditPollModal';
@@ -13,6 +14,23 @@ export default class PostPoll extends Component {
super.oninit(vnode);
this.loadingOptions = false;
+
+ this.useSubmitUI = !this.attrs.poll?.canChangeVote() && this.attrs.poll?.allowMultipleVotes();
+ this.pendingSubmit = false;
+ this.pendingOptions = null;
+ }
+
+ oncreate(vnode) {
+ super.oncreate(vnode);
+
+ this.preventClose = this.preventClose.bind(this);
+ window.addEventListener('beforeunload', this.preventClose);
+ }
+
+ onremove(vnode) {
+ super.onremove(vnode);
+
+ window.removeEventListener('beforeunload', this.preventClose);
}
view() {
@@ -22,6 +40,8 @@ export default class PostPoll extends Component {
if (maxVotes === 0) maxVotes = options.length;
+ const infoItems = this.infoItems(maxVotes);
+
return (
@@ -45,41 +65,79 @@ export default class PostPoll extends Component {
)}
-
{options.map(this.viewOption.bind(this))}
+
+
{options.map(this.viewOption.bind(this))}
-
- {app.session.user && !poll.canVote() && !poll.hasEnded() && (
-
-
- {app.translator.trans('fof-polls.forum.no_permission')}
-
- )}
- {poll.endDate() && (
-
-
- {poll.hasEnded()
- ? app.translator.trans('fof-polls.forum.poll_ended')
- : app.translator.trans('fof-polls.forum.days_remaining', { time: dayjs(poll.endDate()).fromNow() })}
-
- )}
+
+ {!infoItems.isEmpty() &&
{infoItems.toArray()}
}
- {poll.canVote() && (
-
-
- {app.translator.trans('fof-polls.forum.max_votes_allowed', { max: maxVotes })}
-
- )}
+ {this.useSubmitUI && this.pendingSubmit && (
+
+ )}
+
);
}
+ infoItems(maxVotes) {
+ const items = new ItemList();
+ const poll = this.attrs.poll;
+ const hasVoted = poll.myVotes()?.length > 0;
+
+ if (app.session.user && !poll.canVote() && !poll.hasEnded()) {
+ items.add(
+ 'no-permission',
+
+
+ {app.translator.trans('fof-polls.forum.no_permission')}
+
+ );
+ }
+
+ if (poll.endDate()) {
+ items.add(
+ 'end-date',
+
+
+ {poll.hasEnded()
+ ? app.translator.trans('fof-polls.forum.poll_ended')
+ : app.translator.trans('fof-polls.forum.days_remaining', { time: dayjs(poll.endDate()).fromNow() })}
+
+ );
+ }
+
+ if (poll.canVote()) {
+ items.add(
+ 'max-votes',
+
+
+ {app.translator.trans('fof-polls.forum.max_votes_allowed', { max: maxVotes })}
+
+ );
+
+ if (!poll.canChangeVote()) {
+ items.add(
+ 'cannot-change-vote',
+
+
+ {app.translator.trans('fof-polls.forum.poll.cannot_change_vote')}
+
+ );
+ }
+ }
+
+ return items;
+ }
+
viewOption(opt) {
const poll = this.attrs.poll;
const hasVoted = poll.myVotes()?.length > 0;
const totalVotes = poll.voteCount();
- const voted = poll.myVotes()?.some?.((vote) => vote.option() === opt);
+ const voted = this.pendingOptions ? this.pendingOptions.has(opt.id()) : poll.myVotes()?.some?.((vote) => vote.option() === opt);
const votes = opt.voteCount();
const percent = totalVotes > 0 ? Math.round((votes / totalVotes) * 100) : 0;
@@ -88,9 +146,11 @@ export default class PostPoll extends Component {
const isDisabled = this.loadingOptions || (hasVoted && !poll.canChangeVote());
const width = canSeeVoteCount ? percent : (Number(voted) / (poll.myVotes()?.length || 1)) * 100;
+ const showCheckmark = !app.session.user || (!poll.hasEnded() && poll.canVote() && (!hasVoted || poll.canChangeVote()));
+
const bar = (
- {((!poll.hasEnded() && poll.canVote()) || !app.session.user) && (
+ {showCheckmark && (