This commit is contained in:
Nicolas Constant 2019-04-07 14:47:09 -04:00
parent 8559d170f9
commit d26490be62
No known key found for this signature in database
GPG Key ID: 1E9F677FB01A5688
2 changed files with 92 additions and 34 deletions

View File

@ -1,13 +1,12 @@
<div class="profile flexcroll"> <div class="profile flexcroll" #statusstream (scroll)="onScroll()">
<app-waiting-animation *ngIf="isLoading" class="waiting-icon"></app-waiting-animation> <app-waiting-animation *ngIf="isLoading" class="waiting-icon"></app-waiting-animation>
<div *ngIf="account" class="profile-header" [ngStyle]="{'background-image':'url('+account.header+')'}"> <div *ngIf="displayedAccount" class="profile-header" [ngStyle]="{'background-image':'url('+displayedAccount.header+')'}">
<div class="profile-header__inner"> <div class="profile-header__inner">
<!-- <img class="profile-header__header" src="{{account.header}}" alt="header" /> --> <img class="profile-header__avatar" src="{{displayedAccount.avatar}}" alt="header" />
<img class="profile-header__avatar" src="{{account.avatar}}" alt="header" /> <h2 class="profile-header__display-name">{{displayedAccount.display_name}}</h2>
<h2 class="profile-header__display-name">{{account.display_name}}</h2> <h2 class="profile-header__fullhandle"><a href="{{displayedAccount.url}}" target="_blank">@{{displayedAccount.acct}}</a></h2>
<h2 class="profile-header__fullhandle"><a href="{{account.url}}" target="_blank">@{{account.acct}}</a></h2>
<div class="profile-header__follow" *ngIf="relationship"> <div class="profile-header__follow" *ngIf="relationship">
<button class="profile-header__follow--button profile-header__follow--unfollowed" title="follow" <button class="profile-header__follow--button profile-header__follow--unfollowed" title="follow"
@ -32,14 +31,13 @@
</div> </div>
</div> </div>
<div class="profile-sub-header "> <div class="profile-sub-header ">
<div *ngIf="account && hasNote" class="profile-description"> <div *ngIf="displayedAccount && hasNote" class="profile-description">
<!-- <div *ngIf="account && account.note" class="profile-description"> --> <app-databinded-text class="profile-description__content" [textIsSelectable]="false" [text]="displayedAccount.note"
<app-databinded-text class="profile-description__content" [textIsSelectable]="false" [text]="account.note"
(accountSelected)="browseAccount($event)" (hashtagSelected)="browseHashtag($event)"> (accountSelected)="browseAccount($event)" (hashtagSelected)="browseHashtag($event)">
</app-databinded-text> </app-databinded-text>
</div> </div>
<div class="profile-fields" *ngIf="account && account.fields.length > 0"> <div class="profile-fields" *ngIf="displayedAccount && displayedAccount.fields.length > 0">
<div class="profile-fields__field" *ngFor="let field of account.fields"> <div class="profile-fields__field" *ngFor="let field of displayedAccount.fields">
<div class="profile-fields__field--value" innerHTML="{{field.value}}" [ngClass]="{'profile-fields__field--validated': field.verified_at }"> <div class="profile-fields__field--value" innerHTML="{{field.value}}" [ngClass]="{'profile-fields__field--validated': field.verified_at }">
</div> </div>
<div class="profile-fields__field--name"> <div class="profile-fields__field--name">
@ -49,8 +47,6 @@
</div> </div>
<div class="profile-statuses"> <div class="profile-statuses">
<app-waiting-animation *ngIf="statusLoading" class="waiting-icon"></app-waiting-animation>
<div *ngIf="!isLoading && !statusLoading && statuses.length == 0" class="profile-no-toots"> <div *ngIf="!isLoading && !statusLoading && statuses.length == 0" class="profile-no-toots">
no toots found no toots found
</div> </div>
@ -60,6 +56,9 @@
(browseAccountEvent)="browseAccount($event)" (browseThreadEvent)="browseThread($event)"> (browseAccountEvent)="browseAccount($event)" (browseThreadEvent)="browseThread($event)">
</app-status> </app-status>
</div> </div>
<app-waiting-animation *ngIf="statusLoading" class="waiting-icon"></app-waiting-animation>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { faUser, faHourglassHalf, faUserCheck } from "@fortawesome/free-solid-svg-icons"; import { faUser, faHourglassHalf, faUserCheck } from "@fortawesome/free-solid-svg-icons";
import { faUser as faUserRegular } from "@fortawesome/free-regular-svg-icons"; import { faUser as faUserRegular } from "@fortawesome/free-regular-svg-icons";
@ -25,10 +25,13 @@ export class UserProfileComponent implements OnInit {
faHourglassHalf = faHourglassHalf; faHourglassHalf = faHourglassHalf;
faUserCheck = faUserCheck; faUserCheck = faUserCheck;
account: Account; displayedAccount: Account;
hasNote: boolean; hasNote: boolean;
isLoading: boolean; isLoading: boolean;
private maxReached = false;
private maxId: string;
statusLoading: boolean; statusLoading: boolean;
error: string; error: string;
@ -41,6 +44,8 @@ export class UserProfileComponent implements OnInit {
private accounts$: Observable<AccountInfo[]>; private accounts$: Observable<AccountInfo[]>;
private accountSub: Subscription; private accountSub: Subscription;
@ViewChild('statusstream') public statustream: ElementRef;
@Output() browseAccountEvent = new EventEmitter<string>(); @Output() browseAccountEvent = new EventEmitter<string>();
@Output() browseHashtagEvent = new EventEmitter<string>(); @Output() browseHashtagEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>(); @Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
@ -61,12 +66,12 @@ export class UserProfileComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => { this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => {
if (this.account) { if (this.displayedAccount) {
this.currentlyUsedAccount = accounts.filter(x => x.isSelected)[0]; const userAccount = accounts.filter(x => x.isSelected)[0];
this.toolsService.findAccount(this.currentlyUsedAccount, this.lastAccountName) this.toolsService.findAccount(userAccount, this.lastAccountName)
.then((account: Account) => { .then((account: Account) => {
this.getFollowStatus(this.currentlyUsedAccount, account); this.getFollowStatus(userAccount, account);
}) })
.catch((err: HttpErrorResponse) => { .catch((err: HttpErrorResponse) => {
this.notificationService.notifyHttpError(err); this.notificationService.notifyHttpError(err);
@ -82,7 +87,7 @@ export class UserProfileComponent implements OnInit {
private load(accountName: string) { private load(accountName: string) {
this.statuses.length = 0; this.statuses.length = 0;
this.account = null; this.displayedAccount = null;
this.isLoading = true; this.isLoading = true;
this.lastAccountName = accountName; this.lastAccountName = accountName;
@ -93,11 +98,11 @@ export class UserProfileComponent implements OnInit {
this.isLoading = false; this.isLoading = false;
this.statusLoading = true; this.statusLoading = true;
this.account = account; this.displayedAccount = account;
this.hasNote = account && account.note && account.note !== '<p></p>'; this.hasNote = account && account.note && account.note !== '<p></p>';
const getFollowStatusPromise = this.getFollowStatus(this.currentlyUsedAccount, this.account); const getFollowStatusPromise = this.getFollowStatus(this.currentlyUsedAccount, this.displayedAccount);
const getStatusesPromise = this.getStatuses(this.currentlyUsedAccount, this.account); const getStatusesPromise = this.getStatuses(this.currentlyUsedAccount, this.displayedAccount);
return Promise.all([getFollowStatusPromise, getStatusesPromise]); return Promise.all([getFollowStatusPromise, getStatusesPromise]);
}) })
@ -113,11 +118,25 @@ export class UserProfileComponent implements OnInit {
private getStatuses(userAccount: AccountInfo, account: Account): Promise<void> { private getStatuses(userAccount: AccountInfo, account: Account): Promise<void> {
this.statusLoading = true; this.statusLoading = true;
return this.mastodonService.getAccountStatuses(userAccount, account.id, false, false, true, null, null, 40) return this.mastodonService.getAccountStatuses(userAccount, account.id, false, false, true, null, null, 40)
.then((result: Status[]) => { .then((statuses: Status[]) => {
for (const status of result) { this.loadStatus(userAccount, statuses);
const wrapper = new StatusWrapper(status, userAccount);
this.statuses.push(wrapper); // 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; this.statusLoading = false;
}); });
} }
@ -147,10 +166,10 @@ export class UserProfileComponent implements OnInit {
} }
follow(): boolean { follow(): boolean {
this.currentlyUsedAccount = this.toolsService.getSelectedAccounts()[0]; const userAccount = this.toolsService.getSelectedAccounts()[0];
this.toolsService.findAccount(this.currentlyUsedAccount, this.lastAccountName) this.toolsService.findAccount(userAccount, this.lastAccountName)
.then((account: Account) => { .then((account: Account) => {
return this.mastodonService.follow(this.currentlyUsedAccount, account); return this.mastodonService.follow(userAccount, account);
}) })
.then((relationship: Relationship) => { .then((relationship: Relationship) => {
this.relationship = relationship; this.relationship = relationship;
@ -162,10 +181,10 @@ export class UserProfileComponent implements OnInit {
} }
unfollow(): boolean { unfollow(): boolean {
this.currentlyUsedAccount = this.toolsService.getSelectedAccounts()[0]; const userAccount = this.toolsService.getSelectedAccounts()[0];
this.toolsService.findAccount(this.currentlyUsedAccount, this.lastAccountName) this.toolsService.findAccount(userAccount, this.lastAccountName)
.then((account: Account) => { .then((account: Account) => {
return this.mastodonService.unfollow(this.currentlyUsedAccount, account); return this.mastodonService.unfollow(userAccount, account);
}) })
.then((relationship: Relationship) => { .then((relationship: Relationship) => {
this.relationship = relationship; this.relationship = relationship;
@ -175,4 +194,44 @@ export class UserProfileComponent implements OnInit {
}); });
return false; 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;
}
} }