tabHeader.component.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
  2. import { Component, Input, Optional, Inject, HostBinding, HostListener, NgZone } from '@angular/core'
  3. import { auditTime } from 'rxjs'
  4. import { TabContextMenuItemProvider } from '../api/tabContextMenuProvider'
  5. import { BaseTabComponent } from './baseTab.component'
  6. import { SplitTabComponent } from './splitTab.component'
  7. import { HotkeysService } from '../services/hotkeys.service'
  8. import { AppService } from '../services/app.service'
  9. import { HostAppService, Platform } from '../api/hostApp'
  10. import { ConfigService } from '../services/config.service'
  11. import { BaseComponent } from './base.component'
  12. import { MenuItemOptions } from '../api/menu'
  13. import { PlatformService } from '../api/platform'
  14. /** @hidden */
  15. @Component({
  16. selector: 'tab-header',
  17. templateUrl:'./tabHeader.component.pug',
  18. styleUrls: ['./tabHeader.component.scss'],
  19. })
  20. export class TabHeaderComponent extends BaseComponent {
  21. @Input() index: number
  22. @Input() @HostBinding('class.active') active: boolean
  23. @Input() tab: BaseTabComponent
  24. @Input() progress: number|null
  25. Platform = Platform
  26. constructor (
  27. public app: AppService,
  28. public config: ConfigService,
  29. public hostApp: HostAppService,
  30. private hotkeys: HotkeysService,
  31. private platform: PlatformService,
  32. private zone: NgZone,
  33. @Optional() @Inject(TabContextMenuItemProvider) protected contextMenuProviders: TabContextMenuItemProvider[],
  34. ) {
  35. super()
  36. this.subscribeUntilDestroyed(this.hotkeys.hotkey$, (hotkey) => {
  37. if (this.app.activeTab === this.tab) {
  38. if (hotkey === 'rename-tab') {
  39. this.app.renameTab(this.tab)
  40. }
  41. }
  42. })
  43. this.contextMenuProviders.sort((a, b) => a.weight - b.weight)
  44. }
  45. ngOnInit () {
  46. this.subscribeUntilDestroyed(this.tab.progress$.pipe(
  47. auditTime(300),
  48. ), progress => {
  49. this.zone.run(() => {
  50. this.progress = progress
  51. })
  52. })
  53. }
  54. async buildContextMenu (): Promise<MenuItemOptions[]> {
  55. let items: MenuItemOptions[] = []
  56. // Top-level tab menu
  57. for (const section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(this.tab, true)))) {
  58. items.push({ type: 'separator' })
  59. items = items.concat(section)
  60. }
  61. if (this.tab instanceof SplitTabComponent) {
  62. const tab = this.tab.getFocusedTab()
  63. if (tab) {
  64. for (let section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(tab, true)))) {
  65. // eslint-disable-next-line @typescript-eslint/no-loop-func
  66. section = section.filter(item => !items.some(ex => ex.label === item.label))
  67. if (section.length) {
  68. items.push({ type: 'separator' })
  69. items = items.concat(section)
  70. }
  71. }
  72. }
  73. }
  74. return items.slice(1)
  75. }
  76. onTabDragStart (tab: BaseTabComponent) {
  77. this.app.emitTabDragStarted(tab)
  78. }
  79. onTabDragEnd () {
  80. setTimeout(() => {
  81. this.app.emitTabDragEnded()
  82. this.app.emitTabsChanged()
  83. })
  84. }
  85. @HostBinding('class.flex-width') get isFlexWidthEnabled (): boolean {
  86. return this.config.store.appearance.flexTabs
  87. }
  88. @HostListener('dblclick', ['$event']) onDoubleClick ($event: MouseEvent): void {
  89. this.app.renameTab(this.tab)
  90. $event.stopPropagation()
  91. }
  92. @HostListener('mousedown', ['$event']) async onMouseDown ($event: MouseEvent) {
  93. if ($event.which === 2) {
  94. $event.preventDefault()
  95. }
  96. }
  97. @HostListener('mouseup', ['$event']) async onMouseUp ($event: MouseEvent) {
  98. if ($event.which === 2) {
  99. this.app.closeTab(this.tab, true)
  100. }
  101. }
  102. @HostListener('contextmenu', ['$event']) async onContextMenu ($event: MouseEvent) {
  103. $event.preventDefault()
  104. this.platform.popupContextMenu(await this.buildContextMenu(), $event)
  105. }
  106. }