From 5cdca202f89c44fd62cdf7f1962b5d5556a7fafc Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Tue, 12 Mar 2019 19:02:27 -0400 Subject: [PATCH] added mention replication in multiposting #58 --- .../create-status.component.spec.ts | 41 +++++++- .../create-status/create-status.component.ts | 98 ++++++++++++------- 2 files changed, 105 insertions(+), 34 deletions(-) diff --git a/src/app/components/create-status/create-status.component.spec.ts b/src/app/components/create-status/create-status.component.spec.ts index ff43cb37..83364105 100644 --- a/src/app/components/create-status/create-status.component.spec.ts +++ b/src/app/components/create-status/create-status.component.spec.ts @@ -12,7 +12,7 @@ import { StreamsState } from '../../states/streams.state'; import { NavigationService } from '../../services/navigation.service'; import { NotificationService } from '../../services/notification.service'; import { MastodonService } from '../../services/mastodon.service'; -import { restoreView } from '@angular/core/src/render3'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; describe('CreateStatusComponent', () => { let component: CreateStatusComponent; @@ -33,6 +33,7 @@ describe('CreateStatusComponent', () => { ]), ], providers: [NavigationService, NotificationService, MastodonService], + schemas: [ CUSTOM_ELEMENTS_SCHEMA ] }).compileComponents(); })); @@ -93,4 +94,42 @@ describe('CreateStatusComponent', () => { expect(result[1].length).toBeLessThanOrEqual(500); expect(result[2].length).toBeLessThanOrEqual(500); }); + + it('should not count domain length when replying', () => { + const status = '@Lorem@ipsum.com ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed ante id dolor vulputate pulvinar sit amet a nisl. Duis sagittis nisl sit amet est rhoncus rutrum. Duis aliquet eget erat nec molestie. Fusce bibendum consectetur rhoncus. Aenean vel neque ac diam hendrerit interdum id a nisl. Aenean leo ante, luctus eget erat at, interdum tincidunt turpis. Donec non efficitur magna. Nam placerat convallis tincidunt. Etiam ac scelerisque velit, at vestibulum turpis. In hac habitasse platea dictu'; + (component).maxCharLength = 500; + const result = (component).parseStatus(status); + expect(result.length).toBe(1); + }); + + it('should not count domain length when replying', () => { + const status = '@Lorem@ipsum.com @1orem@ipsum.com ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed ante id dolor vulputate pulvinar sit amet a nisl. Duis sagittis nisl sit amet est rhoncus rutrum. Duis aliquet eget erat nec molestie. Fusce bibendum consectetur rhoncus. Aenean vel neque ac diam hendrerit interdum id a nisl. Aenean leo ante, luctus eget erat at, interdum tincidunt turpis. Donec non efficitur magna. Nam placerat convallis tincidunt. Etiam ac scelerisque velit, at vestibulum turpis. In hac habitasse plate'; + (component).maxCharLength = 500; + const result = (component).parseStatus(status); + expect(result.length).toBe(1); + }); + + it('should add alias in multiposting replies', () => { + const status = '@Lorem@ipsum.com ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed ante id dolor vulputate pulvinar sit amet a nisl. Duis sagittis nisl sit amet est rhoncus rutrum. Duis aliquet eget erat nec molestie. Fusce bibendum consectetur rhoncus. Aenean vel neque ac diam hendrerit interdum id a nisl. Aenean leo ante, luctus eget erat at, interdum tincidunt turpis. Donec non efficitur magna. Nam placerat convallis tincidunt. Etiam ac scelerisque velit, at vestibulum turpis. In hac habitasse platea dictu0'; + (component).maxCharLength = 500; + const result = (component).parseStatus(status); + expect(result.length).toBe(2); + expect(result[0].length).toBeLessThanOrEqual(510); + expect(result[1].length).toBeLessThanOrEqual(510); + expect(result[0]).toContain('@Lorem@ipsum.com '); + expect(result[1]).toContain('@Lorem@ipsum.com '); + }); + + it('should add alias in multiposting replies', () => { + const status = '@Lorem@ipsum.com @48756@987586.ipsum.com ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed ante id dolor vulputate pulvinar sit amet a nisl. Duis sagittis nisl sit amet est rhoncus rutrum. Duis aliquet eget erat nec molestie. Fusce bibendum consectetur rhoncus. Aenean vel neque ac diam hendrerit interdum id a nisl. Aenean leo ante, luctus eget erat at, interdum tincidunt turpis. Donec non efficitur magna. Nam placerat convallis tincidunt. Etiam ac scelerisque velit, at vestibulum turpis. In hac habitasse platea dictu0'; + (component).maxCharLength = 500; + const result = (component).parseStatus(status); + expect(result.length).toBe(2); + expect(result[0].length).toBeLessThanOrEqual(527); + expect(result[1].length).toBeLessThanOrEqual(527); + expect(result[0]).toContain('@Lorem@ipsum.com '); + expect(result[1]).toContain('@Lorem@ipsum.com '); + console.warn(result); + }); + }); \ No newline at end of file diff --git a/src/app/components/create-status/create-status.component.ts b/src/app/components/create-status/create-status.component.ts index b94f3d41..e4a4f178 100644 --- a/src/app/components/create-status/create-status.component.ts +++ b/src/app/components/create-status/create-status.component.ts @@ -88,43 +88,46 @@ export class CreateStatusComponent implements OnInit, OnDestroy { } private accountChanged(accounts: AccountInfo[]): void { - const selectedAccount = accounts.filter(x => x.isSelected)[0]; - this.instancesInfoService.getMaxStatusChars(selectedAccount.instance) - .then((maxChars: number) => { - this.maxCharLength = maxChars; - this.countStatusChar(this.status); - }) - .catch((err: HttpErrorResponse) => { - this.notificationService.notifyHttpError(err); - }); + if (accounts && accounts.length > 0) { + const selectedAccount = accounts.filter(x => x.isSelected)[0]; + this.instancesInfoService.getMaxStatusChars(selectedAccount.instance) + .then((maxChars: number) => { + this.maxCharLength = maxChars; + this.countStatusChar(this.status); + }) + .catch((err: HttpErrorResponse) => { + this.notificationService.notifyHttpError(err); + }); - this.instancesInfoService.getDefaultPrivacy(selectedAccount) - .then((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; - } - }) - .catch((err: HttpErrorResponse) => { - this.notificationService.notifyHttpError(err); - }); + this.instancesInfoService.getDefaultPrivacy(selectedAccount) + .then((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; + } + }) + .catch((err: HttpErrorResponse) => { + this.notificationService.notifyHttpError(err); + }); + } } private countStatusChar(status: string) { const parseStatus = this.parseStatus(status); const currentStatus = parseStatus[parseStatus.length - 1]; + const statusExtraChars = this.getMentionExtraChars(status); - const statusLength = currentStatus.length; + const statusLength = currentStatus.length - statusExtraChars; this.charCountLeft = this.maxCharLength - statusLength; this.postCounts = parseStatus.length; } @@ -233,15 +236,44 @@ export class CreateStatusComponent implements OnInit, OnDestroy { } private parseStatus(status: string): string[] { + let mentionExtraChars = this.getMentionExtraChars(status); let trucatedStatus = `${status}`; let results = []; - const maxChars = this.maxCharLength - 6; - while (trucatedStatus.length > this.maxCharLength) { + + let aggregateMention = ''; + let mentions = this.getMentionsFromStatus(status); + mentions.forEach(x => { + aggregateMention += `${x} `; + }); + + const currentMaxCharLength = this.maxCharLength + mentionExtraChars; + const maxChars = currentMaxCharLength - 6; + + while (trucatedStatus.length > currentMaxCharLength) { const nextIndex = trucatedStatus.lastIndexOf(' ', maxChars); results.push(trucatedStatus.substr(0, nextIndex) + ' (...)'); - trucatedStatus = trucatedStatus.substr(nextIndex + 1); + trucatedStatus = aggregateMention + trucatedStatus.substr(nextIndex + 1); } results.push(trucatedStatus); return results; } + + private getMentionExtraChars(status: string): number{ + 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; + } + + private getMentionsFromStatus(status: string): string[]{ + return status.split(' ').filter(x => x.indexOf('@') === 0 && x.length > 1); + } }