added reply/dm capability

This commit is contained in:
Nicolas Constant 2019-07-03 19:55:33 -04:00
parent b2632e981d
commit a2e0789a9c
No known key found for this signature in database
GPG Key ID: 1E9F677FB01A5688
8 changed files with 126 additions and 40 deletions

View File

@ -4,7 +4,7 @@ import { debounceTime, map } from 'rxjs/operators';
import { Select } from '@ngxs/store';
// import { ElectronService } from 'ngx-electron';
import { NavigationService, LeftPanelType } from './services/navigation.service';
import { NavigationService, LeftPanelType, OpenLeftPanelEvent } from './services/navigation.service';
import { StreamElement } from './states/streams.state';
import { OpenMediaEvent } from './models/common.model';
import { ToolsService } from './services/tools.service';
@ -44,8 +44,8 @@ export class AppComponent implements OnInit, OnDestroy {
}
});
this.columnEditorSub = this.navigationService.activatedPanelSubject.subscribe((type: LeftPanelType) => {
if (type === LeftPanelType.Closed) {
this.columnEditorSub = this.navigationService.activatedPanelSubject.subscribe((event: OpenLeftPanelEvent) => {
if (event.type === LeftPanelType.Closed) {
this.floatingColumnActive = false;
} else {
this.floatingColumnActive = true;

View File

@ -21,7 +21,7 @@ import { identifierModuleUrl } from '@angular/compiler';
})
export class CreateStatusComponent implements OnInit, OnDestroy {
private _title: string;
set title(value: string){
set title(value: string) {
this._title = value;
this.countStatusChar(this.status);
}
@ -48,6 +48,26 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
@Output() onClose = new EventEmitter();
@ViewChild('reply') replyElement: ElementRef;
private _isDirectMention: boolean;
@Input('isDirectMention')
set isDirectMention(value: boolean) {
this._isDirectMention = value;
this.initMention();
}
get isDirectMention(): boolean {
return this._isDirectMention;
}
private _replyingUserHandle: string;
@Input('replyingUserHandle')
set replyingUserHandle(value: string) {
this._replyingUserHandle = value;
this.initMention();
}
get replyingUserHandle(): string {
return this._replyingUserHandle;
}
private statusReplyingTo: Status;
selectedPrivacy = 'Public';
@ -55,6 +75,7 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
private accounts$: Observable<AccountInfo[]>;
private accountSub: Subscription;
private selectedAccount: AccountInfo;
constructor(
private readonly store: Store,
@ -70,7 +91,8 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => {
this.accountChanged(accounts);
});
this.selectedAccount = this.toolsService.getSelectedAccounts()[0];
if (this.statusReplyingToWrapper) {
if (this.statusReplyingToWrapper.status.reblog) {
this.statusReplyingTo = this.statusReplyingToWrapper.status.reblog;
@ -99,27 +121,49 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
}
this.title = this.statusReplyingTo.spoiler_text;
} else if (this.replyingUserHandle) {
this.initMention();
}
setTimeout(() => {
this.replyElement.nativeElement.focus();
}, 0);
this.focus();
}
ngOnDestroy() {
this.accountSub.unsubscribe();
}
private focus() {
setTimeout(() => {
this.replyElement.nativeElement.focus();
}, 0);
}
private initMention() {
if (!this.selectedAccount) {
this.selectedAccount = this.toolsService.getSelectedAccounts()[0];
}
if (this.isDirectMention) {
this.setVisibility(VisibilityEnum.Direct);
} else {
this.getDefaultPrivacy();
}
this.status = `@${this.replyingUserHandle} `;
this.countStatusChar(this.status);
this.focus();
}
private accountChanged(accounts: AccountInfo[]): void {
if (accounts && accounts.length > 0) {
const selectedAccount = accounts.filter(x => x.isSelected)[0];
this.selectedAccount = accounts.filter(x => x.isSelected)[0];
const settings = this.toolsService.getAccountSettings(selectedAccount);
const settings = this.toolsService.getAccountSettings(this.selectedAccount);
if (settings.customStatusCharLengthEnabled) {
this.maxCharLength = settings.customStatusCharLength;
this.countStatusChar(this.status);
} else {
this.instancesInfoService.getMaxStatusChars(selectedAccount.instance)
this.instancesInfoService.getMaxStatusChars(this.selectedAccount.instance)
.then((maxChars: number) => {
this.maxCharLength = maxChars;
this.countStatusChar(this.status);
@ -129,18 +173,22 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
});
}
if (!this.statusReplyingToWrapper) {
this.instancesInfoService.getDefaultPrivacy(selectedAccount)
.then((defaultPrivacy: VisibilityEnum) => {
this.setVisibility(defaultPrivacy);
})
.catch((err: HttpErrorResponse) => {
this.notificationService.notifyHttpError(err);
});
if (!this.statusReplyingToWrapper && !this.replyingUserHandle) {
this.getDefaultPrivacy();
}
}
}
private getDefaultPrivacy() {
this.instancesInfoService.getDefaultPrivacy(this.selectedAccount)
.then((defaultPrivacy: VisibilityEnum) => {
this.setVisibility(defaultPrivacy);
})
.catch((err: HttpErrorResponse) => {
this.notificationService.notifyHttpError(err);
});
}
private setVisibility(defaultPrivacy: VisibilityEnum) {
switch (defaultPrivacy) {
case VisibilityEnum.Public:

View File

@ -1,5 +1,7 @@
<div class="panel">
<h3 class="panel__title">new message</h3>
<app-create-status (onClose)="closeColumn()"></app-create-status>
<app-create-status (onClose)="closeColumn()"
[isDirectMention]="isDirectMention"
[replyingUserHandle]="userHandle"></app-create-status>
</div>

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, Input } from '@angular/core';
import { NavigationService } from '../../../services/navigation.service';
@ -8,10 +8,14 @@ import { NavigationService } from '../../../services/navigation.service';
styleUrls: ['./add-new-status.component.scss']
})
export class AddNewStatusComponent implements OnInit {
constructor(
private readonly navigationService: NavigationService) { }
ngOnInit() {
@Input() isDirectMention: boolean;
@Input() userHandle: string;
constructor(private readonly navigationService: NavigationService) {
}
ngOnInit() {
}
closeColumn() {

View File

@ -15,7 +15,9 @@
(browseAccountEvent)="browseAccount($event)"
(browseHashtagEvent)="browseHashtag($event)"
(browseThreadEvent)="browseThread($event)"></app-manage-account>
<app-add-new-status *ngIf="openPanel === 'createNewStatus'"></app-add-new-status>
<app-add-new-status *ngIf="openPanel === 'createNewStatus'"
[isDirectMention]="isDirectMention"
[userHandle]="userHandle"></app-add-new-status>
<app-add-new-account *ngIf="openPanel === 'addNewAccount'"></app-add-new-account>
<app-search *ngIf="openPanel === 'search'"
(browseAccountEvent)="browseAccount($event)"

View File

@ -1,7 +1,7 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { faTimes } from "@fortawesome/free-solid-svg-icons";
import { NavigationService, LeftPanelType } from '../../services/navigation.service';
import { NavigationService, LeftPanelType, OpenLeftPanelEvent, LeftPanelAction } from '../../services/navigation.service';
import { AccountWrapper } from '../../models/account.models';
import { OpenThreadEvent } from '../../services/tools.service';
import { Subscription } from 'rxjs';
@ -21,6 +21,9 @@ export class FloatingColumnComponent implements OnInit, OnDestroy {
userAccountUsed: AccountWrapper;
isDirectMention: boolean;
userHandle: string;
openPanel: string = '';
private activatedPanelSub: Subscription;
@ -28,9 +31,11 @@ export class FloatingColumnComponent implements OnInit, OnDestroy {
constructor(private readonly navigationService: NavigationService) { }
ngOnInit() {
this.activatedPanelSub = this.navigationService.activatedPanelSubject.subscribe((type: LeftPanelType) => {
this.activatedPanelSub = this.navigationService.activatedPanelSubject.subscribe((event: OpenLeftPanelEvent) => {
this.isDirectMention = false;
this.userHandle = null;
this.overlayActive = false;
switch (type) {
switch (event.type) {
case LeftPanelType.Closed:
this.openPanel = '';
break;
@ -42,9 +47,11 @@ export class FloatingColumnComponent implements OnInit, OnDestroy {
}
break;
case LeftPanelType.CreateNewStatus:
if (this.openPanel === 'createNewStatus') {
if (this.openPanel === 'createNewStatus' && !event.userHandle) {
this.closePanel();
} else {
this.isDirectMention = event.action === LeftPanelAction.DM;
this.userHandle = event.userHandle;
this.openPanel = 'createNewStatus';
}
break;

View File

@ -4,6 +4,7 @@ import { Store } from '@ngxs/store';
import { Observable, Subscription } from 'rxjs';
import { faWindowClose, faReply, faRetweet, faStar, faEllipsisH, faLock } from "@fortawesome/free-solid-svg-icons";
import { faWindowClose as faWindowCloseRegular } from "@fortawesome/free-regular-svg-icons";
import { ContextMenuComponent, ContextMenuService } from 'ngx-contextmenu';
import { MastodonService } from '../../../../services/mastodon.service';
import { AccountInfo } from '../../../../states/accounts.state';
@ -11,8 +12,7 @@ import { Status, Account } from '../../../../services/models/mastodon.interfaces
import { ToolsService } from '../../../../services/tools.service';
import { NotificationService } from '../../../../services/notification.service';
import { StatusWrapper } from '../../../../models/common.model';
import { ContextMenuComponent, ContextMenuService } from 'ngx-contextmenu';
import { NavigationService } from '../../../../services/navigation.service';
@Component({
selector: 'app-action-bar',
@ -59,7 +59,8 @@ export class ActionBarComponent implements OnInit, OnDestroy {
private accountSub: Subscription;
constructor(
private contextMenuService: ContextMenuService,
private readonly navigationService: NavigationService,
private readonly contextMenuService: ContextMenuService,
private readonly store: Store,
private readonly toolsService: ToolsService,
private readonly mastodonService: MastodonService,
@ -97,7 +98,7 @@ export class ActionBarComponent implements OnInit, OnDestroy {
private extractHandle(account: Account) {
this.username = account.acct.split('@')[0];
this.fullHandle = account.acct;
this.fullHandle = account.acct.toLowerCase();
if (!this.fullHandle.includes('@')) {
this.fullHandle += `@${account.url.replace('https://', '').split('/')[0]}`;
}
@ -273,13 +274,12 @@ export class ActionBarComponent implements OnInit, OnDestroy {
}
mentionAccount(): boolean {
this.navigationService.replyToUser(this.fullHandle, false);
return false;
}
dmAccount(): boolean {
this.navigationService.replyToUser(this.fullHandle, true);
return false;
}

View File

@ -7,7 +7,7 @@ import { OpenMediaEvent } from '../models/common.model';
@Injectable()
export class NavigationService {
private accountToManage: AccountWrapper;
activatedPanelSubject = new BehaviorSubject<LeftPanelType>(LeftPanelType.Closed);
activatedPanelSubject = new BehaviorSubject<OpenLeftPanelEvent>(new OpenLeftPanelEvent(LeftPanelType.Closed));
activatedMediaSubject: Subject<OpenMediaEvent> = new Subject<OpenMediaEvent>();
columnSelectedSubject = new BehaviorSubject<number>(-1);
@ -15,18 +15,27 @@ export class NavigationService {
openColumnEditor(acc: AccountWrapper) {
this.accountToManage = acc;
this.activatedPanelSubject.next(LeftPanelType.ManageAccount);
const newEvent = new OpenLeftPanelEvent(LeftPanelType.ManageAccount);
this.activatedPanelSubject.next(newEvent);
}
openPanel(type: LeftPanelType){
this.activatedPanelSubject.next(type);
const newEvent = new OpenLeftPanelEvent(type);
this.activatedPanelSubject.next(newEvent);
}
closePanel() {
this.activatedPanelSubject.next(LeftPanelType.Closed);
const newEvent = new OpenLeftPanelEvent(LeftPanelType.Closed);
this.activatedPanelSubject.next(newEvent);
this.accountToManage = null;
}
replyToUser(userHandle: string, isDirectMessage: boolean = false) {
const action = isDirectMessage ? LeftPanelAction.DM : LeftPanelAction.Mention;
const newEvent = new OpenLeftPanelEvent(LeftPanelType.CreateNewStatus, action, userHandle);
this.activatedPanelSubject.next(newEvent);
}
columnSelected(index: number): void {
this.columnSelectedSubject.next(index);
}
@ -40,6 +49,20 @@ export class NavigationService {
}
}
export class OpenLeftPanelEvent {
constructor(
public type: LeftPanelType,
public action: LeftPanelAction = LeftPanelAction.None,
public userHandle: string = null ) {
}
}
export enum LeftPanelAction {
None = 0,
DM = 1,
Mention = 2
}
export enum LeftPanelType {
Closed = 0,
ManageAccount = 1,