This commit is contained in:
Nicolas Constant 2019-02-18 22:44:21 -05:00
parent f3a9ff1013
commit 5c88bda225
No known key found for this signature in database
GPG Key ID: 1E9F677FB01A5688
10 changed files with 101 additions and 56 deletions

View File

@ -4,7 +4,7 @@ import { HttpErrorResponse } from '@angular/common/http';
import { MastodonService } from '../../../services/mastodon.service';
import { AccountInfo } from '../../../states/accounts.state';
import { Results, Account } from '../../../services/models/mastodon.interfaces';
import { ToolsService } from '../../../services/tools.service';
import { ToolsService, OpenThreadEvent } from '../../../services/tools.service';
import { StatusWrapper } from '../../stream/stream.component';
import { NotificationService } from '../../../services/notification.service';
@ -24,7 +24,7 @@ export class SearchComponent implements OnInit {
@Output() browseAccountEvent = new EventEmitter<string>();
@Output() browseHashtagEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
constructor(
private readonly notificationService: NotificationService,

View File

@ -3,6 +3,7 @@ import { Subject } from 'rxjs';
import { Store } from '@ngxs/store';
import { StreamElement, StreamTypeEnum, AddStream } from '../../../states/streams.state';
import { OpenThreadEvent } from '../../../services/tools.service';
@Component({
selector: 'app-hashtag',
@ -12,7 +13,7 @@ import { StreamElement, StreamTypeEnum, AddStream } from '../../../states/stream
export class HashtagComponent implements OnInit {
@Output() browseAccountEvent = new EventEmitter<string>();
@Output() browseHashtagEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
@Input() hashtagElement: StreamElement;
@ -47,7 +48,7 @@ export class HashtagComponent implements OnInit {
this.browseHashtagEvent.next(hashtag);
}
browseThread(statusUri: string): void {
this.browseThreadEvent.next(statusUri);
browseThread(openThreadEvent: OpenThreadEvent): void {
this.browseThreadEvent.next(openThreadEvent);
}
}

View File

@ -1,6 +1,7 @@
import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
import { Status, Account } from "../../../services/models/mastodon.interfaces";
import { StatusWrapper } from "../stream.component";
import { OpenThreadEvent } from "../../../services/tools.service";
@Component({
selector: "app-status",
@ -15,7 +16,7 @@ export class StatusComponent implements OnInit {
@Output() browseAccountEvent = new EventEmitter<string>();
@Output() browseHashtagEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
private _statusWrapper: StatusWrapper;
status: Status;
@ -78,11 +79,15 @@ export class StatusComponent implements OnInit {
textSelected(): void {
const status = this._statusWrapper.status;
const accountInfo = this._statusWrapper.provider;
if (status.reblog) {
this.browseThreadEvent.next(status.reblog.uri);
let openThread: OpenThreadEvent;
if (status.reblog) {
openThread = new OpenThreadEvent(status.reblog, accountInfo);
} else {
this.browseThreadEvent.next(this._statusWrapper.status.uri);
openThread = new OpenThreadEvent(status, accountInfo);
}
this.browseThreadEvent.next(openThread);
}
}

View File

@ -1,7 +1,7 @@
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import { Account, Results } from "../../../services/models/mastodon.interfaces";
import { MastodonService } from '../../../services/mastodon.service';
import { ToolsService } from '../../../services/tools.service';
import { ToolsService, OpenThreadEvent } from '../../../services/tools.service';
import { StreamElement, StreamTypeEnum } from '../../../states/streams.state';
@Component({
@ -19,7 +19,7 @@ export class StreamOverlayComponent implements OnInit {
canGoForward: boolean;
accountName: string;
thread: string;
thread: OpenThreadEvent;
// hashtag: string;
hashtagElement: StreamElement;
@ -32,8 +32,8 @@ export class StreamOverlayComponent implements OnInit {
}
@Input('browseThreadData')
set browseThreadData(statusUri: string) {
this.browseThread(statusUri);
set browseThreadData(openThread: OpenThreadEvent) {
this.browseThread(openThread);
}
@Input('browseHashtagData')
@ -116,15 +116,15 @@ export class StreamOverlayComponent implements OnInit {
this.canGoForward = false;
}
browseThread(statusUri: string): any {
if(!statusUri) return;
browseThread(openThread: OpenThreadEvent): any {
if(!openThread) return;
this.nextElements.length = 0;
if (this.currentElement) {
this.previousElements.push(this.currentElement);
}
const newElement = new OverlayBrowsing(null, null, statusUri);
const newElement = new OverlayBrowsing(null, null, openThread);
this.loadElement(newElement);
this.canGoForward = false;
}
@ -142,7 +142,7 @@ class OverlayBrowsing {
constructor(
public readonly hashtag: StreamElement,
public readonly account: string,
public readonly thread: string) {
public readonly thread: OpenThreadEvent) {
if (hashtag) {
this.type = OverlayEnum.hashtag;

View File

@ -1,6 +1,8 @@
<div class="stream-toots flexcroll" #statusstream (scroll)="onScroll()">
<app-waiting-animation *ngIf="isLoading" class="waiting-icon"></app-waiting-animation>
<div *ngIf="displayError">{{displayError}}</div>
<!-- data-simplebar -->
<div class="stream-toots__status" *ngFor="let statusWrapper of statuses">
<app-status [statusWrapper]="statusWrapper" (browseAccountEvent)="browseAccount($event)" (browseHashtagEvent)="browseHashtag($event)"

View File

@ -10,6 +10,7 @@ import { Status } from '../../../services/models/mastodon.interfaces';
import { MastodonService } from '../../../services/mastodon.service';
import { StatusWrapper } from '../stream.component';
import { NotificationService } from '../../../services/notification.service';
import { OpenThreadEvent } from '../../../services/tools.service';
@Component({
selector: 'app-stream-statuses',
@ -18,6 +19,7 @@ import { NotificationService } from '../../../services/notification.service';
})
export class StreamStatusesComponent implements OnInit, OnDestroy {
isLoading = false; //TODO
displayError: string;
private _streamElement: StreamElement;
private account: AccountInfo;
@ -29,7 +31,7 @@ export class StreamStatusesComponent implements OnInit, OnDestroy {
@Output() browseAccountEvent = new EventEmitter<string>();
@Output() browseHashtagEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
@Input()
set streamElement(streamElement: StreamElement) {
@ -135,8 +137,8 @@ export class StreamStatusesComponent implements OnInit, OnDestroy {
this.browseHashtagEvent.next(hashtag);
}
browseThread(statusUri: string): void {
this.browseThreadEvent.next(statusUri);
browseThread(openThreadEvent: OpenThreadEvent): void {
this.browseThreadEvent.next(openThreadEvent);
}
textSelected(): void {

View File

@ -5,6 +5,7 @@ import { faHome, faGlobe, faUser, faHashtag, faListUl, faBars, IconDefinition }
import { StreamElement, StreamTypeEnum } from "../../states/streams.state";
import { Status } from "../../services/models/mastodon.interfaces";
import { AccountInfo } from "../../states/accounts.state";
import { OpenThreadEvent } from "../../services/tools.service";
@Component({
selector: "app-stream",
@ -18,7 +19,7 @@ export class StreamComponent implements OnInit {
overlayActive: boolean;
overlayAccountToBrowse: string;
overlayHashtagToBrowse: string;
overlayThreadToBrowse: string;
overlayThreadToBrowse: OpenThreadEvent;
goToTopSubject: Subject<void> = new Subject<void>();
@ -75,10 +76,10 @@ export class StreamComponent implements OnInit {
this.overlayActive = true;
}
browseThread(statusUri: string): void {
browseThread(openThreadEvent: OpenThreadEvent): void {
this.overlayAccountToBrowse = null;
this.overlayHashtagToBrowse = null;
this.overlayThreadToBrowse = statusUri;
this.overlayThreadToBrowse = openThreadEvent;
this.overlayActive = true;
}

View File

@ -3,9 +3,10 @@ import { HttpErrorResponse } from '@angular/common/http';
import { StatusWrapper } from '../stream.component';
import { MastodonService } from '../../../services/mastodon.service';
import { ToolsService } from '../../../services/tools.service';
import { Results, Context } from '../../../services/models/mastodon.interfaces';
import { ToolsService, OpenThreadEvent } from '../../../services/tools.service';
import { Results, Context, Status } from '../../../services/models/mastodon.interfaces';
import { NotificationService } from '../../../services/notification.service';
import { AccountInfo } from '../../../states/accounts.state';
@Component({
selector: 'app-thread',
@ -15,13 +16,14 @@ import { NotificationService } from '../../../services/notification.service';
export class ThreadComponent implements OnInit {
statuses: StatusWrapper[] = [];
isLoading: boolean;
displayError: string;
@Output() browseAccountEvent = new EventEmitter<string>();
@Output() browseHashtagEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
@Input('currentThread')
set currentThread(thread: string) {
set currentThread(thread: OpenThreadEvent) {
if (thread) {
this.isLoading = true;
this.getThread(thread);
@ -36,33 +38,58 @@ export class ThreadComponent implements OnInit {
ngOnInit() {
}
private getThread(thread: string) {
private getThread(openThreadEvent: OpenThreadEvent) {
this.statuses.length = 0;
let currentAccount = this.toolsService.getSelectedAccounts()[0];
this.mastodonService.search(currentAccount, thread, true)
.then((result: Results) => {
if (result.statuses.length === 1) {
const retrievedStatus = result.statuses[0];
this.mastodonService.getStatusContext(currentAccount, retrievedStatus.id)
.then((context: Context) => {
this.isLoading = false;
let contextStatuses = [...context.ancestors, retrievedStatus, ...context.descendants]
const status = openThreadEvent.status;
const sourceAccount = openThreadEvent.sourceAccount;
for (const s of contextStatuses) {
const wrapper = new StatusWrapper(s, currentAccount);
this.statuses.push(wrapper);
}
});
} else {
//TODO handle error
this.isLoading = false;
console.error('could not retrieve status');
}
})
.catch((err: HttpErrorResponse) => {
this.notificationService.notifyHttpError(err);
if (status.visibility === 'public' || status.visibility === 'unlisted') {
var statusPromise: Promise<Status> = Promise.resolve(status);
if (sourceAccount.id !== currentAccount.id) {
statusPromise = this.mastodonService.search(currentAccount, status.uri, true)
.then((result: Results) => {
if (result.statuses.length === 1) {
const retrievedStatus = result.statuses[0];
return retrievedStatus;
}
throw new Error('could not find status');
});
}
this.retrieveThread(currentAccount, statusPromise);
} else if (sourceAccount.id === currentAccount.id) {
var statusPromise = Promise.resolve(status);
this.retrieveThread(currentAccount, statusPromise);
} else {
this.isLoading = false;
this.displayError = `You need to use your account ${sourceAccount.username}@${sourceAccount.instance} to show this thread`;
}
}
private retrieveThread(currentAccount: AccountInfo, pipeline: Promise<Status>) {
pipeline
.then((status: Status) => {
this.mastodonService.getStatusContext(currentAccount, status.id)
.then((context: Context) => {
this.isLoading = false;
let contextStatuses = [...context.ancestors, status, ...context.descendants]
for (const s of contextStatuses) {
const wrapper = new StatusWrapper(s, currentAccount);
this.statuses.push(wrapper);
}
})
.catch((err: HttpErrorResponse) => {
this.isLoading = false;
this.notificationService.notifyHttpError(err);
});
});
}
@ -78,7 +105,7 @@ export class ThreadComponent implements OnInit {
this.browseHashtagEvent.next(hashtag);
}
browseThread(statusUri: string): void {
this.browseThreadEvent.next(statusUri);
browseThread(openThreadEvent: OpenThreadEvent): void {
this.browseThreadEvent.next(openThreadEvent);
}
}

View File

@ -3,7 +3,7 @@ import { HttpErrorResponse } from '@angular/common/http';
import { Account, Status} from "../../../services/models/mastodon.interfaces";
import { MastodonService } from '../../../services/mastodon.service';
import { ToolsService } from '../../../services/tools.service';
import { ToolsService, OpenThreadEvent } from '../../../services/tools.service';
import { StatusWrapper } from '../stream.component';
import { NotificationService } from '../../../services/notification.service';
@ -26,7 +26,7 @@ export class UserProfileComponent implements OnInit {
@Output() browseAccountEvent = new EventEmitter<string>();
@Output() browseHashtagEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<string>();
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
@Input('currentAccount')
//set currentAccount(account: Account) {
@ -65,8 +65,8 @@ export class UserProfileComponent implements OnInit {
this.browseHashtagEvent.next(hashtag);
}
browseThread(statusUri: string): void {
this.browseThreadEvent.next(statusUri);
browseThread(openThreadEvent: OpenThreadEvent): void {
this.browseThreadEvent.next(openThreadEvent);
}
private loadAccount(accountName: string): Promise<Account> {

View File

@ -52,5 +52,12 @@ export class ToolsService {
return statusPromise;
}
}
export class OpenThreadEvent {
constructor(
public status: Status,
public sourceAccount: AccountInfo
) {
}
}