2019-03-07 06:31:06 +01:00
|
|
|
import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, ElementRef, ViewChild } from '@angular/core';
|
2019-03-06 04:46:50 +01:00
|
|
|
import { HttpErrorResponse } from '@angular/common/http';
|
2019-03-07 06:31:06 +01:00
|
|
|
import { Store } from '@ngxs/store';
|
|
|
|
import { Subscription, Observable } from 'rxjs';
|
2019-03-06 04:46:50 +01:00
|
|
|
|
|
|
|
import { MastodonService, VisibilityEnum } from '../../services/mastodon.service';
|
2019-03-10 22:38:10 +01:00
|
|
|
import { Status, Attachment } from '../../services/models/mastodon.interfaces';
|
2019-03-06 04:46:50 +01:00
|
|
|
import { ToolsService } from '../../services/tools.service';
|
|
|
|
import { NotificationService } from '../../services/notification.service';
|
|
|
|
import { StatusWrapper } from '../../models/common.model';
|
2019-03-06 05:02:11 +01:00
|
|
|
import { AccountInfo } from '../../states/accounts.state';
|
2019-03-07 06:31:06 +01:00
|
|
|
import { InstancesInfoService } from '../../services/instances-info.service';
|
2019-03-10 22:38:10 +01:00
|
|
|
import { MediaService } from '../../services/media.service';
|
2019-03-07 06:31:06 +01:00
|
|
|
|
2019-03-06 04:46:50 +01:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-create-status',
|
|
|
|
templateUrl: './create-status.component.html',
|
|
|
|
styleUrls: ['./create-status.component.scss']
|
|
|
|
})
|
2019-03-07 06:31:06 +01:00
|
|
|
export class CreateStatusComponent implements OnInit, OnDestroy {
|
2019-06-24 00:45:11 +02:00
|
|
|
private _title: string;
|
2019-07-04 01:55:33 +02:00
|
|
|
set title(value: string) {
|
2019-06-24 00:45:11 +02:00
|
|
|
this._title = value;
|
|
|
|
this.countStatusChar(this.status);
|
|
|
|
}
|
|
|
|
get title(): string {
|
|
|
|
return this._title;
|
|
|
|
}
|
2019-03-07 01:02:29 +01:00
|
|
|
|
|
|
|
private _status: string = '';
|
2019-07-06 06:20:03 +02:00
|
|
|
@Input('status')
|
2019-03-11 05:31:56 +01:00
|
|
|
set status(value: string) {
|
2019-07-06 06:20:03 +02:00
|
|
|
if (value) {
|
|
|
|
this.countStatusChar(value);
|
2019-07-23 04:30:29 +02:00
|
|
|
this.detectAutosuggestion(value);
|
2019-07-06 06:20:03 +02:00
|
|
|
this._status = value;
|
|
|
|
}
|
2019-03-07 01:02:29 +01:00
|
|
|
}
|
|
|
|
get status(): string {
|
|
|
|
return this._status;
|
|
|
|
}
|
2019-03-07 02:45:36 +01:00
|
|
|
|
2019-07-08 00:58:56 +02:00
|
|
|
@Input('redraftedStatus')
|
|
|
|
set redraftedStatus(value: StatusWrapper) {
|
|
|
|
if (value) {
|
2019-07-09 06:20:05 +02:00
|
|
|
let parser = new DOMParser();
|
|
|
|
var dom = parser.parseFromString(value.status.content, 'text/html')
|
|
|
|
this.status = dom.body.textContent;
|
|
|
|
|
2019-07-08 00:58:56 +02:00
|
|
|
this.setVisibilityFromStatus(value.status);
|
|
|
|
this.title = value.status.spoiler_text;
|
|
|
|
|
|
|
|
if (value.status.in_reply_to_id) {
|
|
|
|
this.isSending = true;
|
|
|
|
this.mastodonService.getStatus(value.provider, value.status.in_reply_to_id)
|
|
|
|
.then((status: Status) => {
|
2019-07-09 06:20:05 +02:00
|
|
|
this.statusReplyingToWrapper = new StatusWrapper(status, value.provider);
|
|
|
|
|
|
|
|
const mentions = this.getMentions(this.statusReplyingToWrapper.status, this.statusReplyingToWrapper.provider);
|
|
|
|
for (const mention of mentions) {
|
|
|
|
const name = `@${mention.split('@')[0]}`;
|
|
|
|
if(this.status.includes(name)){
|
|
|
|
this.status = this.status.replace(name, `@${mention}`);
|
|
|
|
} else {
|
|
|
|
this.status = `@${mention} ` + this.status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-08 00:58:56 +02:00
|
|
|
})
|
|
|
|
.catch(err => {
|
|
|
|
this.notificationService.notifyHttpError(err);
|
|
|
|
})
|
|
|
|
.then(() => {
|
|
|
|
this.isSending = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-07 06:31:06 +01:00
|
|
|
private maxCharLength: number;
|
|
|
|
charCountLeft: number;
|
2019-03-07 02:45:36 +01:00
|
|
|
postCounts: number = 1;
|
2019-03-06 05:37:58 +01:00
|
|
|
isSending: boolean;
|
2019-04-07 21:03:17 +02:00
|
|
|
mentionTooFarAwayError: boolean;
|
2019-07-23 04:30:29 +02:00
|
|
|
autosuggestData: string = null;
|
2019-03-06 05:37:58 +01:00
|
|
|
|
2019-03-06 04:46:50 +01:00
|
|
|
@Input() statusReplyingToWrapper: StatusWrapper;
|
|
|
|
@Output() onClose = new EventEmitter();
|
|
|
|
@ViewChild('reply') replyElement: ElementRef;
|
|
|
|
|
2019-07-04 01:55:33 +02:00
|
|
|
private _isDirectMention: boolean;
|
|
|
|
@Input('isDirectMention')
|
|
|
|
set isDirectMention(value: boolean) {
|
2019-07-05 23:22:33 +02:00
|
|
|
if (value) {
|
|
|
|
this._isDirectMention = value;
|
|
|
|
this.initMention();
|
|
|
|
}
|
2019-07-04 01:55:33 +02:00
|
|
|
}
|
|
|
|
get isDirectMention(): boolean {
|
|
|
|
return this._isDirectMention;
|
|
|
|
}
|
|
|
|
|
|
|
|
private _replyingUserHandle: string;
|
|
|
|
@Input('replyingUserHandle')
|
|
|
|
set replyingUserHandle(value: string) {
|
2019-07-05 23:22:33 +02:00
|
|
|
if (value) {
|
|
|
|
this._replyingUserHandle = value;
|
|
|
|
this.initMention();
|
|
|
|
}
|
2019-07-04 01:55:33 +02:00
|
|
|
}
|
|
|
|
get replyingUserHandle(): string {
|
|
|
|
return this._replyingUserHandle;
|
|
|
|
}
|
|
|
|
|
2019-03-06 04:46:50 +01:00
|
|
|
private statusReplyingTo: Status;
|
|
|
|
|
|
|
|
selectedPrivacy = 'Public';
|
|
|
|
privacyList: string[] = ['Public', 'Unlisted', 'Follows-only', 'DM'];
|
|
|
|
|
2019-03-07 06:31:06 +01:00
|
|
|
private accounts$: Observable<AccountInfo[]>;
|
|
|
|
private accountSub: Subscription;
|
2019-07-04 01:55:33 +02:00
|
|
|
private selectedAccount: AccountInfo;
|
2019-03-07 06:31:06 +01:00
|
|
|
|
2019-03-06 04:46:50 +01:00
|
|
|
constructor(
|
2019-03-07 06:31:06 +01:00
|
|
|
private readonly store: Store,
|
2019-03-06 04:46:50 +01:00
|
|
|
private readonly notificationService: NotificationService,
|
|
|
|
private readonly toolsService: ToolsService,
|
2019-03-07 06:31:06 +01:00
|
|
|
private readonly mastodonService: MastodonService,
|
2019-03-10 22:38:10 +01:00
|
|
|
private readonly instancesInfoService: InstancesInfoService,
|
2019-03-11 05:31:56 +01:00
|
|
|
private readonly mediaService: MediaService) {
|
|
|
|
this.accounts$ = this.store.select(state => state.registeredaccounts.accounts);
|
|
|
|
}
|
2019-03-06 04:46:50 +01:00
|
|
|
|
|
|
|
ngOnInit() {
|
2019-03-07 06:31:06 +01:00
|
|
|
this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => {
|
|
|
|
this.accountChanged(accounts);
|
|
|
|
});
|
2019-07-04 01:55:33 +02:00
|
|
|
this.selectedAccount = this.toolsService.getSelectedAccounts()[0];
|
2019-07-05 23:22:33 +02:00
|
|
|
|
2019-03-06 04:46:50 +01:00
|
|
|
if (this.statusReplyingToWrapper) {
|
|
|
|
if (this.statusReplyingToWrapper.status.reblog) {
|
|
|
|
this.statusReplyingTo = this.statusReplyingToWrapper.status.reblog;
|
|
|
|
} else {
|
|
|
|
this.statusReplyingTo = this.statusReplyingToWrapper.status;
|
|
|
|
}
|
2019-03-06 06:02:16 +01:00
|
|
|
|
2019-03-06 05:00:06 +01:00
|
|
|
const uniqueMentions = this.getMentions(this.statusReplyingTo, this.statusReplyingToWrapper.provider);
|
2019-03-06 04:46:50 +01:00
|
|
|
for (const mention of uniqueMentions) {
|
|
|
|
this.status += `@${mention} `;
|
|
|
|
}
|
2019-03-06 06:02:16 +01:00
|
|
|
|
2019-07-08 00:58:56 +02:00
|
|
|
this.setVisibilityFromStatus(this.statusReplyingTo);
|
2019-04-07 21:03:17 +02:00
|
|
|
|
2019-03-06 06:02:16 +01:00
|
|
|
this.title = this.statusReplyingTo.spoiler_text;
|
2019-07-04 01:55:33 +02:00
|
|
|
} else if (this.replyingUserHandle) {
|
|
|
|
this.initMention();
|
2019-03-06 04:46:50 +01:00
|
|
|
}
|
|
|
|
|
2019-07-04 01:55:33 +02:00
|
|
|
this.focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnDestroy() {
|
|
|
|
this.accountSub.unsubscribe();
|
|
|
|
}
|
|
|
|
|
2019-07-23 04:30:29 +02:00
|
|
|
private detectAutosuggestion(status: string) {
|
|
|
|
const parsedStatus = status.split(' ');
|
|
|
|
if(parsedStatus && parsedStatus.length > 0){
|
|
|
|
const lastElement = parsedStatus[parsedStatus.length - 1];
|
|
|
|
if(lastElement.length > 2 && (lastElement.startsWith('@') || lastElement.startsWith('#'))){
|
|
|
|
//this.autosuggestData = lastElement.substring(1);
|
|
|
|
this.autosuggestData = lastElement;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.autosuggestData = null;
|
|
|
|
}
|
|
|
|
|
2019-07-04 01:55:33 +02:00
|
|
|
private focus() {
|
2019-03-06 04:46:50 +01:00
|
|
|
setTimeout(() => {
|
|
|
|
this.replyElement.nativeElement.focus();
|
|
|
|
}, 0);
|
|
|
|
}
|
|
|
|
|
2019-07-04 01:55:33 +02:00
|
|
|
private initMention() {
|
|
|
|
if (!this.selectedAccount) {
|
|
|
|
this.selectedAccount = this.toolsService.getSelectedAccounts()[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isDirectMention) {
|
|
|
|
this.setVisibility(VisibilityEnum.Direct);
|
|
|
|
} else {
|
|
|
|
this.getDefaultPrivacy();
|
|
|
|
}
|
2019-07-09 07:40:59 +02:00
|
|
|
this.status = `${this.replyingUserHandle} `;
|
2019-07-04 01:55:33 +02:00
|
|
|
this.countStatusChar(this.status);
|
|
|
|
|
|
|
|
this.focus();
|
2019-03-07 06:31:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private accountChanged(accounts: AccountInfo[]): void {
|
2019-03-13 00:02:27 +01:00
|
|
|
if (accounts && accounts.length > 0) {
|
2019-07-04 01:55:33 +02:00
|
|
|
this.selectedAccount = accounts.filter(x => x.isSelected)[0];
|
2019-06-23 23:49:19 +02:00
|
|
|
|
2019-07-04 01:55:33 +02:00
|
|
|
const settings = this.toolsService.getAccountSettings(this.selectedAccount);
|
2019-06-24 00:45:11 +02:00
|
|
|
if (settings.customStatusCharLengthEnabled) {
|
2019-06-23 23:49:19 +02:00
|
|
|
this.maxCharLength = settings.customStatusCharLength;
|
|
|
|
this.countStatusChar(this.status);
|
|
|
|
} else {
|
2019-07-04 01:55:33 +02:00
|
|
|
this.instancesInfoService.getMaxStatusChars(this.selectedAccount.instance)
|
2019-06-24 00:45:11 +02:00
|
|
|
.then((maxChars: number) => {
|
|
|
|
this.maxCharLength = maxChars;
|
|
|
|
this.countStatusChar(this.status);
|
|
|
|
})
|
|
|
|
.catch((err: HttpErrorResponse) => {
|
|
|
|
this.notificationService.notifyHttpError(err);
|
|
|
|
});
|
|
|
|
}
|
2019-03-13 00:02:27 +01:00
|
|
|
|
2019-07-04 01:55:33 +02:00
|
|
|
if (!this.statusReplyingToWrapper && !this.replyingUserHandle) {
|
|
|
|
this.getDefaultPrivacy();
|
2019-04-07 21:03:17 +02:00
|
|
|
}
|
2019-03-13 00:02:27 +01:00
|
|
|
}
|
2019-03-07 06:31:06 +01:00
|
|
|
}
|
|
|
|
|
2019-07-04 01:55:33 +02:00
|
|
|
private getDefaultPrivacy() {
|
|
|
|
this.instancesInfoService.getDefaultPrivacy(this.selectedAccount)
|
|
|
|
.then((defaultPrivacy: VisibilityEnum) => {
|
|
|
|
this.setVisibility(defaultPrivacy);
|
|
|
|
})
|
|
|
|
.catch((err: HttpErrorResponse) => {
|
|
|
|
this.notificationService.notifyHttpError(err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-07-08 00:58:56 +02:00
|
|
|
private setVisibilityFromStatus(status: Status) {
|
|
|
|
switch (status.visibility) {
|
|
|
|
case 'unlisted':
|
|
|
|
this.setVisibility(VisibilityEnum.Unlisted);
|
|
|
|
break;
|
|
|
|
case 'public':
|
|
|
|
this.setVisibility(VisibilityEnum.Public);
|
|
|
|
break;
|
|
|
|
case 'private':
|
|
|
|
this.setVisibility(VisibilityEnum.Private);
|
|
|
|
break;
|
|
|
|
case 'direct':
|
|
|
|
this.setVisibility(VisibilityEnum.Direct);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-07 21:03:17 +02:00
|
|
|
private setVisibility(defaultPrivacy: VisibilityEnum) {
|
|
|
|
switch (defaultPrivacy) {
|
|
|
|
case VisibilityEnum.Public:
|
|
|
|
this.selectedPrivacy = 'Public';
|
|
|
|
break;
|
|
|
|
case VisibilityEnum.Unlisted:
|
|
|
|
this.selectedPrivacy = 'Unlisted';
|
|
|
|
break;
|
|
|
|
case VisibilityEnum.Private:
|
|
|
|
this.selectedPrivacy = 'Follows-only';
|
|
|
|
break;
|
|
|
|
case VisibilityEnum.Direct:
|
|
|
|
this.selectedPrivacy = 'DM';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-03-13 00:37:16 +01:00
|
|
|
|
2019-03-11 05:31:56 +01:00
|
|
|
private countStatusChar(status: string) {
|
2019-03-13 00:37:16 +01:00
|
|
|
this.mentionTooFarAwayError = false;
|
2019-03-09 05:53:04 +01:00
|
|
|
const parseStatus = this.parseStatus(status);
|
2019-03-13 00:37:16 +01:00
|
|
|
|
|
|
|
const mentions = this.getMentionsFromStatus(status);
|
2019-04-07 21:03:17 +02:00
|
|
|
if (mentions.length > 0) {
|
2019-03-13 00:37:16 +01:00
|
|
|
let containAllMention = true;
|
|
|
|
mentions.forEach(m => {
|
2019-04-07 21:03:17 +02:00
|
|
|
if (!parseStatus[0].includes(m)) {
|
2019-03-13 00:37:16 +01:00
|
|
|
containAllMention = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2019-04-07 21:03:17 +02:00
|
|
|
if (!containAllMention) {
|
2019-03-13 00:37:16 +01:00
|
|
|
this.mentionTooFarAwayError = true;
|
|
|
|
this.charCountLeft = this.maxCharLength - status.length;
|
|
|
|
this.postCounts = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-09 05:53:04 +01:00
|
|
|
const currentStatus = parseStatus[parseStatus.length - 1];
|
2019-03-13 00:02:27 +01:00
|
|
|
const statusExtraChars = this.getMentionExtraChars(status);
|
2019-03-09 05:53:04 +01:00
|
|
|
|
2019-03-13 00:02:27 +01:00
|
|
|
const statusLength = currentStatus.length - statusExtraChars;
|
2019-06-24 00:45:11 +02:00
|
|
|
this.charCountLeft = this.maxCharLength - statusLength - this.getCwLength();
|
2019-03-09 05:53:04 +01:00
|
|
|
this.postCounts = parseStatus.length;
|
2019-03-07 02:45:36 +01:00
|
|
|
}
|
|
|
|
|
2019-06-24 00:45:11 +02:00
|
|
|
private getCwLength(): number {
|
|
|
|
let cwLength = 0;
|
|
|
|
if (this.title) {
|
|
|
|
cwLength = this.title.length;
|
|
|
|
}
|
|
|
|
return cwLength;
|
|
|
|
}
|
|
|
|
|
2019-03-06 06:02:16 +01:00
|
|
|
private getMentions(status: Status, providerInfo: AccountInfo): string[] {
|
2019-03-06 04:46:50 +01:00
|
|
|
const mentions = [...status.mentions.map(x => x.acct), status.account.acct];
|
2019-03-06 05:00:06 +01:00
|
|
|
|
2019-03-06 04:46:50 +01:00
|
|
|
let uniqueMentions = [];
|
2019-03-06 06:02:16 +01:00
|
|
|
for (let mention of mentions) {
|
|
|
|
if (!uniqueMentions.includes(mention)) {
|
2019-03-06 04:46:50 +01:00
|
|
|
uniqueMentions.push(mention);
|
|
|
|
}
|
2019-03-06 05:00:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
let globalUniqueMentions = [];
|
2019-03-06 06:02:16 +01:00
|
|
|
for (let mention of uniqueMentions) {
|
|
|
|
if (!mention.includes('@')) {
|
2019-03-06 05:00:06 +01:00
|
|
|
mention += `@${providerInfo.instance}`;
|
|
|
|
}
|
|
|
|
globalUniqueMentions.push(mention);
|
|
|
|
}
|
|
|
|
|
2019-04-07 22:15:04 +02:00
|
|
|
const selectedUser = this.toolsService.getSelectedAccounts()[0];
|
|
|
|
globalUniqueMentions = globalUniqueMentions.filter(x => x.toLowerCase() !== `${selectedUser.username}@${selectedUser.instance}`.toLowerCase());
|
|
|
|
|
2019-03-06 05:00:06 +01:00
|
|
|
return globalUniqueMentions;
|
2019-03-06 04:46:50 +01:00
|
|
|
}
|
2019-03-11 05:31:56 +01:00
|
|
|
|
2019-03-09 05:30:50 +01:00
|
|
|
onCtrlEnter(): boolean {
|
|
|
|
this.onSubmit();
|
|
|
|
return false;
|
|
|
|
}
|
2019-03-06 04:46:50 +01:00
|
|
|
|
|
|
|
onSubmit(): boolean {
|
2019-03-13 00:37:16 +01:00
|
|
|
if (this.isSending || this.mentionTooFarAwayError) return false;
|
2019-03-06 05:37:58 +01:00
|
|
|
|
|
|
|
this.isSending = true;
|
|
|
|
|
2019-03-06 04:46:50 +01:00
|
|
|
let visibility: VisibilityEnum = VisibilityEnum.Unknown;
|
2019-04-07 21:03:17 +02:00
|
|
|
switch (this.selectedPrivacy) {
|
2019-03-06 04:46:50 +01:00
|
|
|
case 'Public':
|
|
|
|
visibility = VisibilityEnum.Public;
|
|
|
|
break;
|
|
|
|
case 'Unlisted':
|
|
|
|
visibility = VisibilityEnum.Unlisted;
|
|
|
|
break;
|
|
|
|
case 'Follows-only':
|
|
|
|
visibility = VisibilityEnum.Private;
|
|
|
|
break;
|
|
|
|
case 'DM':
|
|
|
|
visibility = VisibilityEnum.Direct;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-03-10 22:38:10 +01:00
|
|
|
const mediaAttachments = this.mediaService.mediaSubject.value.map(x => x.attachment);
|
|
|
|
|
2019-03-06 04:46:50 +01:00
|
|
|
const acc = this.toolsService.getSelectedAccounts()[0];
|
|
|
|
let usableStatus: Promise<Status>;
|
|
|
|
if (this.statusReplyingToWrapper) {
|
|
|
|
usableStatus = this.toolsService.getStatusUsableByAccount(acc, this.statusReplyingToWrapper);
|
|
|
|
} else {
|
|
|
|
usableStatus = Promise.resolve(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
usableStatus
|
|
|
|
.then((status: Status) => {
|
2019-03-10 22:38:10 +01:00
|
|
|
return this.sendStatus(acc, this.status, visibility, this.title, status, mediaAttachments);
|
2019-03-06 04:46:50 +01:00
|
|
|
})
|
2019-06-24 00:45:11 +02:00
|
|
|
.then((res: Status) => {
|
2019-03-06 04:46:50 +01:00
|
|
|
this.title = '';
|
|
|
|
this.status = '';
|
|
|
|
this.onClose.emit();
|
|
|
|
})
|
|
|
|
.catch((err: HttpErrorResponse) => {
|
|
|
|
this.notificationService.notifyHttpError(err);
|
2019-03-06 05:37:58 +01:00
|
|
|
})
|
|
|
|
.then(() => {
|
|
|
|
this.isSending = false;
|
2019-03-06 04:46:50 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-03-10 22:38:10 +01:00
|
|
|
private sendStatus(account: AccountInfo, status: string, visibility: VisibilityEnum, title: string, previousStatus: Status, attachments: Attachment[]): Promise<Status> {
|
2019-03-09 06:14:44 +01:00
|
|
|
let parsedStatus = this.parseStatus(status);
|
|
|
|
let resultPromise = Promise.resolve(previousStatus);
|
|
|
|
|
2019-03-11 05:31:56 +01:00
|
|
|
for (let i = 0; i < parsedStatus.length; i++) {
|
2019-03-10 22:38:10 +01:00
|
|
|
let s = parsedStatus[i];
|
2019-06-16 03:22:03 +02:00
|
|
|
resultPromise = resultPromise
|
|
|
|
.then((pStatus: Status) => {
|
|
|
|
let inReplyToId = null;
|
|
|
|
if (pStatus) {
|
|
|
|
inReplyToId = pStatus.id;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i === 0) {
|
|
|
|
return this.mastodonService.postNewStatus(account, s, visibility, title, inReplyToId, attachments.map(x => x.id))
|
|
|
|
.then((status: Status) => {
|
|
|
|
this.mediaService.clearMedia();
|
|
|
|
return status;
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return this.mastodonService.postNewStatus(account, s, visibility, title, inReplyToId, []);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.then((status: Status) => {
|
|
|
|
if (this.statusReplyingToWrapper) {
|
|
|
|
this.notificationService.newStatusPosted(this.statusReplyingToWrapper.status.id, new StatusWrapper(status, account));
|
|
|
|
}
|
2019-03-10 22:38:10 +01:00
|
|
|
|
2019-06-16 03:22:03 +02:00
|
|
|
return status;
|
|
|
|
});
|
2019-03-09 06:14:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return resultPromise;
|
|
|
|
}
|
2019-03-06 04:46:50 +01:00
|
|
|
|
2019-03-09 05:30:50 +01:00
|
|
|
private parseStatus(status: string): string[] {
|
2019-03-13 00:02:27 +01:00
|
|
|
let mentionExtraChars = this.getMentionExtraChars(status);
|
2019-03-09 05:30:50 +01:00
|
|
|
let trucatedStatus = `${status}`;
|
|
|
|
let results = [];
|
2019-03-13 00:02:27 +01:00
|
|
|
|
|
|
|
let aggregateMention = '';
|
|
|
|
let mentions = this.getMentionsFromStatus(status);
|
|
|
|
mentions.forEach(x => {
|
2019-04-07 21:03:17 +02:00
|
|
|
aggregateMention += `${x} `;
|
2019-03-13 00:02:27 +01:00
|
|
|
});
|
|
|
|
|
2019-06-24 00:45:11 +02:00
|
|
|
const currentMaxCharLength = this.maxCharLength + mentionExtraChars - this.getCwLength();
|
2019-03-13 00:02:27 +01:00
|
|
|
const maxChars = currentMaxCharLength - 6;
|
|
|
|
|
|
|
|
while (trucatedStatus.length > currentMaxCharLength) {
|
2019-03-09 05:30:50 +01:00
|
|
|
const nextIndex = trucatedStatus.lastIndexOf(' ', maxChars);
|
|
|
|
results.push(trucatedStatus.substr(0, nextIndex) + ' (...)');
|
2019-03-13 00:02:27 +01:00
|
|
|
trucatedStatus = aggregateMention + trucatedStatus.substr(nextIndex + 1);
|
2019-03-09 05:30:50 +01:00
|
|
|
}
|
|
|
|
results.push(trucatedStatus);
|
|
|
|
return results;
|
2019-03-06 04:46:50 +01:00
|
|
|
}
|
2019-03-13 00:02:27 +01:00
|
|
|
|
2019-04-07 21:03:17 +02:00
|
|
|
private getMentionExtraChars(status: string): number {
|
2019-03-13 00:02:27 +01:00
|
|
|
let mentionExtraChars = 0;
|
|
|
|
let mentions = this.getMentionsFromStatus(status);
|
|
|
|
|
|
|
|
for (const mention of mentions) {
|
|
|
|
if (mention.lastIndexOf('@') !== 0) {
|
|
|
|
const domain = mention.split('@')[2];
|
|
|
|
if (domain.length > 1) {
|
|
|
|
mentionExtraChars += (domain.length + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mentionExtraChars;
|
|
|
|
}
|
|
|
|
|
2019-04-07 21:03:17 +02:00
|
|
|
private getMentionsFromStatus(status: string): string[] {
|
2019-03-13 00:02:27 +01:00
|
|
|
return status.split(' ').filter(x => x.indexOf('@') === 0 && x.length > 1);
|
|
|
|
}
|
2019-03-06 04:46:50 +01:00
|
|
|
}
|