2019-06-03 07:33:07 +02:00
|
|
|
import { Component, OnInit, Input } from '@angular/core';
|
2019-06-12 05:38:34 +02:00
|
|
|
import { Store } from '@ngxs/store';
|
|
|
|
import { Observable, Subscription } from 'rxjs';
|
2019-06-12 05:49:54 +02:00
|
|
|
import { faLock } from "@fortawesome/free-solid-svg-icons";
|
2019-06-03 07:33:07 +02:00
|
|
|
|
2019-06-12 05:38:34 +02:00
|
|
|
import { Poll, PollOption, Status } from '../../../../services/models/mastodon.interfaces';
|
2019-06-05 01:14:16 +02:00
|
|
|
import { AccountInfo } from '../../../../states/accounts.state';
|
2019-10-02 06:14:40 +02:00
|
|
|
import { MastodonWrapperService } from '../../../../services/mastodon-wrapper.service';
|
2019-06-05 01:33:36 +02:00
|
|
|
import { NotificationService } from '../../../../services/notification.service';
|
2019-06-12 05:38:34 +02:00
|
|
|
import { ToolsService } from '../../../../services/tools.service';
|
|
|
|
import { StatusWrapper } from '../../../../models/common.model';
|
2019-06-03 07:33:07 +02:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-poll',
|
|
|
|
templateUrl: './poll.component.html',
|
|
|
|
styleUrls: ['./poll.component.scss']
|
|
|
|
})
|
|
|
|
export class PollComponent implements OnInit {
|
2019-06-12 05:49:54 +02:00
|
|
|
faLock = faLock;
|
|
|
|
|
2019-06-05 06:06:29 +02:00
|
|
|
pollName: string;
|
2019-06-05 01:14:16 +02:00
|
|
|
choiceType: string;
|
2019-06-12 05:38:34 +02:00
|
|
|
pollLocked: boolean;
|
2019-06-05 00:36:04 +02:00
|
|
|
|
2020-07-13 00:36:18 +02:00
|
|
|
errorOccuredWhenRetrievingPoll: boolean;
|
|
|
|
|
2019-06-05 01:14:16 +02:00
|
|
|
private pollSelection: number[] = [];
|
|
|
|
options: PollOptionWrapper[] = [];
|
2019-06-03 07:33:07 +02:00
|
|
|
|
2019-06-12 05:38:34 +02:00
|
|
|
private pollPerAccountId: { [id: string]: Promise<Poll>; } = {};
|
2019-06-03 07:33:07 +02:00
|
|
|
|
2019-06-12 05:38:34 +02:00
|
|
|
private _poll: Poll;
|
|
|
|
@Input('poll')
|
|
|
|
set poll(value: Poll) {
|
2020-07-13 00:36:18 +02:00
|
|
|
if (!value) return;
|
2019-07-07 03:47:08 +02:00
|
|
|
|
2019-06-12 05:38:34 +02:00
|
|
|
this._poll = value;
|
2019-06-05 06:06:29 +02:00
|
|
|
|
2019-06-08 04:15:36 +02:00
|
|
|
this.pollName = this.poll.id;
|
2019-06-05 01:14:16 +02:00
|
|
|
|
2019-06-05 06:06:29 +02:00
|
|
|
if (this.poll.multiple) {
|
2019-06-05 00:36:04 +02:00
|
|
|
this.choiceType = 'checkbox';
|
|
|
|
} else {
|
|
|
|
this.choiceType = 'radio';
|
|
|
|
}
|
2019-06-05 01:14:16 +02:00
|
|
|
|
2019-06-08 04:15:36 +02:00
|
|
|
this.options.length = 0;
|
2024-03-08 06:51:27 +01:00
|
|
|
|
|
|
|
let maxVotes = Math.max(...this.poll.options.map(x => x.votes_count));
|
|
|
|
|
|
|
|
if(!this.poll.multiple){ //Fix for absurd values in pleroma
|
|
|
|
this.poll.voters_count = this.poll.votes_count;
|
|
|
|
} else if(this.poll.voters_count * this.poll.options.length < this.poll.votes_count){
|
|
|
|
this.poll.voters_count = this.poll.votes_count;
|
|
|
|
}
|
|
|
|
|
2019-06-05 01:14:16 +02:00
|
|
|
let i = 0;
|
2019-06-05 06:06:29 +02:00
|
|
|
for (let opt of this.poll.options) {
|
2021-03-12 05:09:12 +01:00
|
|
|
let optWrapper = new PollOptionWrapper(i, opt, this.poll.votes_count, this.poll.voters_count, opt.votes_count === maxVotes);
|
2019-06-05 01:14:16 +02:00
|
|
|
this.options.push(optWrapper);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
2019-06-12 05:38:34 +02:00
|
|
|
get poll(): Poll {
|
|
|
|
return this._poll;
|
|
|
|
}
|
|
|
|
|
2019-06-23 21:12:43 +02:00
|
|
|
// @Input() provider: AccountInfo;
|
|
|
|
@Input() statusWrapper: StatusWrapper;
|
2019-06-12 05:38:34 +02:00
|
|
|
|
|
|
|
private accounts$: Observable<AccountInfo[]>;
|
|
|
|
private accountSub: Subscription;
|
|
|
|
|
|
|
|
private selectedAccount: AccountInfo;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
private readonly store: Store,
|
|
|
|
private notificationService: NotificationService,
|
|
|
|
private toolsService: ToolsService,
|
2019-10-02 06:14:40 +02:00
|
|
|
private mastodonService: MastodonWrapperService) {
|
2019-06-12 05:38:34 +02:00
|
|
|
|
|
|
|
this.accounts$ = this.store.select(state => state.registeredaccounts.accounts);
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnInit() {
|
2019-06-23 21:12:43 +02:00
|
|
|
this.pollPerAccountId[this.statusWrapper.provider.id] = Promise.resolve(this.poll);
|
|
|
|
this.selectedAccount = this.statusWrapper.provider;
|
2019-06-12 05:38:34 +02:00
|
|
|
|
|
|
|
this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => {
|
|
|
|
this.checkStatus(accounts);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private checkStatus(accounts: AccountInfo[]): void {
|
|
|
|
this.pollLocked = false;
|
2020-07-13 00:36:18 +02:00
|
|
|
this.errorOccuredWhenRetrievingPoll = false;
|
2019-06-12 05:38:34 +02:00
|
|
|
var newSelectedAccount = accounts.find(x => x.isSelected);
|
|
|
|
|
|
|
|
const accountChanged = this.selectedAccount.id !== newSelectedAccount.id;
|
2019-06-23 21:12:43 +02:00
|
|
|
if (accountChanged && !this.pollPerAccountId[newSelectedAccount.id] && (this.statusWrapper.status.visibility === 'public' || this.statusWrapper.status.visibility === 'unlisted')) {
|
2019-06-12 05:38:34 +02:00
|
|
|
this.setStatsAtZero();
|
|
|
|
|
2020-04-01 08:29:51 +02:00
|
|
|
let statusWrapper = new StatusWrapper(this.statusWrapper.status, this.statusWrapper.provider, this.statusWrapper.applyCw, this.statusWrapper.hide);
|
|
|
|
this.pollPerAccountId[newSelectedAccount.id] = this.toolsService.getStatusUsableByAccount(newSelectedAccount, statusWrapper)
|
2019-06-12 05:38:34 +02:00
|
|
|
.then((status: Status) => {
|
2020-07-13 00:36:18 +02:00
|
|
|
if (!status || !(status.poll)) return null;
|
2019-06-12 05:38:34 +02:00
|
|
|
return this.mastodonService.getPoll(newSelectedAccount, status.poll.id);
|
|
|
|
})
|
|
|
|
.then((poll: Poll) => {
|
|
|
|
this.poll = poll;
|
|
|
|
return poll;
|
|
|
|
})
|
|
|
|
.catch(err => {
|
2020-07-13 00:36:18 +02:00
|
|
|
//this.notificationService.notifyHttpError(err, newSelectedAccount);
|
|
|
|
this.errorOccuredWhenRetrievingPoll = true;
|
|
|
|
this.pollPerAccountId[newSelectedAccount.id] = null;
|
2019-06-12 05:38:34 +02:00
|
|
|
return null;
|
|
|
|
});
|
2019-06-23 21:12:43 +02:00
|
|
|
} else if (this.statusWrapper.status.visibility !== 'public' && this.statusWrapper.status.visibility !== 'unlisted' && this.statusWrapper.provider.id !== newSelectedAccount.id) {
|
2019-06-12 05:38:34 +02:00
|
|
|
this.pollLocked = true;
|
|
|
|
} else {
|
|
|
|
this.pollPerAccountId[newSelectedAccount.id]
|
|
|
|
.then((poll: Poll) => {
|
|
|
|
this.poll = poll;
|
|
|
|
})
|
2019-09-07 23:52:07 +02:00
|
|
|
.catch(err => this.notificationService.notifyHttpError(err, newSelectedAccount));
|
2019-06-12 05:38:34 +02:00
|
|
|
}
|
|
|
|
this.selectedAccount = newSelectedAccount;
|
|
|
|
}
|
|
|
|
|
2019-06-05 01:14:16 +02:00
|
|
|
vote(): boolean {
|
2020-07-13 00:36:18 +02:00
|
|
|
if (this.errorOccuredWhenRetrievingPoll) return false;
|
|
|
|
|
2019-06-12 05:38:34 +02:00
|
|
|
const selectedAccount = this.selectedAccount;
|
|
|
|
const pollPromise = this.pollPerAccountId[selectedAccount.id];
|
|
|
|
|
|
|
|
pollPromise
|
|
|
|
.then((poll: Poll) => {
|
|
|
|
return this.mastodonService.voteOnPoll(selectedAccount, poll.id, this.pollSelection);
|
|
|
|
})
|
2019-06-05 01:33:36 +02:00
|
|
|
.then((poll: Poll) => {
|
|
|
|
this.poll = poll;
|
2019-06-12 05:38:34 +02:00
|
|
|
this.pollPerAccountId[selectedAccount.id] = Promise.resolve(poll);
|
2019-06-08 04:15:36 +02:00
|
|
|
})
|
2019-09-07 23:52:07 +02:00
|
|
|
.catch(err => this.notificationService.notifyHttpError(err, selectedAccount));
|
2019-06-08 04:15:36 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-06-12 05:38:34 +02:00
|
|
|
private setStatsAtZero() {
|
2019-06-08 04:15:36 +02:00
|
|
|
this.options.forEach(p => {
|
|
|
|
p.votes_count = 0;
|
|
|
|
p.percentage = '0';
|
|
|
|
});
|
2019-06-12 05:38:34 +02:00
|
|
|
}
|
2019-06-08 04:15:36 +02:00
|
|
|
|
2019-06-12 05:38:34 +02:00
|
|
|
refresh(): boolean {
|
2020-07-13 00:36:18 +02:00
|
|
|
if (this.errorOccuredWhenRetrievingPoll) return false;
|
|
|
|
|
2019-06-12 05:38:34 +02:00
|
|
|
this.setStatsAtZero();
|
|
|
|
|
|
|
|
const selectedAccount = this.selectedAccount;
|
|
|
|
const pollPromise = this.pollPerAccountId[selectedAccount.id];
|
|
|
|
|
|
|
|
pollPromise
|
|
|
|
.then((poll: Poll) => {
|
|
|
|
return this.mastodonService.getPoll(selectedAccount, poll.id);
|
|
|
|
})
|
2019-06-08 04:15:36 +02:00
|
|
|
.then((poll: Poll) => {
|
|
|
|
this.poll = poll;
|
2019-06-12 05:38:34 +02:00
|
|
|
this.pollPerAccountId[selectedAccount.id] = Promise.resolve(poll);
|
2019-06-05 01:33:36 +02:00
|
|
|
})
|
2019-09-07 23:52:07 +02:00
|
|
|
.catch(err => this.notificationService.notifyHttpError(err, selectedAccount));
|
2019-06-08 04:15:36 +02:00
|
|
|
|
2019-06-05 01:14:16 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-06-05 06:06:29 +02:00
|
|
|
onSelectionChange(entry: PollOptionWrapper) {
|
2019-06-05 01:14:16 +02:00
|
|
|
let index = entry.id;
|
2019-06-05 06:06:29 +02:00
|
|
|
if (this.poll.multiple) {
|
|
|
|
if (this.pollSelection.includes(index)) {
|
2019-06-05 01:14:16 +02:00
|
|
|
this.pollSelection = this.pollSelection.filter(x => x !== index);
|
|
|
|
} else {
|
|
|
|
this.pollSelection.push(index);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.pollSelection.length = 0;
|
|
|
|
this.pollSelection.push(index);
|
|
|
|
}
|
2019-06-03 07:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2019-06-05 01:14:16 +02:00
|
|
|
|
|
|
|
class PollOptionWrapper implements PollOption {
|
2021-03-12 05:09:12 +01:00
|
|
|
constructor(index: number, option: PollOption, totalVotes: number, totalVoters: number, isMax: boolean) {
|
|
|
|
let votesDivider = totalVotes;
|
|
|
|
if(totalVoters && totalVoters > 0){
|
|
|
|
votesDivider = totalVoters;
|
|
|
|
}
|
|
|
|
|
2019-06-05 01:14:16 +02:00
|
|
|
this.id = index;
|
|
|
|
this.title = option.title;
|
|
|
|
this.votes_count = option.votes_count;
|
2019-06-05 06:06:29 +02:00
|
|
|
if (totalVotes === 0) {
|
|
|
|
this.percentage = '0';
|
|
|
|
} else {
|
2024-03-08 06:51:27 +01:00
|
|
|
this.percentage = ((this.votes_count / votesDivider) * 100).toFixed(0);
|
2019-06-05 06:06:29 +02:00
|
|
|
}
|
2019-06-06 07:38:32 +02:00
|
|
|
this.isMax = isMax;
|
2019-06-05 01:14:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
id: number;
|
2019-06-05 06:06:29 +02:00
|
|
|
title: string;
|
2019-06-05 01:14:16 +02:00
|
|
|
votes_count: number;
|
2019-06-05 06:06:29 +02:00
|
|
|
percentage: string;
|
2019-06-06 07:38:32 +02:00
|
|
|
isMax: boolean;
|
2019-06-05 01:14:16 +02:00
|
|
|
}
|