diff --git a/apps/control/src/app/main-view.component.ts b/apps/control/src/app/main-view.component.ts index 4c4407e5f87..5ed40eccc4f 100644 --- a/apps/control/src/app/main-view.component.ts +++ b/apps/control/src/app/main-view.component.ts @@ -28,7 +28,6 @@ import { NextMeetingComponent } from './ui/next-meeting.component'; name="splash" class="absolute inset-0 flex flex-col items-center justify-center text-white" (click)="powerOn()" - (touchend)="powerOn()" >

{{ 'APP.CONTROL.TOUCH_TO_START' | translate }} @@ -43,7 +42,9 @@ import { NextMeetingComponent } from './ui/next-meeting.component'; diff --git a/apps/control/src/app/tabbed-view/tab-outlet.component.ts b/apps/control/src/app/tabbed-view/tab-outlet.component.ts index 7d8bf095290..31d840b7c04 100644 --- a/apps/control/src/app/tabbed-view/tab-outlet.component.ts +++ b/apps/control/src/app/tabbed-view/tab-outlet.component.ts @@ -6,7 +6,6 @@ import { AsyncHandler, log } from '@placeos/common'; import { BindingDirective, IconComponent, - SafePipe, TranslatePipe, } from '@placeos/components'; import { map } from 'rxjs/operators'; @@ -157,9 +156,7 @@ import { TVControlsComponent } from './tv-controls.component';
} @if (!help()) { @@ -243,7 +240,6 @@ import { TVControlsComponent } from './tv-controls.component'; DeviceOutputListComponent, TranslatePipe, MarkdownPipe, - SafePipe, TVControlsComponent, VideoCallDialViewComponent, CameraControlsComponent, diff --git a/apps/control/src/app/tabbed-view/tabbed-view.component.ts b/apps/control/src/app/tabbed-view/tabbed-view.component.ts index abc31590135..d1f5571899f 100644 --- a/apps/control/src/app/tabbed-view/tabbed-view.component.ts +++ b/apps/control/src/app/tabbed-view/tabbed-view.component.ts @@ -37,7 +37,6 @@ import { TabOutletComponent } from './tab-outlet.component'; name="splash" class="absolute inset-0 flex flex-col items-center justify-center text-white" (click)="powerOn()" - (touchend)="powerOn()" >

{{ 'APP.CONTROL.TOUCH_TO_START' | translate }} @@ -50,7 +49,9 @@ import { TabOutletComponent } from './tab-outlet.component'; diff --git a/apps/control/src/app/ui/camera-controls.component.ts b/apps/control/src/app/ui/camera-controls.component.ts index d3329c88770..ca8638acf87 100644 --- a/apps/control/src/app/ui/camera-controls.component.ts +++ b/apps/control/src/app/ui/camera-controls.component.ts @@ -44,7 +44,7 @@ export enum ZoomDirection { } -
+

{{ 'APP.CONTROL.CONTROLS' | translate }}

@@ -63,9 +63,11 @@ export enum ZoomDirection { zoom-in icon matRipple - class="rounded-sm" - (mousedown)="startZoom('in', $event)" - (touchstart)="startZoom('in', $event)" + class="touch-none rounded-sm select-none" + (pointerdown)="startZoom('in', $event)" + (pointerup)="stopZoom()" + (pointercancel)="stopZoom()" + (lostpointercapture)="stopZoom()" (contextmenu)="$event.preventDefault()" > add @@ -79,25 +81,30 @@ export enum ZoomDirection { zoom-out icon matRipple - class="rounded-sm" - (mousedown)="startZoom('out', $event)" - (touchstart)="startZoom('out', $event)" + class="touch-none rounded-sm select-none" + (pointerdown)="startZoom('out', $event)" + (pointerup)="stopZoom()" + (pointercancel)="stopZoom()" + (lostpointercapture)="stopZoom()" (contextmenu)="$event.preventDefault()" - (window:mouseup)="stopZoom()" - (window:touchend)="stopZoom()" > remove
+ @if (!active_camera()) { +
+

+ {{ + 'APP.CONTROL.CAMERA_SELECT_MSG' | translate + }} +

+
+ } - @if (!active_camera()) { -
-

{{ 'APP.CONTROL.CAMERA_SELECT_MSG' | translate }}

-
- } } `, @@ -114,7 +121,6 @@ export enum ZoomDirection { }) export class CameraControlsComponent implements OnInit { private _state = inject(ControlStateService); - private _destroyRef = inject(DestroyRef); /** Currently active camera */ public readonly active_camera = signal(undefined); @@ -141,6 +147,7 @@ export class CameraControlsComponent implements OnInit { } constructor() { + inject(DestroyRef).onDestroy(() => this.stopZoom()); effect(() => { const list = this.camera_list(); const cam = this._selected_camera(); @@ -205,7 +212,9 @@ export class CameraControlsComponent implements OnInit { }, 50); } - public async startZoom(dir: 'in' | 'out', e: MouseEvent | TouchEvent) { + /** Start zooming. Pointer capture makes sure the button receives the release. */ + public async startZoom(dir: 'in' | 'out', e: PointerEvent) { + (e.currentTarget as Element | null)?.setPointerCapture?.(e.pointerId); const cam = this.active_camera(); if (!cam) return; const mod = getModule(this.id, cam.mod); diff --git a/apps/control/src/app/ui/camera-tooltip.component.ts b/apps/control/src/app/ui/camera-tooltip.component.ts index 927314ef602..7e45f536feb 100644 --- a/apps/control/src/app/ui/camera-tooltip.component.ts +++ b/apps/control/src/app/ui/camera-tooltip.component.ts @@ -1,4 +1,4 @@ -import { Component, effect, inject, signal } from '@angular/core'; +import { Component, DestroyRef, effect, inject, signal } from '@angular/core'; import { BindingDirective, CustomTooltipData, @@ -134,11 +134,7 @@ export enum ZoomDirection {

{{ 'APP.CONTROL.CONTROLS' | translate }}

-
+
add @@ -170,11 +167,12 @@ export enum ZoomDirection { zoom-out icon matRipple - class="rounded-sm" - (mousedown)="startZoom('out', $event)" - (touchstart)="startZoom('out', $event)" + class="touch-none rounded-sm select-none" + (pointerdown)="startZoom('out', $event)" + (pointerup)="stopZoom()" + (pointercancel)="stopZoom()" + (lostpointercapture)="stopZoom()" (contextmenu)="$event.preventDefault()" - (click)="stopZoom()" > remove @@ -183,7 +181,8 @@ export enum ZoomDirection {
@if (!active_camera()) {

{{ @@ -267,6 +266,7 @@ export class CameraTooltipComponent { } constructor() { + inject(DestroyRef).onDestroy(() => this.stopZoom()); effect(() => { const l = this.camera_list(); const cam = this._selected_camera(); @@ -312,7 +312,8 @@ export class CameraTooltipComponent { this._move_timeout = setTimeout(async () => { const { index } = camera; const mod = getModule(this.id, camera.mod); - if (!mod) return; + // Stop first so an axis that returned to Stop does not keep moving + await mod.execute('stop', index ? [index] : []); if (this.tilt !== JoystickTilt.Stop) { await mod.execute( 'tilt', @@ -325,16 +326,12 @@ export class CameraTooltipComponent { index ? [this.pan, index] : [this.pan], ); } - if ( - this.tilt === JoystickTilt.Stop && - this.pan === JoystickPan.Stop - ) { - await mod.execute('stop', index ? [index] : []); - } }, 50); } - public async startZoom(dir: 'in' | 'out', e: MouseEvent | TouchEvent) { + /** Start zooming. Pointer capture makes sure the button receives the release. */ + public async startZoom(dir: 'in' | 'out', e: PointerEvent) { + (e.currentTarget as Element | null)?.setPointerCapture?.(e.pointerId); const camera = this.active_camera(); if (!camera?.mod) return; const mod = getModule(this.id, camera.mod); diff --git a/apps/control/src/app/ui/help-modal.component.ts b/apps/control/src/app/ui/help-modal.component.ts index 48991ba6c9c..4e337865526 100644 --- a/apps/control/src/app/ui/help-modal.component.ts +++ b/apps/control/src/app/ui/help-modal.component.ts @@ -8,7 +8,6 @@ import { OrganisationService, SettingsService } from '@placeos/common'; import { AuthenticatedImageDirective, IconComponent, - SafePipe, } from '@placeos/components'; import { marked } from 'marked'; @@ -74,7 +73,7 @@ import { marked } from 'marked';