import { Component , NgZone } from '@angular/core' ; import { Router } from '@angular/router' ; import { ElectronService } from 'ngx-electron' ; import { DictionaryItem } from '@app/models/dictionary-item' ; import { Language } from '@app/models/language' ; import { StorageService } from '@app/services/storage.service' ; import { ThemeService } from '@app/services/theme.service' ; import { updateConfig } from '@app/store/actions/config.actions' ; import * as fromConfig from '@app/store/reducers' ; import { ConfigState , LanguageMode } from '@app/store/reducers/config.reducer' ; import { Translation } from '@models/translation' ; import { UntilDestroy , untilDestroyed } from '@ngneat/until-destroy' ; import { select , Store } from '@ngrx/store' ; import { TranslateService } from '@services/translate.service' ; import { of , Subject , throwError } from 'rxjs' ; import { catchError , debounceTime , delay , distinctUntilChanged , flatMap , map } from 'rxjs/operators' ; @ UntilDestroy ( ) @ Component ( { templateUrl : 'main.component.html' , styleUrls : [ 'main.component.scss' ] , } ) export class MainComponent { /** Translated word/phrase/sentence */ translation : Translation ; /** List of languages for 'translate from' dropdown */ languageListFrom : Language [ ] = [ ] ; /** List of languages for 'translate to' dropdown */ languageListTo : Language [ ] = [ ] ; /** List with vocabularies */ vocabulary : DictionaryItem [ ] ; /** Entered text to translate */ enteredText = '' ; /** Update flag */ updateAvailable = false ; /** Label with detected language */ detectedLanguage = '' ; /** Favorite flag */ isFavorited = false ; /** Menu flag */ showMoreMenu = false ; /** Key up listener */ keyUp = new Subject < string > ( ) ; /** Application config object */ appConfig : ConfigState ; param translateService param storageService param router param electronService param ngZone param themeService param store constructor ( private translateService , private storageService , private router , private electronService , private ngZone , private themeService , private store ) { if ( electronService . remote ) { this . setIpcListeners ( ) ; } this . store . pipe ( select ( fromConfig . getConfig ) , untilDestroyed ( this ) ) . subscribe ( config => { this . appConfig = config ; if ( config . apiKey === '' || config . apiKey === null ) { this . router . navigate ( [ '/settings' ] ) ; } else { this . handleLanguageSettings ( this . appConfig . languageMode ) ; } } ) ; this . themeService . enableActiveTheme ( ) ; this . registerKeyUpShortcut ( ) ; } /**
     * Registers a keyboard key up shortcut to trigger translation after some delay
     */ registerKeyUpShortcut ( ) { this . keyUp . pipe ( map ( ( event ) => event . target . value ) , debounceTime ( 250 ) , distinctUntilChanged ( ) , flatMap ( search => of ( search ) . pipe ( delay ( 500 ) ) ) , catchError ( err => throwError ( err ) ) , untilDestroyed ( this ) ) . subscribe ( ( text ) => this . translate ( text , this . appConfig . fromLang . key , this . appConfig . toLang . key ) ) ; } /**
     * Sets listeners for events from electrons main process
     */ setIpcListeners ( ) { this . electronService . ipcRenderer . on ( 'open-dictionary' , ( ) => { this . ngZone . run ( ( ) => { this . router . navigate ( [ '/dictionary' ] ) ; } ) ; } ) ; this . electronService . ipcRenderer . on ( 'translate-clipboard' , ( ) => { this . ngZone . run ( ( ) => { this . router . navigate ( [ '/home' ] ) ; const clipboardText = this . electronService . clipboard . readText ( ) ; this . enteredText = clipboardText ; this . translate ( this . enteredText , this . appConfig . fromLang . key , this . appConfig . toLang . key ) ; } ) ; } ) ; this . electronService . ipcRenderer . on ( 'translate' , ( ) => { this . ngZone . run ( ( ) => { this . router . navigate ( [ '/home' ] ) ; this . enteredText = '' ; if ( this . translation ) { this . translation = null ; } } ) ; } ) ; this . electronService . ipcRenderer . on ( 'update-available' , ( ) => { this . ngZone . run ( ( ) => { this . updateAvailable = true ; } ) ; } ) ; this . electronService . ipcRenderer . on ( 'show-settings' , ( ) => { this . ngZone . run ( ( ) => { this . router . navigate ( [ '/settings' ] ) ; } ) ; } ) ; } /**
     * Changes translation direction
     */ changeTranslationDir ( ) { this . onLanguageChange ( 'fromLang' , this . appConfig . toLang ) ; this . onLanguageChange ( 'toLang' , this . appConfig . fromLang ) ; } param langDirection param value onLanguageChange ( langDirection , value ) { this . store . dispatch ( updateConfig ( { config : { [ langDirection ] : value } } ) ) ; this . translate ( this . enteredText , this . appConfig . fromLang . key , this . appConfig . toLang . key ) ; } param word translate ( word , fromLang , toLang ) { const temp = word . replace ( /\n/g , ' ' ) ; if ( ! /^ *$/ . test ( temp ) ) { if ( fromLang === 'ad' ) { this . translateService . detectLanguage ( word , fromLang ) . pipe ( untilDestroyed ( this ) , catchError ( err => throwError ( err ) ) ) . subscribe ( ( language ) => { this . translate ( word , language , toLang ) ; this . detectedLanguage = ' (' + language + ' -> ' + toLang + ')' ; } , error => console . error ( `Error:  ${ error }` ) ) ; } else { if ( this . appConfig . fromLang . key !== 'ad' ) { this . detectedLanguage = '' ; } this . translateService . getTranslation ( word , fromLang , toLang ) . pipe ( untilDestroyed ( this ) , catchError ( err => throwError ( err ) ) ) . subscribe ( ( translation ) => { this . translation = translation ; this . translation . $text += this . detectedLanguage ; this . isFavorited = false ; } ) ; } } else { this . translation = null ; } } /**
     * Save entry to the dictionary
     */ saveToDictionary ( ) { this . vocabulary = this . storageService . getVocabulary ( ) ; const dictItem = new DictionaryItem ( this . enteredText , this . translation . $text , this . appConfig . fromLang , this . appConfig . toLang ) ; this . vocabulary . push ( dictItem ) ; this . isFavorited = true ; this . storageService . updateVocabulary ( this . vocabulary ) ; this . storageService . dictionaryChange . next ( 'updated' ) ; } param languageMode handleLanguageSettings ( languageMode ) { if ( languageMode === 'preferred-languages' ) { this . setLanguages ( this . appConfig . preferredLanguages ) ; } else { this . requestLanguageList ( ) ; } } /**
     * Get list with all available languages from the API
     */ requestLanguageList ( ) { this . translateService . getLanguagesList ( ) . pipe ( untilDestroyed ( this ) , catchError ( err => throwError ( err ) ) ) . subscribe ( response => this . setLanguages ( response ) ) ; } param languageList setLanguages ( languageList ) { this . languageListFrom = [ ... languageList ] ; this . languageListTo = [ ... languageList ] ; this . languageListFrom . unshift ( new Language ( 'ad' , 'Auto-detect' ) ) ; } param url openUrl ( url ) { this . electronService . shell . openExternal ( url ) ; } /**
     * Opens dictionary window
     */ showDictionary ( ) { if ( this . electronService . remote ) { this . electronService . ipcRenderer . send ( 'openDictionary' ) ; this . hideMenu ( ) ; } else { this . router . navigate ( [ 'dictionary' ] ) ; } } /**
     * Closes the application
     */ closeApp ( ) { this . electronService . remote . app . quit ( ) ; } /**
     * Closes more menu
     */ hideMenu ( ) { this . showMoreMenu = false ; } }