display lists and add/remove them #46

This commit is contained in:
Nicolas Constant 2019-05-18 20:44:36 -04:00
parent 1055fe6117
commit 62baf8474d
No known key found for this signature in database
GPG Key ID: 1E9F677FB01A5688
11 changed files with 82 additions and 24 deletions

View File

@ -29,7 +29,6 @@ export class DirectMessagesComponent implements OnInit {
@Input('account')
set account(acc: AccountWrapper) {
console.warn('account');
this._account = acc;
this.getDirectMessages();
}

View File

@ -1,9 +1,20 @@
<div class="my-account__body flexcroll">
<h4 class="my-account__label">add column:</h4>
<a class="my-account__link my-account__blue" href *ngFor="let stream of availableStreams"
(click)="addStream(stream)" title="{{ stream.isAdded ? '' : 'add timeline'}}" [class.my-account__link--disabled]="stream.isAdded">
{{ stream.name }} <fa-icon class="my-account__link--icon" *ngIf="stream.isAdded" [icon]="faCheckSquare"></fa-icon>
<h4 class="my-account__label">add timeline:</h4>
<a class="my-account__link my-account__blue" href *ngFor="let stream of availableStreams"
(click)="addStream(stream)" title="{{ stream.isAdded ? '' : 'add timeline'}}"
[class.my-account__link--disabled]="stream.isAdded">
{{ stream.name }} <fa-icon class="my-account__link--icon" *ngIf="stream.isAdded" [icon]="faCheckSquare">
</fa-icon>
</a>
<h4 class="my-account__label">add list:</h4>
<a class="my-account__link my-account__blue" href *ngFor="let list of availableLists"
(click)="addStream(list)" title="{{ list.isAdded ? '' : 'add list'}}"
[class.my-account__link--disabled]="list.isAdded">
{{ list.name }} <fa-icon class="my-account__link--icon" *ngIf="list.isAdded" [icon]="faCheckSquare">
</fa-icon>
</a>
<h4 class="my-account__label my-account__margin-top">remove account from sengi:</h4>
<a class="my-account__link my-account__red" href (click)="removeAccount()">
Delete

View File

@ -8,6 +8,7 @@ import { StreamElement, StreamTypeEnum, AddStream, RemoveAllStreams } from '../.
import { AccountWrapper } from '../../../../models/account.models';
import { RemoveAccount } from '../../../../states/accounts.state';
import { NavigationService } from '../../../../services/navigation.service';
import { MastodonService } from '../../../../services/mastodon.service';
@Component({
selector: 'app-my-account',
@ -19,6 +20,7 @@ export class MyAccountComponent implements OnInit, OnDestroy {
faCheckSquare = faCheckSquare;
availableStreams: StreamWrapper[] = [];
availableLists: StreamWrapper[] = [];
private _account: AccountWrapper;
@Input('account')
@ -36,7 +38,8 @@ export class MyAccountComponent implements OnInit, OnDestroy {
constructor(
private readonly store: Store,
private readonly navigationService: NavigationService,
private notificationService: NotificationService) { }
private readonly mastodonService: MastodonService,
private readonly notificationService: NotificationService) { }
ngOnInit() {
this.streamChangedSub = this.streamElements$.subscribe((streams: StreamElement[]) => {
@ -53,9 +56,9 @@ export class MyAccountComponent implements OnInit, OnDestroy {
private loadStreams(account: AccountWrapper){
const instance = account.info.instance;
this.availableStreams.length = 0;
this.availableStreams.push(new StreamWrapper(new StreamElement(StreamTypeEnum.global, 'Federated Timeline', account.info.id, null, null, instance)));
this.availableStreams.push(new StreamWrapper(new StreamElement(StreamTypeEnum.local, 'Local Timeline', account.info.id, null, null, instance)));
this.availableStreams.push(new StreamWrapper(new StreamElement(StreamTypeEnum.personnal, 'Home', account.info.id, null, null, instance)));
this.availableStreams.push(new StreamWrapper(new StreamElement(StreamTypeEnum.global, 'Federated Timeline', account.info.id, null, null, null, instance)));
this.availableStreams.push(new StreamWrapper(new StreamElement(StreamTypeEnum.local, 'Local Timeline', account.info.id, null, null, null, instance)));
this.availableStreams.push(new StreamWrapper(new StreamElement(StreamTypeEnum.personnal, 'Home', account.info.id, null, null, null, instance)));
const loadedStreams = <StreamElement[]>this.store.snapshot().streamsstatemodel.streams;
this.availableStreams.forEach(s => {
@ -65,6 +68,24 @@ export class MyAccountComponent implements OnInit, OnDestroy {
s.isAdded = false;
}
});
this.availableLists.length = 0;
this.mastodonService.getLists(account.info)
.then((streams: StreamElement[]) => {
this.availableLists.length = 0;
for (let stream of streams) {
let wrappedStream = new StreamWrapper(stream);
if(loadedStreams.find(x => x.id == stream.id)){
wrappedStream.isAdded = true;
} else {
wrappedStream.isAdded = false;
}
this.availableLists.push(wrappedStream);
}
})
.catch(err => {
});
}
addStream(stream: StreamWrapper): boolean {
@ -72,7 +93,6 @@ export class MyAccountComponent implements OnInit, OnDestroy {
this.store.dispatch([new AddStream(stream)]).toPromise()
.then(() => {
stream.isAdded = true;
//this.notificationService.notify(`stream added`, false);
});
}
return false;
@ -88,7 +108,7 @@ export class MyAccountComponent implements OnInit, OnDestroy {
class StreamWrapper extends StreamElement {
constructor(stream: StreamElement) {
super(stream.type, stream.name, stream.accountId, stream.tag, stream.list, stream.instance);
super(stream.type, stream.name, stream.accountId, stream.tag, stream.list, stream.listId, stream.instance);
}
isAdded: boolean;

View File

@ -50,7 +50,7 @@ export class HashtagComponent implements OnInit {
event.stopPropagation();
const hashtag = this.hashtagElement.tag;
const newStream = new StreamElement(StreamTypeEnum.tag, `${hashtag}`, this.lastUsedAccount.id, hashtag, null, this.lastUsedAccount.instance);
const newStream = new StreamElement(StreamTypeEnum.tag, `${hashtag}`, this.lastUsedAccount.id, hashtag, null, null, this.lastUsedAccount.instance);
this.store.dispatch([new AddStream(newStream)]);
return false;

View File

@ -156,7 +156,7 @@ export class StreamOverlayComponent implements OnInit, OnDestroy {
}
const selectedAccount = this.toolsService.getSelectedAccounts()[0];
const hashTagElement = new StreamElement(StreamTypeEnum.tag, hashtag, selectedAccount.id, hashtag, null, selectedAccount.instance);
const hashTagElement = new StreamElement(StreamTypeEnum.tag, hashtag, selectedAccount.id, hashtag, null, null, selectedAccount.instance);
const newElement = new OverlayBrowsing(hashTagElement, null, null);
this.loadElement(newElement);
// this.canGoForward = false;

View File

@ -187,7 +187,7 @@ export class StreamStatusesComponent implements OnInit, OnDestroy {
this.isProcessingInfiniteScroll = true;
const lastStatus = this.statuses[this.statuses.length - 1];
this.mastodonService.getTimeline(this.account, this._streamElement.type, lastStatus.status.id, null, this.streamingService.nbStatusPerIteration, this._streamElement.tag, this._streamElement.list)
this.mastodonService.getTimeline(this.account, this._streamElement.type, lastStatus.status.id, null, this.streamingService.nbStatusPerIteration, this._streamElement.tag, this._streamElement.listId)
.then((status: Status[]) => {
for (const s of status) {
const wrapper = new StatusWrapper(s, this.account);
@ -210,7 +210,7 @@ export class StreamStatusesComponent implements OnInit, OnDestroy {
private retrieveToots(): void {
this.mastodonService.getTimeline(this.account, this._streamElement.type, null, null, this.streamingService.nbStatusPerIteration, this._streamElement.tag, this._streamElement.list)
this.mastodonService.getTimeline(this.account, this._streamElement.type, null, null, this.streamingService.nbStatusPerIteration, this._streamElement.tag, this._streamElement.listId)
.then((results: Status[]) => {
this.isLoading = false;
for (const s of results) {

View File

@ -2,9 +2,9 @@ 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 } from "./models/mastodon.interfaces";
import { Account, Status, Results, Context, Relationship, Instance, Attachment, Notification, List } from "./models/mastodon.interfaces";
import { AccountInfo } from '../states/accounts.state';
import { StreamTypeEnum } from '../states/streams.state';
import { StreamTypeEnum, StreamElement } from '../states/streams.state';
@Injectable()
export class MastodonService {
@ -22,13 +22,13 @@ export class MastodonService {
return this.httpClient.get<Account>('https://' + account.instance + this.apiRoutes.getCurrentAccount, { headers: headers }).toPromise();
}
getTimeline(account: AccountInfo, type: StreamTypeEnum, max_id: string = null, since_id: string = null, limit: number = 20, tag: string = null, list: string = null): Promise<Status[]> {
const route = `https://${account.instance}${this.getTimelineRoute(type, max_id, since_id, limit, tag, list)}`;
getTimeline(account: AccountInfo, type: StreamTypeEnum, max_id: string = null, since_id: string = null, limit: number = 20, tag: string = null, listId: string = null): Promise<Status[]> {
const route = `https://${account.instance}${this.getTimelineRoute(type, max_id, since_id, limit, tag, listId)}`;
const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` });
return this.httpClient.get<Status[]>(route, { headers: headers }).toPromise();
}
private getTimelineRoute(type: StreamTypeEnum, max_id: string, since_id: string, limit: number, tag: string, list: string): string {
private getTimelineRoute(type: StreamTypeEnum, max_id: string, since_id: string, limit: number, tag: string, listId: string): string {
let route: string;
switch (type) {
case StreamTypeEnum.personnal:
@ -47,7 +47,7 @@ export class MastodonService {
route = this.apiRoutes.getTagTimeline.replace('{0}', tag);
break;
case StreamTypeEnum.list:
route = this.apiRoutes.getListTimeline.replace('{0}', list);
route = this.apiRoutes.getListTimeline.replace('{0}', listId);
break;
default:
throw new Error('StreamTypeEnum not supported');
@ -256,6 +256,20 @@ export class MastodonService {
result += `${paramName}[]=${x}`;
});
return result;
}
getLists(account: AccountInfo): Promise<StreamElement[]> {
let route = `https://${account.instance}${this.apiRoutes.getLists}`;
const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` });
return this.httpClient.get<List[]>(route, { headers: headers }).toPromise()
.then((lists: List[]) => {
const streams: StreamElement[] = [];
for (const list of lists) {
const stream = new StreamElement(StreamTypeEnum.list, list.title, account.id, null, list.title, list.id, account.instance);
streams.push(stream);
}
return streams;
});
}
}

View File

@ -50,4 +50,13 @@ export class ApiRoutes {
getTagTimeline = '/api/v1/timelines/tag/{0}';
getListTimeline = '/api/v1/timelines/list/{0}';
getStreaming = '/api/v1/streaming?access_token={0}&stream={1}';
getLists = '/api/v1/lists';
getList = '/api/v1/lists/{0}';
getListsWithAccount = '/api/v1/accounts/{0}/lists';
getAccountsInList = '/api/v1/lists/{0}/accounts';
postList = '/api/v1/lists';
putList = '/api/v1/lists/{0}';
deleteList = '/api/v1/lists/{0}';
addAccountToList = '/api/v1/lists/{0}/accounts';
removeAccountFromList = '/api/v1/lists/{0}/accounts';
}

View File

@ -188,3 +188,7 @@ export interface Tag {
url: string;
}
export interface List {
id: string;
title: string;
}

View File

@ -47,7 +47,7 @@ export class StreamingWrapper {
this.eventSource = new WebSocket(route);
this.eventSource.onmessage = x => this.statusParsing(<WebSocketEvent>JSON.parse(x.data));
this.eventSource.onerror = x => this.webSocketGotError(x);
this.eventSource.onopen = x => console.log(x);
this.eventSource.onopen = x => {};
this.eventSource.onclose = x => this.webSocketClosed(route, x);
}
@ -65,7 +65,7 @@ export class StreamingWrapper {
}
private pullNewStatuses(domain) {
this.mastodonService.getTimeline(this.account, this.stream.type, null, this.since_id, this.nbStatusPerIteration, this.stream.tag, this.stream.list)
this.mastodonService.getTimeline(this.account, this.stream.type, null, this.since_id, this.nbStatusPerIteration, this.stream.tag, this.stream.listId)
.then((status: Status[]) => {
// status = status.sort((n1, n2) => { return (<number>n1.id) < (<number>n2.id); });
status = status.sort((a, b) => a.id.localeCompare(b.id));
@ -112,7 +112,7 @@ export class StreamingWrapper {
let route = `wss://${account.instance}${this.apiRoutes.getStreaming}`.replace('{0}', account.token.access_token).replace('{1}', streamingRouteType);
if (stream.tag) route = `${route}&tag=${stream.tag}`;
if (stream.list) route = `${route}&tag=${stream.list}`;
if (stream.list) route = `${route}&list=${stream.listId}`;
return route;
}

View File

@ -98,6 +98,7 @@ export class StreamElement {
public accountId: string,
public tag: string,
public list: string,
public listId: string,
public instance: string) {
this.id = `${type}-${name}-${accountId}`;
}