index.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import { NgModule, ModuleWithProviders, LOCALE_ID } from '@angular/core'
  2. import { BrowserModule } from '@angular/platform-browser'
  3. import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
  4. import { FormsModule } from '@angular/forms'
  5. import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
  6. import { PerfectScrollbarModule, PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar'
  7. import { NgxFilesizeModule } from 'ngx-filesize'
  8. import { SortablejsModule } from 'ngx-sortablejs'
  9. import { DragDropModule } from '@angular/cdk/drag-drop'
  10. import { TranslateModule, TranslateCompiler, TranslateService } from '@ngx-translate/core'
  11. import { TranslateMessageFormatCompiler, MESSAGE_FORMAT_CONFIG } from 'ngx-translate-messageformat-compiler'
  12. import { AppRootComponent } from './components/appRoot.component'
  13. import { CheckboxComponent } from './components/checkbox.component'
  14. import { TabBodyComponent } from './components/tabBody.component'
  15. import { PromptModalComponent } from './components/promptModal.component'
  16. import { SafeModeModalComponent } from './components/safeModeModal.component'
  17. import { StartPageComponent } from './components/startPage.component'
  18. import { TabHeaderComponent } from './components/tabHeader.component'
  19. import { TitleBarComponent } from './components/titleBar.component'
  20. import { ToggleComponent } from './components/toggle.component'
  21. import { WindowControlsComponent } from './components/windowControls.component'
  22. import { RenameTabModalComponent } from './components/renameTabModal.component'
  23. import { SelectorModalComponent } from './components/selectorModal.component'
  24. import { SplitTabComponent, SplitTabRecoveryProvider } from './components/splitTab.component'
  25. import { SplitTabSpannerComponent } from './components/splitTabSpanner.component'
  26. import { SplitTabDropZoneComponent } from './components/splitTabDropZone.component'
  27. import { SplitTabPaneLabelComponent } from './components/splitTabPaneLabel.component'
  28. import { UnlockVaultModalComponent } from './components/unlockVaultModal.component'
  29. import { WelcomeTabComponent } from './components/welcomeTab.component'
  30. import { TransfersMenuComponent } from './components/transfersMenu.component'
  31. import { AutofocusDirective } from './directives/autofocus.directive'
  32. import { AlwaysVisibleTypeaheadDirective } from './directives/alwaysVisibleTypeahead.directive'
  33. import { FastHtmlBindDirective } from './directives/fastHtmlBind.directive'
  34. import { DropZoneDirective } from './directives/dropZone.directive'
  35. import { CdkAutoDropGroup } from './directives/cdkAutoDropGroup.directive'
  36. import { Theme, CLIHandler, TabContextMenuItemProvider, TabRecoveryProvider, HotkeyProvider, ConfigProvider, PlatformService, FileProvider, ToolbarButtonProvider, ProfilesService, ProfileProvider, SelectorOption, Profile, SelectorService } from './api'
  37. import { AppService } from './services/app.service'
  38. import { ConfigService } from './services/config.service'
  39. import { VaultFileProvider } from './services/vault.service'
  40. import { HotkeysService } from './services/hotkeys.service'
  41. import { LocaleService, TranslateServiceWrapper } from './services/locale.service'
  42. import { StandardTheme, StandardCompactTheme, PaperTheme } from './theme'
  43. import { CoreConfigProvider } from './config'
  44. import { AppHotkeyProvider } from './hotkeys'
  45. import { TaskCompletionContextMenu, CommonOptionsContextMenu, TabManagementContextMenu, ProfilesContextMenu } from './tabContextMenu'
  46. import { LastCLIHandler, ProfileCLIHandler } from './cli'
  47. import { ButtonProvider } from './buttonProvider'
  48. import { SplitLayoutProfilesService } from './profiles'
  49. import 'perfect-scrollbar/css/perfect-scrollbar.css'
  50. export function TranslateMessageFormatCompilerFactory (): TranslateMessageFormatCompiler {
  51. return new TranslateMessageFormatCompiler()
  52. }
  53. const PROVIDERS = [
  54. { provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
  55. { provide: Theme, useClass: StandardTheme, multi: true },
  56. { provide: Theme, useClass: StandardCompactTheme, multi: true },
  57. { provide: Theme, useClass: PaperTheme, multi: true },
  58. { provide: ConfigProvider, useClass: CoreConfigProvider, multi: true },
  59. { provide: TabContextMenuItemProvider, useClass: CommonOptionsContextMenu, multi: true },
  60. { provide: TabContextMenuItemProvider, useClass: TabManagementContextMenu, multi: true },
  61. { provide: TabContextMenuItemProvider, useClass: TaskCompletionContextMenu, multi: true },
  62. { provide: TabContextMenuItemProvider, useClass: ProfilesContextMenu, multi: true },
  63. { provide: TabRecoveryProvider, useExisting: SplitTabRecoveryProvider, multi: true },
  64. { provide: CLIHandler, useClass: ProfileCLIHandler, multi: true },
  65. { provide: CLIHandler, useClass: LastCLIHandler, multi: true },
  66. { provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } },
  67. { provide: FileProvider, useClass: VaultFileProvider, multi: true },
  68. { provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
  69. { provide: ProfileProvider, useExisting: SplitLayoutProfilesService, multi: true },
  70. {
  71. provide: LOCALE_ID,
  72. deps: [LocaleService],
  73. useFactory: locale => locale.getLocale(),
  74. },
  75. {
  76. provide: MESSAGE_FORMAT_CONFIG,
  77. useValue: LocaleService.allLocales,
  78. },
  79. {
  80. provide: TranslateService,
  81. useClass: TranslateServiceWrapper,
  82. },
  83. ]
  84. /** @hidden */
  85. @NgModule({
  86. imports: [
  87. BrowserModule,
  88. BrowserAnimationsModule,
  89. FormsModule,
  90. NgbModule,
  91. NgxFilesizeModule,
  92. PerfectScrollbarModule,
  93. DragDropModule,
  94. SortablejsModule.forRoot({ animation: 150 }),
  95. TranslateModule,
  96. ],
  97. declarations: [
  98. AppRootComponent,
  99. CheckboxComponent,
  100. PromptModalComponent,
  101. StartPageComponent,
  102. TabBodyComponent,
  103. TabHeaderComponent,
  104. TitleBarComponent,
  105. ToggleComponent,
  106. WindowControlsComponent,
  107. RenameTabModalComponent,
  108. SafeModeModalComponent,
  109. AutofocusDirective,
  110. FastHtmlBindDirective,
  111. AlwaysVisibleTypeaheadDirective,
  112. SelectorModalComponent,
  113. SplitTabComponent,
  114. SplitTabSpannerComponent,
  115. SplitTabDropZoneComponent,
  116. SplitTabPaneLabelComponent,
  117. UnlockVaultModalComponent,
  118. WelcomeTabComponent,
  119. TransfersMenuComponent,
  120. DropZoneDirective,
  121. CdkAutoDropGroup,
  122. ],
  123. entryComponents: [
  124. PromptModalComponent,
  125. RenameTabModalComponent,
  126. SafeModeModalComponent,
  127. SelectorModalComponent,
  128. SplitTabComponent,
  129. UnlockVaultModalComponent,
  130. WelcomeTabComponent,
  131. ],
  132. exports: [
  133. CheckboxComponent,
  134. ToggleComponent,
  135. PromptModalComponent,
  136. AutofocusDirective,
  137. DropZoneDirective,
  138. FastHtmlBindDirective,
  139. AlwaysVisibleTypeaheadDirective,
  140. SortablejsModule,
  141. DragDropModule,
  142. TranslateModule,
  143. ],
  144. })
  145. export default class AppModule { // eslint-disable-line @typescript-eslint/no-extraneous-class
  146. constructor (
  147. app: AppService,
  148. config: ConfigService,
  149. platform: PlatformService,
  150. hotkeys: HotkeysService,
  151. private profilesService: ProfilesService,
  152. private selector: SelectorService,
  153. ) {
  154. app.ready$.subscribe(() => {
  155. config.ready$.toPromise().then(() => {
  156. if (config.store.enableWelcomeTab) {
  157. app.openNewTabRaw({ type: WelcomeTabComponent })
  158. }
  159. })
  160. })
  161. platform.setErrorHandler(err => {
  162. console.error('Unhandled exception:', err)
  163. })
  164. hotkeys.hotkey$.subscribe(async (hotkey) => {
  165. if (hotkey.startsWith('profile.')) {
  166. const id = hotkey.substring(hotkey.indexOf('.') + 1)
  167. const profiles = await profilesService.getProfiles()
  168. const profile = profiles.find(x => AppHotkeyProvider.getProfileHotkeyName(x) === id)
  169. if (profile) {
  170. profilesService.openNewTabForProfile(profile)
  171. }
  172. }
  173. if (hotkey.startsWith('profile-selectors.')) {
  174. const id = hotkey.substring(hotkey.indexOf('.') + 1)
  175. const provider = profilesService.getProviders().find(x => x.id === id)
  176. if (!provider) {
  177. return
  178. }
  179. this.showSelector(provider)
  180. }
  181. })
  182. }
  183. async showSelector (provider: ProfileProvider<Profile>): Promise<void> {
  184. let profiles = await this.profilesService.getProfiles()
  185. profiles = profiles.filter(x => !x.isTemplate && x.type === provider.id)
  186. const options: SelectorOption<void>[] = profiles.map(p => ({
  187. ...this.profilesService.selectorOptionForProfile(p),
  188. callback: () => this.profilesService.openNewTabForProfile(p),
  189. }))
  190. if (provider.supportsQuickConnect) {
  191. options.push({
  192. name: 'Quick connect',
  193. freeInputPattern: 'Connect to "%s"...',
  194. icon: 'fas fa-arrow-right',
  195. callback: query => {
  196. const p = provider.quickConnect(query)
  197. if (p) {
  198. this.profilesService.openNewTabForProfile(p)
  199. }
  200. },
  201. })
  202. }
  203. await this.selector.show('Select profile', options)
  204. }
  205. static forRoot (): ModuleWithProviders<AppModule> {
  206. const translateModule = TranslateModule.forRoot({
  207. defaultLanguage: 'en',
  208. compiler: {
  209. provide: TranslateCompiler,
  210. useFactory: TranslateMessageFormatCompilerFactory,
  211. },
  212. })
  213. return {
  214. ngModule: AppModule,
  215. providers: [
  216. ...PROVIDERS,
  217. ...translateModule.providers!.filter(x => x !== TranslateService),
  218. ],
  219. }
  220. }
  221. }
  222. export { AppRootComponent as bootstrap }
  223. export * from './api'
  224. // Deprecations
  225. export { ToolbarButton as IToolbarButton } from './api'
  226. export { HotkeyDescription as IHotkeyDescription } from './api'