diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 591f2991..365672e7 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -90,6 +90,7 @@ import { TutorialEnhancedComponent } from './components/tutorial-enhanced/tutori import { NotificationsTutorialComponent } from './components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component'; import { LabelsTutorialComponent } from './components/tutorial-enhanced/labels-tutorial/labels-tutorial.component'; import { ThankyouTutorialComponent } from './components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component'; +import { StatusTranslateComponent } from './components/stream/status/status-translate/status-translate.component'; const routes: Routes = [ { path: "", component: StreamsMainDisplayComponent }, @@ -159,7 +160,8 @@ const routes: Routes = [ TutorialEnhancedComponent, NotificationsTutorialComponent, LabelsTutorialComponent, - ThankyouTutorialComponent + ThankyouTutorialComponent, + StatusTranslateComponent ], entryComponents: [ EmojiPickerComponent diff --git a/src/app/components/stream/status/status-translate/status-translate.component.html b/src/app/components/stream/status/status-translate/status-translate.component.html new file mode 100644 index 00000000..e5222fab --- /dev/null +++ b/src/app/components/stream/status/status-translate/status-translate.component.html @@ -0,0 +1,3 @@ +
+ Translate +
diff --git a/src/app/components/stream/status/status-translate/status-translate.component.scss b/src/app/components/stream/status/status-translate/status-translate.component.scss new file mode 100644 index 00000000..becab0f6 --- /dev/null +++ b/src/app/components/stream/status/status-translate/status-translate.component.scss @@ -0,0 +1,13 @@ +@import "variables"; +@import "commons"; + +.translation { + margin: 0 10px 0 $avatar-column-space; + text-align: center; + + &__link { + font-size: 12px; + color: #656b8f; + padding: 5px; + } +} \ No newline at end of file diff --git a/src/app/components/stream/status/status-translate/status-translate.component.spec.ts b/src/app/components/stream/status/status-translate/status-translate.component.spec.ts new file mode 100644 index 00000000..a90fa173 --- /dev/null +++ b/src/app/components/stream/status/status-translate/status-translate.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StatusTranslateComponent } from './status-translate.component'; + +describe('StatusTranslateComponent', () => { + let component: StatusTranslateComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StatusTranslateComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StatusTranslateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/stream/status/status-translate/status-translate.component.ts b/src/app/components/stream/status/status-translate/status-translate.component.ts new file mode 100644 index 00000000..8f528fa6 --- /dev/null +++ b/src/app/components/stream/status/status-translate/status-translate.component.ts @@ -0,0 +1,71 @@ +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs'; + +import { StatusWrapper } from '../../../../models/common.model'; +import { ILanguage } from '../../../../states/settings.state'; +import { LanguageService } from '../../../../services/language.service'; +import { InstancesInfoService } from '../../../../services/instances-info.service'; + +@Component({ + selector: 'app-status-translate', + templateUrl: './status-translate.component.html', + styleUrls: ['./status-translate.component.scss'] +}) +export class StatusTranslateComponent implements OnInit, OnDestroy { + + private languageSub: Subscription; + private languagesSub: Subscription; + + selectedLanguage: ILanguage; + configuredLanguages: ILanguage[] = []; + + isTranslationAvailable: boolean; + + @Input() status: StatusWrapper; + + constructor( + private readonly languageService: LanguageService, + private readonly instancesInfoService: InstancesInfoService, + ) { } + + ngOnInit() { + this.languageSub = this.languageService.selectedLanguageChanged.subscribe(l => { + if (l) { + this.selectedLanguage = l; + this.analyseAvailability(); + } + }); + + this.languagesSub = this.languageService.configuredLanguagesChanged.subscribe(l => { + if (l) { + this.configuredLanguages = l; + this.analyseAvailability(); + } + }); + } + + private analyseAvailability() { + this.instancesInfoService.getTranslationAvailability(this.status.provider) + .then(canTranslate => { + if (canTranslate + && this.configuredLanguages.length > 0 + && this.configuredLanguages.findIndex(x => x.iso639 === this.status.status.language) === -1) { + + console.warn('can translate'); + this.isTranslationAvailable = true; + } + else { + this.isTranslationAvailable = false; + } + }) + .catch(err => { + console.error(err); + this.isTranslationAvailable = false; + }); + } + + ngOnDestroy(): void { + if (this.languageSub) this.languageSub.unsubscribe(); + if (this.languagesSub) this.languagesSub.unsubscribe(); + } +} diff --git a/src/app/components/stream/status/status.component.html b/src/app/components/stream/status/status.component.html index be44235a..24fc2a32 100644 --- a/src/app/components/stream/status/status.component.html +++ b/src/app/components/stream/status/status.component.html @@ -102,6 +102,8 @@ (accountSelected)="accountSelected($event)" (hashtagSelected)="hashtagSelected($event)" (textSelected)="textSelected()"> + + diff --git a/src/app/components/stream/status/status.component.scss b/src/app/components/stream/status/status.component.scss index aa1796c5..9a5aad81 100644 --- a/src/app/components/stream/status/status.component.scss +++ b/src/app/components/stream/status/status.component.scss @@ -272,4 +272,4 @@ &__label{ color: $status-secondary-color; } -} +} \ No newline at end of file diff --git a/src/app/services/instances-info.service.ts b/src/app/services/instances-info.service.ts index 3d64fc5e..b4a2ece5 100644 --- a/src/app/services/instances-info.service.ts +++ b/src/app/services/instances-info.service.ts @@ -11,6 +11,7 @@ import { AccountInfo } from '../states/accounts.state'; export class InstancesInfoService { private defaultMaxChars = 500; private cachedMaxInstanceChar: { [id: string]: Promise; } = {}; + private cachedTranslationAvailability: { [id: string]: Promise; } = {}; private cachedDefaultPrivacy: { [id: string]: Promise; } = {}; constructor(private mastodonService: MastodonWrapperService) { } @@ -65,4 +66,30 @@ export class InstancesInfoService { } return this.cachedDefaultPrivacy[instance]; } + + getTranslationAvailability(account: AccountInfo): Promise { + const instance = account.instance; + if (!this.cachedTranslationAvailability[instance]) { + this.cachedTranslationAvailability[instance] = this.mastodonService.getInstance(instance) + .then((instance: Instance) => { + if (+instance.version.split('.')[0] >= 4) { + const instanceV2 = instance; + if (instanceV2 + && instanceV2.configuration + && instanceV2.configuration.translation) + return instanceV2.configuration.translation.enabled; + } else { + const instanceV1 = instance; + if (instanceV1 && instanceV1.max_toot_chars) + return false; + } + + return false; + }) + .catch(() => { + return false; + }); + } + return this.cachedTranslationAvailability[instance]; + } }