diff --git a/src/app/components/floating-column/search/search.component.ts b/src/app/components/floating-column/search/search.component.ts index 735d0dd0..d4704e11 100644 --- a/src/app/components/floating-column/search/search.component.ts +++ b/src/app/components/floating-column/search/search.component.ts @@ -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(); @Output() browseHashtagEvent = new EventEmitter(); - @Output() browseThreadEvent = new EventEmitter(); + @Output() browseThreadEvent = new EventEmitter(); constructor( private readonly notificationService: NotificationService, diff --git a/src/app/components/stream/hashtag/hashtag.component.ts b/src/app/components/stream/hashtag/hashtag.component.ts index 7760d2a0..917898d5 100644 --- a/src/app/components/stream/hashtag/hashtag.component.ts +++ b/src/app/components/stream/hashtag/hashtag.component.ts @@ -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(); @Output() browseHashtagEvent = new EventEmitter(); - @Output() browseThreadEvent = new EventEmitter(); + @Output() browseThreadEvent = new EventEmitter(); @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); } } diff --git a/src/app/components/stream/status/status.component.ts b/src/app/components/stream/status/status.component.ts index 15a50e53..66e02e7b 100644 --- a/src/app/components/stream/status/status.component.ts +++ b/src/app/components/stream/status/status.component.ts @@ -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(); @Output() browseHashtagEvent = new EventEmitter(); - @Output() browseThreadEvent = new EventEmitter(); + @Output() browseThreadEvent = new EventEmitter(); 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); } } diff --git a/src/app/components/stream/stream-overlay/stream-overlay.component.ts b/src/app/components/stream/stream-overlay/stream-overlay.component.ts index fec67403..5beca3af 100644 --- a/src/app/components/stream/stream-overlay/stream-overlay.component.ts +++ b/src/app/components/stream/stream-overlay/stream-overlay.component.ts @@ -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; diff --git a/src/app/components/stream/stream-statuses/stream-statuses.component.html b/src/app/components/stream/stream-statuses/stream-statuses.component.html index e9f6dec7..7c38a49f 100644 --- a/src/app/components/stream/stream-statuses/stream-statuses.component.html +++ b/src/app/components/stream/stream-statuses/stream-statuses.component.html @@ -1,6 +1,8 @@
+
{{displayError}}
+
(); @Output() browseHashtagEvent = new EventEmitter(); - @Output() browseThreadEvent = new EventEmitter(); + @Output() browseThreadEvent = new EventEmitter(); @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 { diff --git a/src/app/components/stream/stream.component.ts b/src/app/components/stream/stream.component.ts index fbc26ba7..8a252728 100644 --- a/src/app/components/stream/stream.component.ts +++ b/src/app/components/stream/stream.component.ts @@ -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 = new Subject(); @@ -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; } diff --git a/src/app/components/stream/thread/thread.component.ts b/src/app/components/stream/thread/thread.component.ts index 60f399cb..de30c3f0 100644 --- a/src/app/components/stream/thread/thread.component.ts +++ b/src/app/components/stream/thread/thread.component.ts @@ -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(); @Output() browseHashtagEvent = new EventEmitter(); - @Output() browseThreadEvent = new EventEmitter(); + @Output() browseThreadEvent = new EventEmitter(); @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 = 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) { + 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); } } diff --git a/src/app/components/stream/user-profile/user-profile.component.ts b/src/app/components/stream/user-profile/user-profile.component.ts index 72c825cd..f5488e5f 100644 --- a/src/app/components/stream/user-profile/user-profile.component.ts +++ b/src/app/components/stream/user-profile/user-profile.component.ts @@ -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(); @Output() browseHashtagEvent = new EventEmitter(); - @Output() browseThreadEvent = new EventEmitter(); + @Output() browseThreadEvent = new EventEmitter(); @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 { diff --git a/src/app/services/tools.service.ts b/src/app/services/tools.service.ts index 35c0cbba..b07e8bde 100644 --- a/src/app/services/tools.service.ts +++ b/src/app/services/tools.service.ts @@ -52,5 +52,12 @@ export class ToolsService { return statusPromise; } - +} + +export class OpenThreadEvent { + constructor( + public status: Status, + public sourceAccount: AccountInfo + ) { + } }