new overlay navigation functionnal
This commit is contained in:
parent
eb66cb7760
commit
798f8f404d
|
@ -1,5 +1,5 @@
|
|||
import { Component, OnInit, Output, EventEmitter, Input, ViewChild } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Component, OnInit, Output, EventEmitter, Input, ViewChild, OnDestroy } from '@angular/core';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { Store } from '@ngxs/store';
|
||||
|
||||
import { StreamElement, StreamTypeEnum, AddStream } from '../../../states/streams.state';
|
||||
|
@ -12,8 +12,9 @@ import { AccountInfo } from '../../../states/accounts.state';
|
|||
templateUrl: './hashtag.component.html',
|
||||
styleUrls: ['./hashtag.component.scss']
|
||||
})
|
||||
export class HashtagComponent implements OnInit {
|
||||
|
||||
export class HashtagComponent implements OnInit, OnDestroy {
|
||||
@Input() refreshEventEmitter: EventEmitter<any>;
|
||||
|
||||
@Output() browseAccountEvent = new EventEmitter<string>();
|
||||
@Output() browseHashtagEvent = new EventEmitter<string>();
|
||||
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
|
||||
|
@ -27,18 +28,29 @@ export class HashtagComponent implements OnInit {
|
|||
get hashtagElement(): StreamElement{
|
||||
return this._hashtagElement;
|
||||
}
|
||||
|
||||
|
||||
@ViewChild('appStreamStatuses') appStreamStatuses: StreamStatusesComponent;
|
||||
|
||||
goToTopSubject: Subject<void> = new Subject<void>();
|
||||
|
||||
private lastUsedAccount: AccountInfo;
|
||||
private refreshSubscription: Subscription;
|
||||
|
||||
constructor(
|
||||
private readonly store: Store,
|
||||
private readonly toolsService: ToolsService) { }
|
||||
|
||||
ngOnInit() {
|
||||
if(this.refreshEventEmitter) {
|
||||
this.refreshSubscription = this.refreshEventEmitter.subscribe(() => {
|
||||
this.refresh();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if(this.refreshSubscription) this.refreshSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
goToTop(): boolean {
|
||||
|
|
|
@ -4,29 +4,41 @@
|
|||
<fa-icon [icon]="faTimes"></fa-icon>
|
||||
</button>
|
||||
|
||||
<button class="overlay__button overlay-previous" [ngClass]="{'overlay__button--focus': previousElements.length > 0 }" title="previous" (click)="previous()">
|
||||
<button class="overlay__button overlay-previous"
|
||||
[ngClass]="{'overlay__button--focus': hasPreviousElements }" title="previous" (click)="previous()">
|
||||
<fa-icon [icon]="faAngleLeft"></fa-icon>
|
||||
</button>
|
||||
<button class="overlay__button overlay-refresh" [ngClass]="{'overlay__button--focus': refreshFocused }" title="refresh" (click)="refresh()">
|
||||
<button class="overlay__button overlay-refresh" [ngClass]="{'overlay__button--focus': refreshFocused }"
|
||||
title="refresh" (click)="refresh()">
|
||||
<fa-icon [icon]="faRedoAlt"></fa-icon>
|
||||
</button>
|
||||
<button class="overlay__button overlay-next" [ngClass]="{'overlay__button--focus': nextElements.length > 0 }" title="next" (click)="next()">
|
||||
<button class="overlay__button overlay-next" [ngClass]="{'overlay__button--focus': hasNextElements > 0 }"
|
||||
title="next" (click)="next()">
|
||||
<fa-icon [icon]="faAngleRight"></fa-icon>
|
||||
</button>
|
||||
|
||||
<!-- <a href class="overlay-close" (click)="close()">CLOSE</a>
|
||||
<a href class="overlay-previous" (click)="previous()">PREV</a>
|
||||
<a href class="overlay-refresh" *ngIf="canRefresh" (click)="refresh()">REFRESH</a>
|
||||
<a href class="overlay-next" *ngIf="canGoForward" (click)="next()">NEXT</a> -->
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<app-user-profile #appUserProfile *ngIf="accountName" [currentAccount]="accountName" class="stream-overlay__content"
|
||||
(browseAccountEvent)="browseAccount($event)" (browseHashtagEvent)="browseHashtag($event)"
|
||||
(browseThreadEvent)="browseThread($event)"></app-user-profile>
|
||||
<app-hashtag #appHashtag *ngIf="hashtagElement" [hashtagElement]="hashtagElement" class="stream-overlay__content"
|
||||
(browseAccountEvent)="browseAccount($event)" (browseHashtagEvent)="browseHashtag($event)"
|
||||
(browseThreadEvent)="browseThread($event)"></app-hashtag>
|
||||
<app-thread #appThread *ngIf="browseThread" [currentThread]="thread" class="stream-overlay__content"
|
||||
(browseAccountEvent)="browseAccount($event)" (browseHashtagEvent)="browseHashtag($event)"
|
||||
(browseThreadEvent)="browseThread($event)"></app-thread>
|
||||
<div *ngFor="let e of loadedElements" class="stream-overlay__content-wrapper"
|
||||
[class.stream-overlay__content-wrapper--selected]="e.isVisible">
|
||||
<app-user-profile #appUserProfile *ngIf="e.type === 'account'"
|
||||
[currentAccount]="e.account"
|
||||
[refreshEventEmitter]="e.refreshEventEmitter"
|
||||
class="stream-overlay__content"
|
||||
(browseAccountEvent)="browseAccount($event)"
|
||||
(browseHashtagEvent)="browseHashtag($event)"
|
||||
(browseThreadEvent)="browseThread($event)"></app-user-profile>
|
||||
<app-hashtag #appHashtag *ngIf="e.type === 'hashtag'"
|
||||
[hashtagElement]="e.hashtag"
|
||||
[refreshEventEmitter]="e.refreshEventEmitter"
|
||||
class="stream-overlay__content"
|
||||
(browseAccountEvent)="browseAccount($event)"
|
||||
(browseHashtagEvent)="browseHashtag($event)"
|
||||
(browseThreadEvent)="browseThread($event)"></app-hashtag>
|
||||
<app-thread #appThread *ngIf="e.type === 'thread'"
|
||||
[currentThread]="e.thread" class="stream-overlay__content"
|
||||
[refreshEventEmitter]="e.refreshEventEmitter"
|
||||
(browseAccountEvent)="browseAccount($event)"
|
||||
(browseHashtagEvent)="browseHashtag($event)"
|
||||
(browseThreadEvent)="browseThread($event)"></app-thread>
|
||||
</div>
|
||||
</div>
|
|
@ -3,9 +3,11 @@
|
|||
@import "commons";
|
||||
$header-content: 40px;
|
||||
.stream-overlay {
|
||||
// width: $stream-column-width;
|
||||
// width: $stream-column-width;
|
||||
height: calc(100%);
|
||||
background-color: $column-color;
|
||||
position: relative;
|
||||
|
||||
&__header {
|
||||
width: calc(100%);
|
||||
height: $header-content;
|
||||
|
@ -17,6 +19,25 @@ $header-content: 40px;
|
|||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
&__content-wrapper {
|
||||
transition: all .2s;
|
||||
position: absolute;
|
||||
top: $header-content;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
||||
// outline: 1px solid greenyellow;
|
||||
// background-color: salmon;
|
||||
|
||||
z-index: 1;
|
||||
opacity: 0;
|
||||
|
||||
&--selected {
|
||||
z-index: 10;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&__content {
|
||||
display: block;
|
||||
width: calc(100%);
|
||||
|
|
|
@ -5,9 +5,6 @@ import { Store } from '@ngxs/store';
|
|||
|
||||
import { ToolsService, OpenThreadEvent } from '../../../services/tools.service';
|
||||
import { StreamElement, StreamTypeEnum } from '../../../states/streams.state';
|
||||
import { ThreadComponent } from '../thread/thread.component';
|
||||
import { UserProfileComponent } from '../user-profile/user-profile.component';
|
||||
import { HashtagComponent } from '../hashtag/hashtag.component';
|
||||
import { AccountInfo } from '../../../states/accounts.state';
|
||||
|
||||
|
||||
|
@ -21,18 +18,13 @@ export class StreamOverlayComponent implements OnInit, OnDestroy {
|
|||
faAngleRight = faAngleRight;
|
||||
faTimes = faTimes;
|
||||
faRedoAlt = faRedoAlt;
|
||||
|
||||
|
||||
refreshFocused: boolean;
|
||||
previousElements: OverlayBrowsing[] = [];
|
||||
nextElements: OverlayBrowsing[] = [];
|
||||
private currentElement: OverlayBrowsing;
|
||||
hasPreviousElements: boolean;
|
||||
hasNextElements: boolean;
|
||||
|
||||
// canRefresh: boolean = true;
|
||||
// canGoForward: boolean;
|
||||
|
||||
accountName: string;
|
||||
thread: OpenThreadEvent;
|
||||
hashtagElement: StreamElement;
|
||||
loadedElements: OverlayBrowsing[] = [];
|
||||
visibleElementIndex: number = -1;
|
||||
|
||||
@Output() closeOverlay = new EventEmitter();
|
||||
|
||||
|
@ -51,17 +43,13 @@ export class StreamOverlayComponent implements OnInit, OnDestroy {
|
|||
this.browseHashtag(hashtag);
|
||||
}
|
||||
|
||||
@ViewChild('appUserProfile') appUserProfile: UserProfileComponent;
|
||||
@ViewChild('appHashtag') appHashtag: HashtagComponent;
|
||||
@ViewChild('appThread') appThread: ThreadComponent;
|
||||
|
||||
private currentlyUsedAccount: AccountInfo;
|
||||
private accounts$: Observable<AccountInfo[]>;
|
||||
private accountSub: Subscription;
|
||||
|
||||
constructor(
|
||||
private readonly store: Store,
|
||||
private readonly toolsService: ToolsService) {
|
||||
private readonly toolsService: ToolsService) {
|
||||
this.accounts$ = this.store.select(state => state.registeredaccounts.accounts);
|
||||
}
|
||||
|
||||
|
@ -87,36 +75,41 @@ export class StreamOverlayComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
next(): boolean {
|
||||
if (this.nextElements.length === 0) {
|
||||
if (this.visibleElementIndex >= this.loadedElements.length - 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.currentElement) {
|
||||
this.previousElements.push(this.currentElement);
|
||||
}
|
||||
this.loadedElements[this.visibleElementIndex].hide();
|
||||
let newIndex = this.visibleElementIndex + 1;
|
||||
this.loadedElements[newIndex].show();
|
||||
this.visibleElementIndex = newIndex;
|
||||
|
||||
const nextElement = this.nextElements.pop();
|
||||
this.loadElement(nextElement);
|
||||
console.warn(`visibleElementIndex ${this.visibleElementIndex}`);
|
||||
console.warn(`this.loadedElements ${this.loadedElements.length}`);
|
||||
|
||||
//if(this.nextElements.length === 0) this.canGoForward = false;
|
||||
this.hasPreviousElements = true;
|
||||
this.hasNextElements = this.visibleElementIndex < this.loadedElements.length - 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
previous(): boolean {
|
||||
if (this.previousElements.length === 0) {
|
||||
if (this.visibleElementIndex <= 0) {
|
||||
this.closeOverlay.next();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.currentElement) {
|
||||
this.nextElements.push(this.currentElement);
|
||||
}
|
||||
this.loadedElements[this.visibleElementIndex].hide();
|
||||
let newIndex = this.visibleElementIndex - 1;
|
||||
this.loadedElements[newIndex].show();
|
||||
this.visibleElementIndex = newIndex;
|
||||
|
||||
const previousElement = this.previousElements.pop();
|
||||
this.loadElement(previousElement);
|
||||
console.warn(`visibleElementIndex ${this.visibleElementIndex}`);
|
||||
console.warn(`this.loadedElements ${this.loadedElements.length}`);
|
||||
|
||||
this.hasPreviousElements = this.visibleElementIndex > 0;
|
||||
this.hasNextElements = true;
|
||||
|
||||
//this.canGoForward = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -124,92 +117,84 @@ export class StreamOverlayComponent implements OnInit, OnDestroy {
|
|||
this.currentlyUsedAccount = this.toolsService.getSelectedAccounts()[0];
|
||||
this.refreshFocused = false;
|
||||
|
||||
if(this.thread){
|
||||
this.appThread.refresh();
|
||||
} else if(this.hashtagElement){
|
||||
this.appHashtag.refresh();
|
||||
} else if(this.accountName){
|
||||
this.appUserProfile.refresh();
|
||||
}
|
||||
|
||||
this.loadedElements[this.visibleElementIndex].refresh();
|
||||
return false;
|
||||
}
|
||||
|
||||
browseAccount(accountName: string): void {
|
||||
if(!accountName) return;
|
||||
if (!accountName) return;
|
||||
|
||||
this.nextElements.length = 0;
|
||||
if (this.currentElement) {
|
||||
this.previousElements.push(this.currentElement);
|
||||
}
|
||||
const newElement = new OverlayBrowsing(null, accountName, null);
|
||||
this.loadElement(newElement);
|
||||
//this.canGoForward = false;
|
||||
}
|
||||
|
||||
browseHashtag(hashtag: string): void {
|
||||
if(!hashtag) return;
|
||||
|
||||
this.nextElements.length = 0;
|
||||
if (this.currentElement) {
|
||||
this.previousElements.push(this.currentElement);
|
||||
}
|
||||
if (!hashtag) return;
|
||||
|
||||
const selectedAccount = this.toolsService.getSelectedAccounts()[0];
|
||||
const hashTagElement = new StreamElement(StreamTypeEnum.tag, hashtag, selectedAccount.id, hashtag, null, null, selectedAccount.instance);
|
||||
const newElement = new OverlayBrowsing(hashTagElement, null, null);
|
||||
this.loadElement(newElement);
|
||||
// this.canGoForward = false;
|
||||
}
|
||||
|
||||
browseThread(openThread: OpenThreadEvent): any {
|
||||
if(!openThread) return;
|
||||
|
||||
this.nextElements.length = 0;
|
||||
if (this.currentElement) {
|
||||
this.previousElements.push(this.currentElement);
|
||||
}
|
||||
if (!openThread) return;
|
||||
|
||||
const newElement = new OverlayBrowsing(null, null, openThread);
|
||||
this.loadElement(newElement);
|
||||
//this.canGoForward = false;
|
||||
}
|
||||
|
||||
private loadElement(element: OverlayBrowsing) {
|
||||
|
||||
this.currentlyUsedAccount = this.toolsService.getSelectedAccounts()[0];
|
||||
this.refreshFocused = false;
|
||||
this.refreshFocused = false;
|
||||
|
||||
this.currentElement = element;
|
||||
if (this.visibleElementIndex >= 0) {
|
||||
this.loadedElements[this.visibleElementIndex].hide();
|
||||
this.loadedElements = this.loadedElements.slice(0, this.visibleElementIndex + 1);
|
||||
}
|
||||
|
||||
this.accountName = this.currentElement.account;
|
||||
this.thread = this.currentElement.thread;
|
||||
this.hashtagElement = this.currentElement.hashtag;
|
||||
this.visibleElementIndex = this.visibleElementIndex + 1;
|
||||
this.loadedElements.push(element)
|
||||
this.loadedElements[this.visibleElementIndex].show();
|
||||
|
||||
this.hasPreviousElements = this.visibleElementIndex > 0;
|
||||
this.hasNextElements = false;
|
||||
}
|
||||
}
|
||||
|
||||
class OverlayBrowsing {
|
||||
refreshEventEmitter = new EventEmitter();
|
||||
|
||||
constructor(
|
||||
public readonly hashtag: StreamElement,
|
||||
public readonly account: string,
|
||||
public readonly thread: OpenThreadEvent) {
|
||||
|
||||
if (hashtag) {
|
||||
this.type = OverlayEnum.hashtag;
|
||||
this.type = 'hashtag';
|
||||
} else if (account) {
|
||||
this.type = OverlayEnum.account;
|
||||
this.type = 'account';
|
||||
} else if (thread) {
|
||||
this.type = OverlayEnum.thread;
|
||||
this.type = 'thread';
|
||||
} else {
|
||||
throw Error('NotImplemented');
|
||||
}
|
||||
}
|
||||
|
||||
type: OverlayEnum;
|
||||
}
|
||||
show(): any {
|
||||
setTimeout(() => {
|
||||
this.isVisible = true;
|
||||
}, 200);
|
||||
}
|
||||
hide(): any {
|
||||
this.isVisible = false;
|
||||
}
|
||||
|
||||
enum OverlayEnum {
|
||||
unknown = 0,
|
||||
hashtag = 1,
|
||||
account = 2,
|
||||
thread = 3
|
||||
refresh(): any {
|
||||
this.refreshEventEmitter.next();
|
||||
}
|
||||
|
||||
isVisible: boolean;
|
||||
type: 'hashtag' | 'account' | 'thread';
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ export class ThreadComponent implements OnInit, OnDestroy {
|
|||
@Output() browseHashtagEvent = new EventEmitter<string>();
|
||||
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
|
||||
|
||||
@Input() refreshEventEmitter: EventEmitter<any>;
|
||||
|
||||
@Input('currentThread')
|
||||
set currentThread(thread: OpenThreadEvent) {
|
||||
if (thread) {
|
||||
|
@ -41,6 +43,7 @@ export class ThreadComponent implements OnInit, OnDestroy {
|
|||
private newPostSub: Subscription;
|
||||
private hideAccountSubscription: Subscription;
|
||||
private deleteStatusSubscription: Subscription;
|
||||
private refreshSubscription: Subscription;
|
||||
|
||||
constructor(
|
||||
private readonly notificationService: NotificationService,
|
||||
|
@ -48,6 +51,12 @@ export class ThreadComponent implements OnInit, OnDestroy {
|
|||
private readonly mastodonService: MastodonService) { }
|
||||
|
||||
ngOnInit() {
|
||||
if(this.refreshEventEmitter) {
|
||||
this.refreshSubscription = this.refreshEventEmitter.subscribe(() => {
|
||||
this.refresh();
|
||||
})
|
||||
}
|
||||
|
||||
this.newPostSub = this.notificationService.newRespondPostedStream.subscribe((replyData: NewReplyData) => {
|
||||
if(replyData){
|
||||
const repondingStatus = this.statuses.find(x => x.status.id === replyData.uiStatusId);
|
||||
|
@ -97,6 +106,7 @@ export class ThreadComponent implements OnInit, OnDestroy {
|
|||
if (this.newPostSub) this.newPostSub.unsubscribe();
|
||||
if (this.hideAccountSubscription) this.hideAccountSubscription.unsubscribe();
|
||||
if (this.deleteStatusSubscription) this.deleteStatusSubscription.unsubscribe();
|
||||
if(this.refreshSubscription) this.refreshSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
private getThread(openThreadEvent: OpenThreadEvent) {
|
||||
|
|
|
@ -55,6 +55,7 @@ export class UserProfileComponent implements OnInit {
|
|||
private accounts$: Observable<AccountInfo[]>;
|
||||
private accountSub: Subscription;
|
||||
private deleteStatusSubscription: Subscription;
|
||||
private refreshSubscription: Subscription;
|
||||
|
||||
@ViewChild('statusstream') public statustream: ElementRef;
|
||||
@ViewChild('profilestatuses') public profilestatuses: ElementRef;
|
||||
|
@ -63,6 +64,8 @@ export class UserProfileComponent implements OnInit {
|
|||
@Output() browseHashtagEvent = new EventEmitter<string>();
|
||||
@Output() browseThreadEvent = new EventEmitter<OpenThreadEvent>();
|
||||
|
||||
@Input() refreshEventEmitter: EventEmitter<any>;
|
||||
|
||||
@Input('currentAccount')
|
||||
set currentAccount(accountName: string) {
|
||||
this.load(accountName);
|
||||
|
@ -79,6 +82,12 @@ export class UserProfileComponent implements OnInit {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
if(this.refreshEventEmitter) {
|
||||
this.refreshSubscription = this.refreshEventEmitter.subscribe(() => {
|
||||
this.refresh();
|
||||
})
|
||||
}
|
||||
|
||||
this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => {
|
||||
if (this.displayedAccount) {
|
||||
const userAccount = accounts.filter(x => x.isSelected)[0];
|
||||
|
@ -107,8 +116,9 @@ export class UserProfileComponent implements OnInit {
|
|||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.accountSub.unsubscribe();
|
||||
this.deleteStatusSubscription.unsubscribe();
|
||||
if(this.accountSub) this.accountSub.unsubscribe();
|
||||
if(this.deleteStatusSubscription) this.deleteStatusSubscription.unsubscribe();
|
||||
if(this.refreshSubscription) this.refreshSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
private load(accountName: string) {
|
||||
|
|
Loading…
Reference in New Issue