From 34644e0652f00212a2c1010e61b145f0b4c893f1 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Sun, 2 Jun 2019 20:28:22 -0400 Subject: [PATCH 01/17] updated mastodon interface to support polls #93 --- src/app/services/models/mastodon.interfaces.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/app/services/models/mastodon.interfaces.ts b/src/app/services/models/mastodon.interfaces.ts index 63d9ff66..186c5ed4 100644 --- a/src/app/services/models/mastodon.interfaces.ts +++ b/src/app/services/models/mastodon.interfaces.ts @@ -1,3 +1,5 @@ +import { PlatformLocation } from '@angular/common'; + export interface AppData { client_id: string; client_secret: string; @@ -174,6 +176,7 @@ export interface Status { language: string; pinned: boolean; card: Card; + poll: Poll; pleroma: PleromaStatusInfo; } @@ -191,4 +194,19 @@ export interface Tag { export interface List { id: string; title: string; +} + +export interface Poll { + id: string; + expires_at: string; + expired: boolean; + multiple: boolean; + votes_count: number; + options: PollOption[]; + voted: boolean; +} + +export interface PollOption { + title: string; + votes_count: number; } \ No newline at end of file From 43ecbde31a8aaa9ff05c702de1a9cddcecd966dc Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Mon, 3 Jun 2019 01:33:07 -0400 Subject: [PATCH 02/17] added poll component #93 --- src/app/app.module.ts | 4 ++- .../stream/status/poll/poll.component.html | 8 ++++++ .../stream/status/poll/poll.component.scss | 0 .../stream/status/poll/poll.component.spec.ts | 25 +++++++++++++++++++ .../stream/status/poll/poll.component.ts | 22 ++++++++++++++++ .../stream/status/status.component.html | 2 ++ 6 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/app/components/stream/status/poll/poll.component.html create mode 100644 src/app/components/stream/status/poll/poll.component.scss create mode 100644 src/app/components/stream/status/poll/poll.component.spec.ts create mode 100644 src/app/components/stream/status/poll/poll.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5384c05b..baf785e2 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -60,6 +60,7 @@ import { AccountEmojiPipe } from './pipes/account-emoji.pipe'; import { CardComponent } from './components/stream/status/card/card.component'; import { ListEditorComponent } from './components/floating-column/manage-account/my-account/list-editor/list-editor.component'; import { ListAccountComponent } from './components/floating-column/manage-account/my-account/list-editor/list-account/list-account.component'; +import { PollComponent } from './components/stream/status/poll/poll.component'; const routes: Routes = [ { path: "", redirectTo: "home", pathMatch: "full" }, @@ -108,7 +109,8 @@ const routes: Routes = [ AccountEmojiPipe, CardComponent, ListEditorComponent, - ListAccountComponent + ListAccountComponent, + PollComponent ], imports: [ FontAwesomeModule, diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html new file mode 100644 index 00000000..e06aa38e --- /dev/null +++ b/src/app/components/stream/status/poll/poll.component.html @@ -0,0 +1,8 @@ +
+
+ + +
+
+ Vote {{poll.votes_count}} votes - X days left +
\ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.scss b/src/app/components/stream/status/poll/poll.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/stream/status/poll/poll.component.spec.ts b/src/app/components/stream/status/poll/poll.component.spec.ts new file mode 100644 index 00000000..111d6548 --- /dev/null +++ b/src/app/components/stream/status/poll/poll.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PollComponent } from './poll.component'; + +xdescribe('PollComponent', () => { + let component: PollComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PollComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PollComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts new file mode 100644 index 00000000..5a8aae4d --- /dev/null +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -0,0 +1,22 @@ +import { Component, OnInit, Input } from '@angular/core'; + +import { Poll } from '../../../../services/models/mastodon.interfaces'; + +@Component({ + selector: 'app-poll', + templateUrl: './poll.component.html', + styleUrls: ['./poll.component.scss'] +}) +export class PollComponent implements OnInit { + // choiceType: string = 'radio'; + choiceType: string = 'checkbox'; + + @Input() poll: Poll; + + constructor() { } + + ngOnInit() { + + } + +} diff --git a/src/app/components/stream/status/status.component.html b/src/app/components/stream/status/status.component.html index 9b091474..bfdaca9d 100644 --- a/src/app/components/stream/status/status.component.html +++ b/src/app/components/stream/status/status.component.html @@ -67,6 +67,8 @@ (accountSelected)="accountSelected($event)" (hashtagSelected)="hashtagSelected($event)" (textSelected)="textSelected()"> + + Date: Tue, 4 Jun 2019 02:31:51 -0400 Subject: [PATCH 03/17] starting the design of polls --- .../stream/status/poll/poll.component.html | 6 ++-- .../stream/status/poll/poll.component.scss | 32 +++++++++++++++++++ .../stream/status/status.component.html | 2 +- .../stream/status/status.component.scss | 5 +++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html index e06aa38e..05c07a80 100644 --- a/src/app/components/stream/status/poll/poll.component.html +++ b/src/app/components/stream/status/poll/poll.component.html @@ -1,8 +1,8 @@
- - + +
- Vote {{poll.votes_count}} votes - X days left +
{{poll.votes_count}} votes - X days left
\ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.scss b/src/app/components/stream/status/poll/poll.component.scss index e69de29b..b716675a 100644 --- a/src/app/components/stream/status/poll/poll.component.scss +++ b/src/app/components/stream/status/poll/poll.component.scss @@ -0,0 +1,32 @@ +// @import "variables"; +// @import "commons"; +// @import "panel"; +@import "buttons"; + +.poll { + + &__btn-vote { + margin: 0 10px 0 0; + padding: 4px 15px; + } + + &__statistics { + display: inline-block; + font-size: 0.8em; + color: rgb(101, 121, 160); + } + + &__label { + cursor: pointer; + } +} + +.noselect { + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently + supported by Chrome and Opera */ + } \ No newline at end of file diff --git a/src/app/components/stream/status/status.component.html b/src/app/components/stream/status/status.component.html index bfdaca9d..1dfa129b 100644 --- a/src/app/components/stream/status/status.component.html +++ b/src/app/components/stream/status/status.component.html @@ -67,7 +67,7 @@ (accountSelected)="accountSelected($event)" (hashtagSelected)="hashtagSelected($event)" (textSelected)="textSelected()"> - + diff --git a/src/app/components/stream/status/status.component.scss b/src/app/components/stream/status/status.component.scss index 6afae100..14c2f362 100644 --- a/src/app/components/stream/status/status.component.scss +++ b/src/app/components/stream/status/status.component.scss @@ -116,6 +116,11 @@ margin: 10px 10px 0 $avatar-column-space; display: block; } + &__poll { + word-wrap: break-word; + margin: 10px 10px 0 $avatar-column-space; + display: block; + } &__content-warning { min-height: 80px; display: block; // border: 1px solid greenyellow; From 131054514cd96931f3bf3351fbb34c22d5520cee Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Tue, 4 Jun 2019 18:36:04 -0400 Subject: [PATCH 04/17] styling the poll choices #93 --- .../stream/status/poll/poll.component.html | 14 ++- .../stream/status/poll/poll.component.scss | 109 ++++++++++++++++-- .../stream/status/poll/poll.component.ts | 13 ++- 3 files changed, 123 insertions(+), 13 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html index 05c07a80..a7e25b38 100644 --- a/src/app/components/stream/status/poll/poll.component.html +++ b/src/app/components/stream/status/poll/poll.component.html @@ -1,8 +1,16 @@
- + + + +
+
+ +
{{poll.votes_count}} votes - X days left
-
{{poll.votes_count}} votes - X days left
\ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.scss b/src/app/components/stream/status/poll/poll.component.scss index b716675a..6c6eb46f 100644 --- a/src/app/components/stream/status/poll/poll.component.scss +++ b/src/app/components/stream/status/poll/poll.component.scss @@ -19,14 +19,109 @@ &__label { cursor: pointer; } + + &__voting { + margin-top: 10px; + } + + &__container { + display: block; + position: relative; + padding-left: 25px; + margin: 0 0 5px 5px; + cursor: pointer; + // font-size: 22px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + &:hover &__input~&__checkmark { + background-color: #ccc; + } + + & &__input:checked~&__checkmark { + background-color: rgb(62, 75, 100); + } + + &__input { + position: absolute; + opacity: 0; + cursor: pointer; + height: 0; + width: 0; + } + + &__checkmark--box { + position: absolute; + top: 0; + left: 0; + height: 20px; + width: 20px; + background-color: #eee; + + &:after { + content: ""; + position: absolute; + display: none; + } + } + + &__checkmark--round { + position: absolute; + top: 0; + left: 0; + height: 20px; + width: 20px; + background-color: #eee; + border-radius: 50%; + } + + & &__input:checked:checked~&__checkmark:after { + display: block; + } + + & &__checkmark--box:after { + left: 7px; + top: 5px; + width: 5px; + height: 10px; + border: solid white; + border-width: 0 3px 3px 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + } + + &__checkmark--round:after { + content: ""; + position: absolute; + display: none; + } + + & &__checkmark--round:after { + top: 6px; + left: 6px; + width: 8px; + height: 8px; + border-radius: 50%; + background: white; + } + } } .noselect { - -webkit-touch-callout: none; /* iOS Safari */ - -webkit-user-select: none; /* Safari */ - -khtml-user-select: none; /* Konqueror HTML */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* Internet Explorer/Edge */ - user-select: none; /* Non-prefixed version, currently + -webkit-touch-callout: none; + /* iOS Safari */ + -webkit-user-select: none; + /* Safari */ + -khtml-user-select: none; + /* Konqueror HTML */ + -moz-user-select: none; + /* Firefox */ + -ms-user-select: none; + /* Internet Explorer/Edge */ + user-select: none; + /* Non-prefixed version, currently supported by Chrome and Opera */ - } \ No newline at end of file +} \ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index 5a8aae4d..77409030 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -8,15 +8,22 @@ import { Poll } from '../../../../services/models/mastodon.interfaces'; styleUrls: ['./poll.component.scss'] }) export class PollComponent implements OnInit { - // choiceType: string = 'radio'; - choiceType: string = 'checkbox'; + pollName: string; + + choiceType: string;// = 'radio'; + //choiceType: string = 'checkbox'; @Input() poll: Poll; constructor() { } ngOnInit() { - + this.pollName = this.poll.id; + if(this.poll.multiple){ + this.choiceType = 'checkbox'; + } else { + this.choiceType = 'radio'; + } } } From 55684d5ada67c15d41d8d1a88cfecf6583fe06e1 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Tue, 4 Jun 2019 19:14:16 -0400 Subject: [PATCH 05/17] added poll selection retrieval #93 --- .../stream/status/poll/poll.component.html | 7 +-- .../stream/status/poll/poll.component.ts | 53 +++++++++++++++++-- .../stream/status/status.component.html | 3 +- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html index a7e25b38..02892c5d 100644 --- a/src/app/components/stream/status/poll/poll.component.html +++ b/src/app/components/stream/status/poll/poll.component.html @@ -1,16 +1,17 @@
-
+
- +
{{poll.votes_count}} votes - X days left
\ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index 77409030..c62c7e5d 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit, Input } from '@angular/core'; -import { Poll } from '../../../../services/models/mastodon.interfaces'; +import { Poll, PollOption } from '../../../../services/models/mastodon.interfaces'; +import { AccountInfo } from '../../../../states/accounts.state'; @Component({ selector: 'app-poll', @@ -8,22 +9,66 @@ import { Poll } from '../../../../services/models/mastodon.interfaces'; styleUrls: ['./poll.component.scss'] }) export class PollComponent implements OnInit { - pollName: string; + pollName: string; + choiceType: string; - choiceType: string;// = 'radio'; - //choiceType: string = 'checkbox'; + private pollSelection: number[] = []; + options: PollOptionWrapper[] = []; @Input() poll: Poll; + @Input() provider: AccountInfo; constructor() { } ngOnInit() { this.pollName = this.poll.id; + + // this.poll.multiple = true; + if(this.poll.multiple){ this.choiceType = 'checkbox'; } else { this.choiceType = 'radio'; } + + let i = 0; + for(let opt of this.poll.options){ + let optWrapper = new PollOptionWrapper(i, opt); + this.options.push(optWrapper); + i++; + } + } + + vote(): boolean { + console.log(this.pollSelection); + + return false; + } + + onSelectionChange(entry: PollOptionWrapper){ + let index = entry.id; + if(this.poll.multiple){ + if(this.pollSelection.includes(index)){ + this.pollSelection = this.pollSelection.filter(x => x !== index); + } else { + this.pollSelection.push(index); + } + } else { + this.pollSelection.length = 0; + this.pollSelection.push(index); + } } } + +class PollOptionWrapper implements PollOption { + constructor(index: number, option: PollOption){ + this.id = index; + this.title = option.title; + this.votes_count = option.votes_count; + } + + id: number; + title: string; + votes_count: number; +} \ No newline at end of file diff --git a/src/app/components/stream/status/status.component.html b/src/app/components/stream/status/status.component.html index 1dfa129b..f3ac3722 100644 --- a/src/app/components/stream/status/status.component.html +++ b/src/app/components/stream/status/status.component.html @@ -67,7 +67,8 @@ (accountSelected)="accountSelected($event)" (hashtagSelected)="hashtagSelected($event)" (textSelected)="textSelected()"> - + From 979d21bdfe90c5d801065a7108b82efe5ba687eb Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Tue, 4 Jun 2019 19:33:36 -0400 Subject: [PATCH 06/17] added service #93 --- .../stream/status/poll/poll.component.ts | 15 +++++++++++++-- src/app/services/mastodon.service.ts | 12 ++++++++++-- src/app/services/models/api.settings.ts | 1 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index c62c7e5d..1016ece8 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -2,6 +2,8 @@ import { Component, OnInit, Input } from '@angular/core'; import { Poll, PollOption } from '../../../../services/models/mastodon.interfaces'; import { AccountInfo } from '../../../../states/accounts.state'; +import { MastodonService } from '../../../../services/mastodon.service'; +import { NotificationService } from '../../../../services/notification.service'; @Component({ selector: 'app-poll', @@ -18,12 +20,14 @@ export class PollComponent implements OnInit { @Input() poll: Poll; @Input() provider: AccountInfo; - constructor() { } + constructor( + private notificationService: NotificationService, + private mastodonService: MastodonService) { } ngOnInit() { this.pollName = this.poll.id; - // this.poll.multiple = true; + //this.poll.multiple = true; if(this.poll.multiple){ this.choiceType = 'checkbox'; @@ -42,6 +46,13 @@ export class PollComponent implements OnInit { vote(): boolean { console.log(this.pollSelection); + this.mastodonService.voteOnPoll(this.provider, this.poll.id, this.pollSelection) + .then((poll: Poll) => { + this.poll = poll; + }) + .catch(err => { + this.notificationService.notifyHttpError(err); + }); return false; } diff --git a/src/app/services/mastodon.service.ts b/src/app/services/mastodon.service.ts index dce27b31..5dc797a5 100644 --- a/src/app/services/mastodon.service.ts +++ b/src/app/services/mastodon.service.ts @@ -2,12 +2,12 @@ import { Injectable } from '@angular/core'; import { HttpHeaders, HttpClient, HttpResponse } from '@angular/common/http'; import { ApiRoutes } from './models/api.settings'; -import { Account, Status, Results, Context, Relationship, Instance, Attachment, Notification, List } from "./models/mastodon.interfaces"; +import { Account, Status, Results, Context, Relationship, Instance, Attachment, Notification, List, Poll } from "./models/mastodon.interfaces"; import { AccountInfo } from '../states/accounts.state'; import { StreamTypeEnum, StreamElement } from '../states/streams.state'; @Injectable() -export class MastodonService { +export class MastodonService { private apiRoutes = new ApiRoutes(); constructor(private readonly httpClient: HttpClient) { } @@ -306,6 +306,14 @@ export class MastodonService { const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` }); return this.httpClient.delete(route, { headers: headers }).toPromise(); } + + voteOnPoll(account: AccountInfo, pollId: string, pollSelection: number[]): Promise { + let route = `https://${account.instance}${this.apiRoutes.voteOnPoll}`.replace('{0}', pollId); + route += `?${this.formatArray(pollSelection.map(x => x.toString()), 'choices')}`; + + const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` }); + return this.httpClient.post(route, null, { headers: headers }).toPromise(); + } } export enum VisibilityEnum { diff --git a/src/app/services/models/api.settings.ts b/src/app/services/models/api.settings.ts index 4cb3702c..09668996 100644 --- a/src/app/services/models/api.settings.ts +++ b/src/app/services/models/api.settings.ts @@ -59,4 +59,5 @@ export class ApiRoutes { deleteList = '/api/v1/lists/{0}'; addAccountToList = '/api/v1/lists/{0}/accounts'; removeAccountFromList = '/api/v1/lists/{0}/accounts'; + voteOnPoll = '/api/v1/polls/{0}/votes'; } From c122d66fb64a8cb76dcaf59293f76794b65e5f90 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Wed, 5 Jun 2019 00:06:29 -0400 Subject: [PATCH 07/17] displaying result percentages #93 --- .../stream/status/poll/poll.component.html | 32 ++++++++++++------- .../stream/status/poll/poll.component.scss | 21 ++++++++++++ .../stream/status/poll/poll.component.ts | 30 +++++++++++------ 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html index 02892c5d..059cbeff 100644 --- a/src/app/components/stream/status/poll/poll.component.html +++ b/src/app/components/stream/status/poll/poll.component.html @@ -1,17 +1,25 @@
-
- - - +
+
+ +
+
+
+
+
+ {{ o.percentage }}% {{o.title}} +
+
- -
{{poll.votes_count}} votes - X days left
+ + refresh +
· {{poll.votes_count}} votes · X days left
\ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.scss b/src/app/components/stream/status/poll/poll.component.scss index 6c6eb46f..1b7bde85 100644 --- a/src/app/components/stream/status/poll/poll.component.scss +++ b/src/app/components/stream/status/poll/poll.component.scss @@ -4,6 +4,8 @@ @import "buttons"; .poll { + color: white; + color: rgb(228, 228, 228); &__btn-vote { margin: 0 10px 0 0; @@ -24,6 +26,11 @@ margin-top: 10px; } + &__refresh { + font-size: 0.8em; + color: rgb(101, 121, 160); + } + &__container { display: block; position: relative; @@ -108,6 +115,20 @@ background: white; } } + + &__result { + margin: 0 0 5px 5px; + + &--percentage { + // font-weight: bold; + // font-weight: 600; + // font-style: italic; + color: rgb(228, 228, 228); + color: white; + display: inline; + margin-right: 10px; + } + } } .noselect { diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index 1016ece8..8e19d3f2 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -11,7 +11,7 @@ import { NotificationService } from '../../../../services/notification.service'; styleUrls: ['./poll.component.scss'] }) export class PollComponent implements OnInit { - pollName: string; + pollName: string; choiceType: string; private pollSelection: number[] = []; @@ -26,18 +26,18 @@ export class PollComponent implements OnInit { ngOnInit() { this.pollName = this.poll.id; - + //this.poll.multiple = true; - if(this.poll.multiple){ + if (this.poll.multiple) { this.choiceType = 'checkbox'; } else { this.choiceType = 'radio'; } let i = 0; - for(let opt of this.poll.options){ - let optWrapper = new PollOptionWrapper(i, opt); + for (let opt of this.poll.options) { + let optWrapper = new PollOptionWrapper(i, opt, this.poll.votes_count); this.options.push(optWrapper); i++; } @@ -56,10 +56,10 @@ export class PollComponent implements OnInit { return false; } - onSelectionChange(entry: PollOptionWrapper){ + onSelectionChange(entry: PollOptionWrapper) { let index = entry.id; - if(this.poll.multiple){ - if(this.pollSelection.includes(index)){ + if (this.poll.multiple) { + if (this.pollSelection.includes(index)) { this.pollSelection = this.pollSelection.filter(x => x !== index); } else { this.pollSelection.push(index); @@ -73,13 +73,23 @@ export class PollComponent implements OnInit { } class PollOptionWrapper implements PollOption { - constructor(index: number, option: PollOption){ + constructor(index: number, option: PollOption, totalVotes: number) { this.id = index; this.title = option.title; this.votes_count = option.votes_count; + console.log(this.votes_count); + console.log(totalVotes); + console.log(this.votes_count / totalVotes); + console.log( (this.votes_count / totalVotes) * 100); + if (totalVotes === 0) { + this.percentage = '0'; + } else { + this.percentage = ((this.votes_count / totalVotes) * 100).toFixed(0); + } } id: number; - title: string; + title: string; votes_count: number; + percentage: string; } \ No newline at end of file From f72141a79441b28791bc2b6b1b1572ed477c717a Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Thu, 6 Jun 2019 01:38:32 -0400 Subject: [PATCH 08/17] added poll progress bars #93 --- .../stream/status/poll/poll.component.html | 13 +++++---- .../stream/status/poll/poll.component.scss | 29 +++++++++++++++++-- .../stream/status/poll/poll.component.ts | 14 ++++----- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html index 059cbeff..aa570621 100644 --- a/src/app/components/stream/status/poll/poll.component.html +++ b/src/app/components/stream/status/poll/poll.component.html @@ -11,15 +11,18 @@
-
- {{ o.percentage }}% {{o.title}} +
+
+
{{ o.percentage }}% + {{o.title}}
+
- - refresh + + refresh
· {{poll.votes_count}} votes · X days left
\ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.scss b/src/app/components/stream/status/poll/poll.component.scss index 1b7bde85..af1a342c 100644 --- a/src/app/components/stream/status/poll/poll.component.scss +++ b/src/app/components/stream/status/poll/poll.component.scss @@ -118,15 +118,38 @@ &__result { margin: 0 0 5px 5px; + padding: 0 5px 0 5px; + position: relative; + height: 26px; + + &--data { + position: absolute; + z-index: 10; + } &--percentage { - // font-weight: bold; - // font-weight: 600; - // font-style: italic; color: rgb(228, 228, 228); color: white; display: inline; margin-right: 10px; + + } + + &--progress-bar { + position: absolute; + background-color: rgb(47, 68, 100); + // background-color: rgb(43, 62, 92); + top:0; + left:0; + width: calc(100%); + height: 21px; + z-index: 1; + float: left; + border-radius: 2px; + + &--most-votes { + background-color: rgb(18, 118, 158); + } } } } diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index 8e19d3f2..007021f9 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -35,17 +35,16 @@ export class PollComponent implements OnInit { this.choiceType = 'radio'; } + const maxVotes = Math.max(...this.poll.options.map(x => x.votes_count)); let i = 0; for (let opt of this.poll.options) { - let optWrapper = new PollOptionWrapper(i, opt, this.poll.votes_count); + let optWrapper = new PollOptionWrapper(i, opt, this.poll.votes_count, opt.votes_count === maxVotes); this.options.push(optWrapper); i++; } } vote(): boolean { - console.log(this.pollSelection); - this.mastodonService.voteOnPoll(this.provider, this.poll.id, this.pollSelection) .then((poll: Poll) => { this.poll = poll; @@ -73,23 +72,22 @@ export class PollComponent implements OnInit { } class PollOptionWrapper implements PollOption { - constructor(index: number, option: PollOption, totalVotes: number) { + constructor(index: number, option: PollOption, totalVotes: number, isMax: boolean) { this.id = index; this.title = option.title; this.votes_count = option.votes_count; - console.log(this.votes_count); - console.log(totalVotes); - console.log(this.votes_count / totalVotes); - console.log( (this.votes_count / totalVotes) * 100); if (totalVotes === 0) { this.percentage = '0'; } else { this.percentage = ((this.votes_count / totalVotes) * 100).toFixed(0); } + this.isMax = isMax; + console.warn(this.isMax); } id: number; title: string; votes_count: number; percentage: string; + isMax: boolean; } \ No newline at end of file From b8311371f9a89099ddae311a87fc84e5aaeebcb0 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Thu, 6 Jun 2019 19:01:04 -0400 Subject: [PATCH 09/17] better display of poll button #93 --- .../stream/status/poll/poll.component.html | 4 ++-- .../stream/status/poll/poll.component.scss | 12 ++++++++---- .../components/stream/status/poll/poll.component.ts | 1 - 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html index aa570621..0ff1feb2 100644 --- a/src/app/components/stream/status/poll/poll.component.html +++ b/src/app/components/stream/status/poll/poll.component.html @@ -22,7 +22,7 @@
- refresh -
· {{poll.votes_count}} votes · X days left
+ refresh +
·{{poll.votes_count}} votes· X days left
\ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.scss b/src/app/components/stream/status/poll/poll.component.scss index af1a342c..3ab37e63 100644 --- a/src/app/components/stream/status/poll/poll.component.scss +++ b/src/app/components/stream/status/poll/poll.component.scss @@ -120,7 +120,7 @@ margin: 0 0 5px 5px; padding: 0 5px 0 5px; position: relative; - height: 26px; + height: 27px; &--data { position: absolute; @@ -142,7 +142,7 @@ top:0; left:0; width: calc(100%); - height: 21px; + height: 22px; z-index: 1; float: left; border-radius: 2px; @@ -152,6 +152,11 @@ } } } + + &__separator { + display: inline-block; + margin: 0 5px; + } } .noselect { @@ -166,6 +171,5 @@ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; - /* Non-prefixed version, currently - supported by Chrome and Opera */ + /* Non-prefixed version, currently supported by Chrome and Opera */ } \ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index 007021f9..c4c340f3 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -82,7 +82,6 @@ class PollOptionWrapper implements PollOption { this.percentage = ((this.votes_count / totalVotes) * 100).toFixed(0); } this.isMax = isMax; - console.warn(this.isMax); } id: number; From 6cb2132bf9aead0d902ffb356e39d7e8ad193029 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Thu, 6 Jun 2019 19:28:45 -0400 Subject: [PATCH 10/17] added time left display #93 --- src/app/app.module.ts | 4 +- .../stream/status/poll/poll.component.html | 2 +- src/app/pipes/time-left.pipe.spec.ts | 8 ++ src/app/pipes/time-left.pipe.ts | 106 ++++++++++++++++++ 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 src/app/pipes/time-left.pipe.spec.ts create mode 100644 src/app/pipes/time-left.pipe.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index baf785e2..7abfafcc 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -61,6 +61,7 @@ import { CardComponent } from './components/stream/status/card/card.component'; import { ListEditorComponent } from './components/floating-column/manage-account/my-account/list-editor/list-editor.component'; import { ListAccountComponent } from './components/floating-column/manage-account/my-account/list-editor/list-account/list-account.component'; import { PollComponent } from './components/stream/status/poll/poll.component'; +import { TimeLeftPipe } from './pipes/time-left.pipe'; const routes: Routes = [ { path: "", redirectTo: "home", pathMatch: "full" }, @@ -110,7 +111,8 @@ const routes: Routes = [ CardComponent, ListEditorComponent, ListAccountComponent, - PollComponent + PollComponent, + TimeLeftPipe ], imports: [ FontAwesomeModule, diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html index 0ff1feb2..dc54ba10 100644 --- a/src/app/components/stream/status/poll/poll.component.html +++ b/src/app/components/stream/status/poll/poll.component.html @@ -23,6 +23,6 @@ refresh -
·{{poll.votes_count}} votes· X days left
+
·{{poll.votes_count}} votes· {{ poll.expires_at | timeLeft | async }}
\ No newline at end of file diff --git a/src/app/pipes/time-left.pipe.spec.ts b/src/app/pipes/time-left.pipe.spec.ts new file mode 100644 index 00000000..fea69b28 --- /dev/null +++ b/src/app/pipes/time-left.pipe.spec.ts @@ -0,0 +1,8 @@ +import { TimeLeftPipe } from './time-left.pipe'; + +xdescribe('TimeLeftPipe', () => { + it('create an instance', () => { + const pipe = new TimeLeftPipe(null); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/app/pipes/time-left.pipe.ts b/src/app/pipes/time-left.pipe.ts new file mode 100644 index 00000000..eb3ba1a3 --- /dev/null +++ b/src/app/pipes/time-left.pipe.ts @@ -0,0 +1,106 @@ +import { Pipe, PipeTransform, NgZone } from '@angular/core'; +import { Observable, Observer } from 'rxjs'; + +interface processOutput { + text: string; // Convert timestamp to string + timeToUpdate: number; // Time until update in milliseconds +} + +@Pipe({ + name: 'timeLeft' +}) +export class TimeLeftPipe implements PipeTransform { + + constructor(private ngZone: NgZone) { } + + private process = (timestamp: number): processOutput => { + let text: string; + let timeToUpdate: number; + + const now = new Date(); + + // Time ago in milliseconds + const timeLeft: number = timestamp - now.getTime(); + + const seconds = timeLeft / 1000; + const minutes = seconds / 60; + const hours = minutes / 60; + const days = hours / 24; + // const months = days / 30.416; + // const years = days / 365; + + if (seconds < 0) { + text = '0 seconds left'; + } else if (seconds <= 60) { + text = Math.round(seconds) + ' seconds left'; + } else if (minutes <= 90) { + text = Math.round(minutes) + ' minutes left'; + } else if (hours <= 24) { + text = Math.round(hours) + ' hours left'; + } else { + text = Math.round(days) + ' days left'; + } + + if (seconds < -10) { + // update every week + timeToUpdate = 7 * 24 * 3600 * 1000; + } else if (minutes < 1) { + // update every 2 secs + timeToUpdate = 2 * 1000; + } else if (hours < 1) { + // update every 30 secs + timeToUpdate = 30 * 1000; + } else if (days < 1) { + // update every 5 mins + timeToUpdate = 300 * 1000; + } else { + // update every hour + timeToUpdate = 3600 * 1000; + } + + return { + text, + timeToUpdate + }; + } + + public transform = (value: string | Date): Observable => { + let d: Date; + if (value instanceof Date) { + d = value; + } + else { + d = new Date(value); + } + // time value in milliseconds + const timestamp = d.getTime(); + + let timeoutID: any; + + return Observable.create((observer: Observer) => { + let latestText = ''; + + // Repeatedly set new timeouts for new update checks. + const registerUpdate = () => { + const processOutput = this.process(timestamp); + if (processOutput.text !== latestText) { + latestText = processOutput.text; + this.ngZone.run(() => { + observer.next(latestText); + }); + } + timeoutID = setTimeout(registerUpdate, processOutput.timeToUpdate); + }; + + this.ngZone.runOutsideAngular(registerUpdate); + + // Return teardown function + const teardownFunction = () => { + if (timeoutID) { + clearTimeout(timeoutID); + } + }; + return teardownFunction; + }); + } +} From f591955e497f2f66ac214fcf4755afa0481a065b Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Fri, 7 Jun 2019 22:15:36 -0400 Subject: [PATCH 11/17] added refresh poll functionnality #93 --- .../stream/status/poll/poll.component.html | 2 +- .../stream/status/poll/poll.component.scss | 3 +++ .../stream/status/poll/poll.component.ts | 26 +++++++++++++++++-- src/app/services/mastodon.service.ts | 8 +++++- src/app/services/models/api.settings.ts | 1 + 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html index dc54ba10..e61e3f7e 100644 --- a/src/app/components/stream/status/poll/poll.component.html +++ b/src/app/components/stream/status/poll/poll.component.html @@ -22,7 +22,7 @@
- refresh + refresh
·{{poll.votes_count}} votes· {{ poll.expires_at | timeLeft | async }}
\ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.scss b/src/app/components/stream/status/poll/poll.component.scss index 3ab37e63..76cc74ca 100644 --- a/src/app/components/stream/status/poll/poll.component.scss +++ b/src/app/components/stream/status/poll/poll.component.scss @@ -4,6 +4,7 @@ @import "buttons"; .poll { + color: white; color: rgb(228, 228, 228); @@ -117,6 +118,8 @@ } &__result { + transition: width 2s; + margin: 0 0 5px 5px; padding: 0 5px 0 5px; position: relative; diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index c4c340f3..2b514cc8 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -25,9 +25,11 @@ export class PollComponent implements OnInit { private mastodonService: MastodonService) { } ngOnInit() { - this.pollName = this.poll.id; + this.loadPoll(); + } - //this.poll.multiple = true; + private loadPoll() { + this.pollName = this.poll.id; if (this.poll.multiple) { this.choiceType = 'checkbox'; @@ -35,6 +37,7 @@ export class PollComponent implements OnInit { this.choiceType = 'radio'; } + this.options.length = 0; const maxVotes = Math.max(...this.poll.options.map(x => x.votes_count)); let i = 0; for (let opt of this.poll.options) { @@ -48,10 +51,29 @@ export class PollComponent implements OnInit { this.mastodonService.voteOnPoll(this.provider, this.poll.id, this.pollSelection) .then((poll: Poll) => { this.poll = poll; + this.loadPoll(); + }) + .catch(err => { + this.notificationService.notifyHttpError(err); + }); + return false; + } + + refresh(): boolean { + this.options.forEach(p => { + p.votes_count = 0; + p.percentage = '0'; + }); + + this.mastodonService.getPoll(this.provider, this.poll.id) + .then((poll: Poll) => { + this.poll = poll; + this.loadPoll(); }) .catch(err => { this.notificationService.notifyHttpError(err); }); + return false; } diff --git a/src/app/services/mastodon.service.ts b/src/app/services/mastodon.service.ts index 5dc797a5..afbf664a 100644 --- a/src/app/services/mastodon.service.ts +++ b/src/app/services/mastodon.service.ts @@ -7,7 +7,7 @@ import { AccountInfo } from '../states/accounts.state'; import { StreamTypeEnum, StreamElement } from '../states/streams.state'; @Injectable() -export class MastodonService { +export class MastodonService { private apiRoutes = new ApiRoutes(); constructor(private readonly httpClient: HttpClient) { } @@ -314,6 +314,12 @@ export class MastodonService { const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` }); return this.httpClient.post(route, null, { headers: headers }).toPromise(); } + + getPoll(account: AccountInfo, pollId: string): Promise { + let route = `https://${account.instance}${this.apiRoutes.getPoll}`.replace('{0}', pollId); + const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` }); + return this.httpClient.get(route, { headers: headers }).toPromise(); + } } export enum VisibilityEnum { diff --git a/src/app/services/models/api.settings.ts b/src/app/services/models/api.settings.ts index 09668996..bfb00405 100644 --- a/src/app/services/models/api.settings.ts +++ b/src/app/services/models/api.settings.ts @@ -60,4 +60,5 @@ export class ApiRoutes { addAccountToList = '/api/v1/lists/{0}/accounts'; removeAccountFromList = '/api/v1/lists/{0}/accounts'; voteOnPoll = '/api/v1/polls/{0}/votes'; + getPoll = '/api/v1/polls/{0}'; } From 26bc0cf44b4aa901fb5071f1fd0ae820514a7dac Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Tue, 11 Jun 2019 23:38:34 -0400 Subject: [PATCH 12/17] poll are multi-user compatible #93 --- .../stream/status/poll/poll.component.ts | 120 ++++++++++++++---- .../stream/status/status.component.html | 2 +- 2 files changed, 99 insertions(+), 23 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index 2b514cc8..666ed659 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -1,9 +1,13 @@ import { Component, OnInit, Input } from '@angular/core'; +import { Store } from '@ngxs/store'; +import { Observable, Subscription } from 'rxjs'; -import { Poll, PollOption } from '../../../../services/models/mastodon.interfaces'; +import { Poll, PollOption, Status } from '../../../../services/models/mastodon.interfaces'; import { AccountInfo } from '../../../../states/accounts.state'; import { MastodonService } from '../../../../services/mastodon.service'; import { NotificationService } from '../../../../services/notification.service'; +import { ToolsService } from '../../../../services/tools.service'; +import { StatusWrapper } from '../../../../models/common.model'; @Component({ selector: 'app-poll', @@ -13,22 +17,18 @@ import { NotificationService } from '../../../../services/notification.service'; export class PollComponent implements OnInit { pollName: string; choiceType: string; + pollLocked: boolean; private pollSelection: number[] = []; options: PollOptionWrapper[] = []; - @Input() poll: Poll; - @Input() provider: AccountInfo; + private pollPerAccountId: { [id: string]: Promise; } = {}; - constructor( - private notificationService: NotificationService, - private mastodonService: MastodonService) { } - - ngOnInit() { - this.loadPoll(); - } + private _poll: Poll; + @Input('poll') + set poll(value: Poll) { + this._poll = value; - private loadPoll() { this.pollName = this.poll.id; if (this.poll.multiple) { @@ -46,33 +46,109 @@ export class PollComponent implements OnInit { i++; } } + get poll(): Poll { + return this._poll; + } + + @Input() provider: AccountInfo; + @Input() status: Status; + + private accounts$: Observable; + private accountSub: Subscription; + + private selectedAccount: AccountInfo; + + constructor( + private readonly store: Store, + private notificationService: NotificationService, + private toolsService: ToolsService, + private mastodonService: MastodonService) { + + this.accounts$ = this.store.select(state => state.registeredaccounts.accounts); + } + + ngOnInit() { + this.pollPerAccountId[this.provider.id] = Promise.resolve(this.poll); + + this.selectedAccount = this.provider; + + this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => { + this.checkStatus(accounts); + }); + } + + private checkStatus(accounts: AccountInfo[]): void { + this.pollLocked = false; + var newSelectedAccount = accounts.find(x => x.isSelected); + + const accountChanged = this.selectedAccount.id !== newSelectedAccount.id; + if (accountChanged && !this.pollPerAccountId[newSelectedAccount.id] && this.status.visibility === 'public') { + this.setStatsAtZero(); + + this.pollPerAccountId[newSelectedAccount.id] = this.toolsService.getStatusUsableByAccount(newSelectedAccount, new StatusWrapper(this.status, this.provider)) + .then((status: Status) => { + console.warn(status); + return this.mastodonService.getPoll(newSelectedAccount, status.poll.id); + }) + .then((poll: Poll) => { + this.poll = poll; + return poll; + }) + .catch(err => { + this.notificationService.notifyHttpError(err); + return null; + }); + } else if (this.status.visibility !== 'public') { + this.pollLocked = true; + } else { + this.pollPerAccountId[newSelectedAccount.id] + .then((poll: Poll) => { + this.poll = poll; + }) + .catch(err => this.notificationService.notifyHttpError(err)); + } + this.selectedAccount = newSelectedAccount; + } + vote(): boolean { - this.mastodonService.voteOnPoll(this.provider, this.poll.id, this.pollSelection) + const selectedAccount = this.selectedAccount; + const pollPromise = this.pollPerAccountId[selectedAccount.id]; + + pollPromise + .then((poll: Poll) => { + return this.mastodonService.voteOnPoll(selectedAccount, poll.id, this.pollSelection); + }) .then((poll: Poll) => { this.poll = poll; - this.loadPoll(); + this.pollPerAccountId[selectedAccount.id] = Promise.resolve(poll); }) - .catch(err => { - this.notificationService.notifyHttpError(err); - }); + .catch(err => this.notificationService.notifyHttpError(err)); return false; } - refresh(): boolean { + private setStatsAtZero() { this.options.forEach(p => { p.votes_count = 0; p.percentage = '0'; }); + } - this.mastodonService.getPoll(this.provider, this.poll.id) + refresh(): boolean { + this.setStatsAtZero(); + + const selectedAccount = this.selectedAccount; + const pollPromise = this.pollPerAccountId[selectedAccount.id]; + + pollPromise + .then((poll: Poll) => { + return this.mastodonService.getPoll(selectedAccount, poll.id); + }) .then((poll: Poll) => { this.poll = poll; - this.loadPoll(); + this.pollPerAccountId[selectedAccount.id] = Promise.resolve(poll); }) - .catch(err => { - this.notificationService.notifyHttpError(err); - }); + .catch(err => this.notificationService.notifyHttpError(err)); return false; } diff --git a/src/app/components/stream/status/status.component.html b/src/app/components/stream/status/status.component.html index f3ac3722..2beab721 100644 --- a/src/app/components/stream/status/status.component.html +++ b/src/app/components/stream/status/status.component.html @@ -68,7 +68,7 @@ (textSelected)="textSelected()"> + [poll]="displayedStatus.poll" [status]="displayedStatus" [provider]="statusWrapper.provider"> From 803913ccf09b5ad98544d32bdf9bbe4a9cbfc680 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Tue, 11 Jun 2019 23:49:54 -0400 Subject: [PATCH 13/17] added lock icon #93 --- .../components/stream/status/poll/poll.component.html | 9 +++++---- .../components/stream/status/poll/poll.component.scss | 6 ++++++ src/app/components/stream/status/poll/poll.component.ts | 6 ++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.html b/src/app/components/stream/status/poll/poll.component.html index e61e3f7e..33a3192b 100644 --- a/src/app/components/stream/status/poll/poll.component.html +++ b/src/app/components/stream/status/poll/poll.component.html @@ -4,8 +4,9 @@ @@ -20,9 +21,9 @@
- - refresh -
·{{poll.votes_count}} votes· {{ poll.expires_at | timeLeft | async }}
+ refresh +
·{{poll.votes_count}} votes· {{ poll.expires_at | timeLeft | async }}
\ No newline at end of file diff --git a/src/app/components/stream/status/poll/poll.component.scss b/src/app/components/stream/status/poll/poll.component.scss index 76cc74ca..cc3a19eb 100644 --- a/src/app/components/stream/status/poll/poll.component.scss +++ b/src/app/components/stream/status/poll/poll.component.scss @@ -60,6 +60,12 @@ width: 0; } + &__lock { + position: absolute; + top: 0; + left: 0; + } + &__checkmark--box { position: absolute; top: 0; diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index 666ed659..e9d8077c 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit, Input } from '@angular/core'; import { Store } from '@ngxs/store'; import { Observable, Subscription } from 'rxjs'; +import { faLock } from "@fortawesome/free-solid-svg-icons"; import { Poll, PollOption, Status } from '../../../../services/models/mastodon.interfaces'; import { AccountInfo } from '../../../../states/accounts.state'; @@ -15,6 +16,8 @@ import { StatusWrapper } from '../../../../models/common.model'; styleUrls: ['./poll.component.scss'] }) export class PollComponent implements OnInit { + faLock = faLock; + pollName: string; choiceType: string; pollLocked: boolean; @@ -87,7 +90,6 @@ export class PollComponent implements OnInit { this.pollPerAccountId[newSelectedAccount.id] = this.toolsService.getStatusUsableByAccount(newSelectedAccount, new StatusWrapper(this.status, this.provider)) .then((status: Status) => { - console.warn(status); return this.mastodonService.getPoll(newSelectedAccount, status.poll.id); }) .then((poll: Poll) => { @@ -98,7 +100,7 @@ export class PollComponent implements OnInit { this.notificationService.notifyHttpError(err); return null; }); - } else if (this.status.visibility !== 'public') { + } else if (this.status.visibility !== 'public' && this.provider.id !== newSelectedAccount.id) { this.pollLocked = true; } else { this.pollPerAccountId[newSelectedAccount.id] From ba4fa61667dc63bc4f38cd6488546fafd171ef11 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Wed, 12 Jun 2019 00:10:57 -0400 Subject: [PATCH 14/17] fix visibility --- src/app/components/stream/status/poll/poll.component.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/components/stream/status/poll/poll.component.ts b/src/app/components/stream/status/poll/poll.component.ts index e9d8077c..198ef283 100644 --- a/src/app/components/stream/status/poll/poll.component.ts +++ b/src/app/components/stream/status/poll/poll.component.ts @@ -72,7 +72,6 @@ export class PollComponent implements OnInit { ngOnInit() { this.pollPerAccountId[this.provider.id] = Promise.resolve(this.poll); - this.selectedAccount = this.provider; this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => { @@ -85,7 +84,7 @@ export class PollComponent implements OnInit { var newSelectedAccount = accounts.find(x => x.isSelected); const accountChanged = this.selectedAccount.id !== newSelectedAccount.id; - if (accountChanged && !this.pollPerAccountId[newSelectedAccount.id] && this.status.visibility === 'public') { + if (accountChanged && !this.pollPerAccountId[newSelectedAccount.id] && (this.status.visibility === 'public' || this.status.visibility === 'unlisted')) { this.setStatsAtZero(); this.pollPerAccountId[newSelectedAccount.id] = this.toolsService.getStatusUsableByAccount(newSelectedAccount, new StatusWrapper(this.status, this.provider)) @@ -100,7 +99,7 @@ export class PollComponent implements OnInit { this.notificationService.notifyHttpError(err); return null; }); - } else if (this.status.visibility !== 'public' && this.provider.id !== newSelectedAccount.id) { + } else if (this.status.visibility !== 'public' && this.status.visibility !== 'unlisted' && this.provider.id !== newSelectedAccount.id) { this.pollLocked = true; } else { this.pollPerAccountId[newSelectedAccount.id] From 83258ed553d74090c273ce4548c50a5d5e28781a Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Thu, 13 Jun 2019 20:57:05 -0400 Subject: [PATCH 15/17] added poll support in notifications --- .../notifications/notifications.component.ts | 3 ++- src/app/components/stream/status/status.component.html | 8 ++++++++ src/app/components/stream/status/status.component.ts | 3 ++- src/app/services/models/mastodon.interfaces.ts | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/app/components/floating-column/manage-account/notifications/notifications.component.ts b/src/app/components/floating-column/manage-account/notifications/notifications.component.ts index ad26f8ec..55212886 100644 --- a/src/app/components/floating-column/manage-account/notifications/notifications.component.ts +++ b/src/app/components/floating-column/manage-account/notifications/notifications.component.ts @@ -154,6 +154,7 @@ class NotificationWrapper { case 'mention': case 'reblog': case 'favourite': + case 'poll': this.status= new StatusWrapper(notification.status, provider); break; } @@ -164,5 +165,5 @@ class NotificationWrapper { wrapperId: string; account: Account; status: StatusWrapper; - type: 'mention' | 'reblog' | 'favourite' | 'follow'; + type: 'mention' | 'reblog' | 'favourite' | 'follow' | 'poll'; } \ No newline at end of file diff --git a/src/app/components/stream/status/status.component.html b/src/app/components/stream/status/status.component.html index 2beab721..683a9df0 100644 --- a/src/app/components/stream/status/status.component.html +++ b/src/app/components/stream/status/status.component.html @@ -21,6 +21,14 @@ innerHTML="{{ notificationAccount | accountEmoji }}"> boosted your status +
+
+ +
+
+ A poll you have voted in has ended +
+