From 9803c06a23940ced8026f4f5a06fc8b2325dae8a Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Thu, 7 Mar 2019 00:31:06 -0500 Subject: [PATCH] added retrieval of chars limit from instances --- .../create-status/create-status.component.ts | 46 +++++++++++++++---- .../services/instances-info.service.spec.ts | 12 +++++ src/app/services/instances-info.service.ts | 31 +++++++++++++ src/app/services/mastodon.service.ts | 9 +++- .../services/models/mastodon.interfaces.ts | 4 ++ 5 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 src/app/services/instances-info.service.spec.ts create mode 100644 src/app/services/instances-info.service.ts diff --git a/src/app/components/create-status/create-status.component.ts b/src/app/components/create-status/create-status.component.ts index 6d615cc2..da4b23ac 100644 --- a/src/app/components/create-status/create-status.component.ts +++ b/src/app/components/create-status/create-status.component.ts @@ -1,5 +1,7 @@ -import { Component, OnInit, Input, Output, EventEmitter, ElementRef, ViewChild } from '@angular/core'; +import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, ElementRef, ViewChild } from '@angular/core'; import { HttpErrorResponse } from '@angular/common/http'; +import { Store } from '@ngxs/store'; +import { Subscription, Observable } from 'rxjs'; import { MastodonService, VisibilityEnum } from '../../services/mastodon.service'; import { Status } from '../../services/models/mastodon.interfaces'; @@ -7,13 +9,15 @@ import { ToolsService } from '../../services/tools.service'; import { NotificationService } from '../../services/notification.service'; import { StatusWrapper } from '../../models/common.model'; import { AccountInfo } from '../../states/accounts.state'; +import { InstancesInfoService } from '../../services/instances-info.service'; + @Component({ selector: 'app-create-status', templateUrl: './create-status.component.html', styleUrls: ['./create-status.component.scss'] }) -export class CreateStatusComponent implements OnInit { +export class CreateStatusComponent implements OnInit, OnDestroy { title: string; private _status: string = ''; @@ -25,7 +29,8 @@ export class CreateStatusComponent implements OnInit { return this._status; } - charCountLeft: number = 500; + private maxCharLength: number; + charCountLeft: number; postCounts: number = 1; isSending: boolean; @@ -39,13 +44,23 @@ export class CreateStatusComponent implements OnInit { selectedPrivacy = 'Public'; privacyList: string[] = ['Public', 'Unlisted', 'Follows-only', 'DM']; + private accounts$: Observable; + private accountSub: Subscription; + constructor( - // private readonly store: Store, + private readonly store: Store, private readonly notificationService: NotificationService, private readonly toolsService: ToolsService, - private readonly mastodonService: MastodonService) { } + private readonly mastodonService: MastodonService, + private readonly instancesInfoService: InstancesInfoService) { + this.accounts$ = this.store.select(state => state.registeredaccounts.accounts); + } ngOnInit() { + this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => { + this.accountChanged(accounts); + }); + if (this.statusReplyingToWrapper) { if (this.statusReplyingToWrapper.status.reblog) { this.statusReplyingTo = this.statusReplyingToWrapper.status.reblog; @@ -66,12 +81,25 @@ export class CreateStatusComponent implements OnInit { }, 0); } + ngOnDestroy(){ + this.accountSub.unsubscribe(); + } + + 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); + }); + } + private countStatusChar(status: string){ - const maxLength = 500; + // const maxLength = 500; const statusLength = status.length; - const mod = statusLength % maxLength; - this.charCountLeft = maxLength - mod; - this.postCounts = Math.trunc(statusLength/maxLength) + 1; + const mod = statusLength % this.maxCharLength; + this.charCountLeft = this.maxCharLength - mod; + this.postCounts = Math.trunc(statusLength/this.maxCharLength) + 1; } private getMentions(status: Status, providerInfo: AccountInfo): string[] { diff --git a/src/app/services/instances-info.service.spec.ts b/src/app/services/instances-info.service.spec.ts new file mode 100644 index 00000000..00f6929a --- /dev/null +++ b/src/app/services/instances-info.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { InstancesInfoService } from './instances-info.service'; + +xdescribe('InstancesInfoService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: InstancesInfoService = TestBed.get(InstancesInfoService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/instances-info.service.ts b/src/app/services/instances-info.service.ts new file mode 100644 index 00000000..c59331d3 --- /dev/null +++ b/src/app/services/instances-info.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; + +import { MastodonService } from './mastodon.service'; +import { Instance } from './models/mastodon.interfaces'; + +@Injectable({ + providedIn: 'root' +}) +export class InstancesInfoService { + private defaultMaxChars = 500; + private cachedMaxInstanceChar: { [id: string] : Promise; } = {}; + + constructor(private mastodonService: MastodonService) { } + + getMaxStatusChars(instance:string): Promise { + if(!this.cachedMaxInstanceChar[instance]){ + this.cachedMaxInstanceChar[instance] = this.mastodonService.getInstance(instance) + .then((instance: Instance)=>{ + if(instance.max_toot_chars){ + return instance.max_toot_chars; + } else { + return this.defaultMaxChars; + } + }) + .catch(() => { + return this.defaultMaxChars; + }); + } + return this.cachedMaxInstanceChar[instance]; + } +} diff --git a/src/app/services/mastodon.service.ts b/src/app/services/mastodon.service.ts index 55aecab2..8d131d93 100644 --- a/src/app/services/mastodon.service.ts +++ b/src/app/services/mastodon.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { HttpHeaders, HttpClient } from '@angular/common/http'; import { ApiRoutes } from './models/api.settings'; -import { Account, Status, Results, Context, Relationship } from "./models/mastodon.interfaces"; +import { Account, Status, Results, Context, Relationship, Instance } from "./models/mastodon.interfaces"; import { AccountInfo } from '../states/accounts.state'; import { StreamTypeEnum } from '../states/streams.state'; @@ -12,6 +12,11 @@ export class MastodonService { constructor(private readonly httpClient: HttpClient) { } + getInstance(instance: string): Promise{ + const route = `https://${instance}${this.apiRoutes.getInstance}`; + return this.httpClient.get(route).toPromise(); + } + retrieveAccountDetails(account: AccountInfo): Promise { const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` }); return this.httpClient.get('https://' + account.instance + this.apiRoutes.getCurrentAccount, { headers: headers }).toPromise(); @@ -20,7 +25,7 @@ export class MastodonService { getTimeline(account: AccountInfo, type: StreamTypeEnum, max_id: string = null, since_id: string = null, limit: number = 20, tag: string = null, list: string = null): Promise { const route = `https://${account.instance}${this.getTimelineRoute(type, max_id, since_id, limit, tag, list)}`; const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` }); - return this.httpClient.get(route, { headers: headers }).toPromise() + return this.httpClient.get(route, { headers: headers }).toPromise(); } private getTimelineRoute(type: StreamTypeEnum, max_id: string, since_id: string, limit: number, tag: string, list: string): string { diff --git a/src/app/services/models/mastodon.interfaces.ts b/src/app/services/models/mastodon.interfaces.ts index e37d6ac7..deb3d3a4 100644 --- a/src/app/services/models/mastodon.interfaces.ts +++ b/src/app/services/models/mastodon.interfaces.ts @@ -84,6 +84,10 @@ export interface Instance { title: string; description: string; email: string; + version: string; + urls: string[]; + contact_account: Account; + max_toot_chars: number; } export interface Mention {