This commit is contained in:
Nicolas Constant 2019-03-23 17:43:59 -04:00
parent 76955704e7
commit 38ce9697f0
No known key found for this signature in database
GPG Key ID: 1E9F677FB01A5688
2 changed files with 106 additions and 18 deletions

View File

@ -1,11 +1,12 @@
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import { Component, OnInit, Output, EventEmitter, Input, ViewChild, ElementRef } from '@angular/core';
import { StatusWrapper } from '../../../../models/common.model';
import { OpenThreadEvent } from '../../../../services/tools.service';
import { AccountWrapper } from '../../../../models/account.models';
import { MastodonService } from '../../../../services/mastodon.service';
import { MastodonService, FavoriteResult } from '../../../../services/mastodon.service';
import { Status } from '../../../../services/models/mastodon.interfaces';
import { NotificationService } from '../../../../services/notification.service';
import { resetCompiledComponents } from '@angular/core/src/render3/jit/module';
@Component({
selector: 'app-favorites',
@ -15,7 +16,7 @@ import { NotificationService } from '../../../../services/notification.service';
export class FavoritesComponent implements OnInit {
statuses: StatusWrapper[] = [];
displayError: string;
isLoading = true;
isLoading = true;
isThread = false;
hasContentWarnings = false;
@ -23,24 +24,43 @@ export class FavoritesComponent implements OnInit {
@Output() browseHashtagEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
@Input() account: AccountWrapper;
private maxReached = false;
private maxId: string;
private _account: AccountWrapper;
@Input('account')
set account(acc: AccountWrapper) {
console.warn('account');
this._account = acc;
this.getFavorites();
}
get account(): AccountWrapper {
return this._account;
}
@ViewChild('statusstream') public statustream: ElementRef;
constructor(
private readonly notificationService: NotificationService,
private readonly mastodonService: MastodonService) { }
ngOnInit() {
this.getFavorites();
}
private getFavorites(){
private reset(){
this.isLoading = true;
this.statuses.length = 0;
this.maxReached = false;
this.maxId = null;
}
private getFavorites() {
this.reset();
this.mastodonService.getFavorites(this.account.info)
.then((statuses: Status[]) => {
for (const s of statuses) {
.then((result: FavoriteResult) => {
this.maxId = result.max_id;
for (const s of result.favorites) {
const wrapper = new StatusWrapper(s, this.account.info);
this.statuses.push(wrapper);
}
@ -54,4 +74,51 @@ export class FavoritesComponent implements OnInit {
}
onScroll() {
var element = this.statustream.nativeElement as HTMLElement;
const atBottom = element.scrollHeight <= element.clientHeight + element.scrollTop + 1000;
if (atBottom) {
this.scrolledToBottom();
}
}
private scrolledToBottom() {
if (this.isLoading || this.maxReached) return;
this.isLoading = true;
this.mastodonService.getFavorites(this.account.info, this.maxId)
.then((result: FavoriteResult) => {
const statuses = result.favorites;
if (statuses.length === 0 || !this.maxId) {
this.maxReached = true;
return;
}
this.maxId = result.max_id;
for (const s of statuses) {
const wrapper = new StatusWrapper(s, this.account.info);
this.statuses.push(wrapper);
}
})
.catch(err => {
this.notificationService.notifyHttpError(err);
})
.then(() => {
this.isLoading = false;
});
}
browseAccount(accountName: string): void {
this.browseAccountEvent.next(accountName);
}
browseHashtag(hashtag: string): void {
this.browseHashtagEvent.next(hashtag);
}
browseThread(openThreadEvent: OpenThreadEvent): void {
this.browseThreadEvent.next(openThreadEvent);
}
}

View File

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { HttpHeaders, HttpClient } from '@angular/common/http';
import { HttpHeaders, HttpClient, HttpResponse } from '@angular/common/http';
import { ApiRoutes } from './models/api.settings';
import { Account, Status, Results, Context, Relationship, Instance, Attachment } from "./models/mastodon.interfaces";
@ -7,7 +7,7 @@ import { AccountInfo } from '../states/accounts.state';
import { StreamTypeEnum } from '../states/streams.state';
@Injectable()
export class MastodonService {
export class MastodonService {
private apiRoutes = new ApiRoutes();
constructor(private readonly httpClient: HttpClient) { }
@ -133,12 +133,27 @@ export class MastodonService {
const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` });
return this.httpClient.get<Context>(route, { headers: headers }).toPromise();
}
getFavorites(account: AccountInfo): Promise<Status[]> {
const route = `https://${account.instance}${this.apiRoutes.getFavourites}`;
getFavorites(account: AccountInfo, maxId: string = null): Promise<FavoriteResult> { //, minId: string = null
let route = `https://${account.instance}${this.apiRoutes.getFavourites}`; //?limit=${limit}
if (maxId) route += `?max_id=${maxId}`;
//if (minId) route += `&min_id=${minId}`;
const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` });
return this.httpClient.get<Status[]>(route, { headers: headers }).toPromise();
}
return this.httpClient.get(route, { headers: headers, observe: "response" }).toPromise()
.then((res: HttpResponse<Status[]>) => {
const link = res.headers.get('Link');
let lastId = null;
if(link){
const maxId = link.split('max_id=')[1];
if(maxId){
lastId = maxId.split('>;')[0];
}
}
return new FavoriteResult(lastId, res.body);
});
}
searchAccount(account: AccountInfo, query: string, limit: number = 40, following: boolean = false): Promise<Account[]> {
const route = `https://${account.instance}${this.apiRoutes.searchForAccounts}?q=${query}&limit=${limit}&following=${following}`;
@ -168,7 +183,7 @@ export class MastodonService {
const route = `https://${account.instance}${this.apiRoutes.unfavouritingStatus}`.replace('{0}', status.id);
const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` });
return this.httpClient.post<Status>(route, null, { headers: headers }).toPromise()
}
}
getRelationships(account: AccountInfo, accountsToRetrieve: Account[]): Promise<Relationship[]> {
let params = `?${this.formatArray(accountsToRetrieve.map(x => x.id.toString()), 'id')}`;
@ -206,7 +221,7 @@ export class MastodonService {
}
//TODO: add focus support
updateMediaAttachment(account: AccountInfo, mediaId: string, description: string): Promise<Attachment> {
updateMediaAttachment(account: AccountInfo, mediaId: string, description: string): Promise<Attachment> {
let input = new FormData();
input.append('description', description);
const route = `https://${account.instance}${this.apiRoutes.updateMediaAttachment.replace('{0}', mediaId)}`;
@ -239,4 +254,10 @@ class StatusData {
sensitive: boolean;
spoiler_text: string;
visibility: string;
}
export class FavoriteResult {
constructor(
public max_id: string,
public favorites: Status[]) {}
}