238 lines
8.2 KiB
TypeScript
238 lines
8.2 KiB
TypeScript
import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
|
|
import { HttpErrorResponse } from '@angular/common/http';
|
|
import { faUser, faHourglassHalf, faUserCheck } from "@fortawesome/free-solid-svg-icons";
|
|
import { faUser as faUserRegular } from "@fortawesome/free-regular-svg-icons";
|
|
import { Observable, Subscription } from 'rxjs';
|
|
import { Store } from '@ngxs/store';
|
|
|
|
import { Account, Status, Relationship } from "../../../services/models/mastodon.interfaces";
|
|
import { MastodonService } from '../../../services/mastodon.service';
|
|
import { ToolsService, OpenThreadEvent } from '../../../services/tools.service';
|
|
import { NotificationService } from '../../../services/notification.service';
|
|
import { AccountInfo } from '../../../states/accounts.state';
|
|
import { StatusWrapper } from '../../../models/common.model';
|
|
|
|
|
|
|
|
@Component({
|
|
selector: 'app-user-profile',
|
|
templateUrl: './user-profile.component.html',
|
|
styleUrls: ['./user-profile.component.scss']
|
|
})
|
|
export class UserProfileComponent implements OnInit {
|
|
faUser = faUser;
|
|
faUserRegular = faUserRegular;
|
|
faHourglassHalf = faHourglassHalf;
|
|
faUserCheck = faUserCheck;
|
|
|
|
displayedAccount: Account;
|
|
hasNote: boolean;
|
|
|
|
isLoading: boolean;
|
|
|
|
private maxReached = false;
|
|
private maxId: string;
|
|
statusLoading: boolean;
|
|
error: string;
|
|
|
|
relationship: Relationship;
|
|
statuses: StatusWrapper[] = [];
|
|
|
|
private lastAccountName: string;
|
|
|
|
private currentlyUsedAccount: AccountInfo;
|
|
private accounts$: Observable<AccountInfo[]>;
|
|
private accountSub: Subscription;
|
|
|
|
@ViewChild('statusstream') public statustream: ElementRef;
|
|
|
|
@Output() browseAccountEvent = new EventEmitter<string>();
|
|
@Output() browseHashtagEvent = new EventEmitter<string>();
|
|
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
|
|
|
|
@Input('currentAccount')
|
|
set currentAccount(accountName: string) {
|
|
this.load(accountName);
|
|
}
|
|
|
|
constructor(
|
|
private readonly store: Store,
|
|
private readonly notificationService: NotificationService,
|
|
private readonly mastodonService: MastodonService,
|
|
private readonly toolsService: ToolsService) {
|
|
|
|
this.accounts$ = this.store.select(state => state.registeredaccounts.accounts);
|
|
}
|
|
|
|
ngOnInit() {
|
|
this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => {
|
|
if (this.displayedAccount) {
|
|
const userAccount = accounts.filter(x => x.isSelected)[0];
|
|
|
|
this.toolsService.findAccount(userAccount, this.lastAccountName)
|
|
.then((account: Account) => {
|
|
this.getFollowStatus(userAccount, account);
|
|
})
|
|
.catch((err: HttpErrorResponse) => {
|
|
this.notificationService.notifyHttpError(err);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
ngOnDestroy() {
|
|
this.accountSub.unsubscribe();
|
|
}
|
|
|
|
private load(accountName: string) {
|
|
this.statuses.length = 0;
|
|
|
|
this.displayedAccount = null;
|
|
this.isLoading = true;
|
|
|
|
this.lastAccountName = accountName;
|
|
this.currentlyUsedAccount = this.toolsService.getSelectedAccounts()[0];
|
|
|
|
return this.toolsService.findAccount(this.currentlyUsedAccount, this.lastAccountName)
|
|
.then((account: Account) => {
|
|
this.isLoading = false;
|
|
this.statusLoading = true;
|
|
|
|
this.displayedAccount = account;
|
|
this.hasNote = account && account.note && account.note !== '<p></p>';
|
|
|
|
const getFollowStatusPromise = this.getFollowStatus(this.currentlyUsedAccount, this.displayedAccount);
|
|
const getStatusesPromise = this.getStatuses(this.currentlyUsedAccount, this.displayedAccount);
|
|
|
|
return Promise.all([getFollowStatusPromise, getStatusesPromise]);
|
|
})
|
|
.catch((err: HttpErrorResponse) => {
|
|
this.notificationService.notifyHttpError(err);
|
|
})
|
|
.then(() => {
|
|
this.isLoading = false;
|
|
this.statusLoading = false;
|
|
});
|
|
}
|
|
|
|
private getStatuses(userAccount: AccountInfo, account: Account): Promise<void> {
|
|
this.statusLoading = true;
|
|
return this.mastodonService.getAccountStatuses(userAccount, account.id, false, false, true, null, null, 40)
|
|
.then((statuses: Status[]) => {
|
|
this.loadStatus(userAccount, statuses);
|
|
|
|
// if (statuses.length === 0) {
|
|
// this.maxReached = true;
|
|
// return;
|
|
// }
|
|
|
|
// for (const status of statuses) {
|
|
// const wrapper = new StatusWrapper(status, userAccount);
|
|
// this.statuses.push(wrapper);
|
|
// }
|
|
|
|
// this.maxId = this.statuses[this.statuses.length - 1].status.id;
|
|
})
|
|
.catch(err => {
|
|
this.notificationService.notifyHttpError(err);
|
|
})
|
|
.then(() => {
|
|
this.statusLoading = false;
|
|
});
|
|
}
|
|
|
|
private getFollowStatus(userAccount: AccountInfo, account: Account): Promise<void> {
|
|
// this.relationship = null;
|
|
return this.mastodonService.getRelationships(userAccount, [account])
|
|
.then((result: Relationship[]) => {
|
|
this.relationship = result.filter(x => x.id === account.id)[0];
|
|
});
|
|
}
|
|
|
|
refresh(): any {
|
|
this.load(this.lastAccountName);
|
|
}
|
|
|
|
browseAccount(accountName: string): void {
|
|
this.browseAccountEvent.next(accountName);
|
|
}
|
|
|
|
browseHashtag(hashtag: string): void {
|
|
this.browseHashtagEvent.next(hashtag);
|
|
}
|
|
|
|
browseThread(openThreadEvent: OpenThreadEvent): void {
|
|
this.browseThreadEvent.next(openThreadEvent);
|
|
}
|
|
|
|
follow(): boolean {
|
|
const userAccount = this.toolsService.getSelectedAccounts()[0];
|
|
this.toolsService.findAccount(userAccount, this.lastAccountName)
|
|
.then((account: Account) => {
|
|
return this.mastodonService.follow(userAccount, account);
|
|
})
|
|
.then((relationship: Relationship) => {
|
|
this.relationship = relationship;
|
|
})
|
|
.catch((err: HttpErrorResponse) => {
|
|
this.notificationService.notifyHttpError(err);
|
|
});
|
|
return false;
|
|
}
|
|
|
|
unfollow(): boolean {
|
|
const userAccount = this.toolsService.getSelectedAccounts()[0];
|
|
this.toolsService.findAccount(userAccount, this.lastAccountName)
|
|
.then((account: Account) => {
|
|
return this.mastodonService.unfollow(userAccount, account);
|
|
})
|
|
.then((relationship: Relationship) => {
|
|
this.relationship = relationship;
|
|
})
|
|
.catch((err: HttpErrorResponse) => {
|
|
this.notificationService.notifyHttpError(err);
|
|
});
|
|
return false;
|
|
}
|
|
|
|
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.statusLoading || this.maxReached) return;
|
|
|
|
this.statusLoading = true;
|
|
const userAccount = this.currentlyUsedAccount;
|
|
this.mastodonService.getAccountStatuses(userAccount, this.displayedAccount.id, false, false, true, this.maxId, null, 40)
|
|
.then((statuses: Status[]) => {
|
|
this.loadStatus(userAccount, statuses);
|
|
})
|
|
.catch(err => {
|
|
this.notificationService.notifyHttpError(err);
|
|
})
|
|
.then(() => {
|
|
this.statusLoading = false;
|
|
});
|
|
}
|
|
|
|
private loadStatus(userAccount: AccountInfo, statuses: Status[]){
|
|
if (statuses.length === 0) {
|
|
this.maxReached = true;
|
|
return;
|
|
}
|
|
|
|
for (const status of statuses) {
|
|
const wrapper = new StatusWrapper(status, userAccount);
|
|
this.statuses.push(wrapper);
|
|
}
|
|
|
|
this.maxId = this.statuses[this.statuses.length - 1].status.id;
|
|
}
|
|
}
|