diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 78ebe16..7855d0d 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1778,6 +1778,11 @@ onBeforeUnmount(() => { " class="phone-resolution-wrapper phone-resolution-wrapper--primary" > +
{ it('uses layout zoom so the fixed-resolution phone stays sharply rasterized', () => { expect(source).toContain('phone-resolution-canvas--primary') + expect(source).toMatch( + /phone-resolution-wrapper--primary[\s\S]*?id="phone-home-drag-portal"[\s\S]*?phone-resolution-canvas--primary/, + ) + expect(source.match(/id="phone-home-drag-portal"/g)).toHaveLength(1) expect(source).toContain("'--phone-rendered-height'") expect(source).toContain("'--phone-rendered-width'") expect(mainCss).toMatch( diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css index 1eb36f7..b1b735a 100644 --- a/frontend/src/assets/main.css +++ b/frontend/src/assets/main.css @@ -295,6 +295,18 @@ button { height: var(--phone-rendered-height, 844px); } +.phone-home-drag-portal { + position: absolute; + z-index: 70; + inset: 0; + overflow: hidden; + pointer-events: none; +} + +.phone-home-drag-portal * { + pointer-events: none !important; +} + .phone-resolution-canvas { position: absolute; top: 0; @@ -2622,8 +2634,30 @@ button { .springboard--widget-dragging .springboard-widget-page-scroll { overflow: visible; } -.springboard--home-dragging .springboard-page--apps { - overflow: visible; +.home-drag-layer { + position: absolute; + overflow: hidden; + pointer-events: none; +} +.home-drag-layer * { + pointer-events: none !important; +} +.home-drag-position { + position: absolute; + top: 0; + left: 0; + will-change: transform; +} +.home-drag-ghost { + position: absolute; + top: 0; + left: 0; + margin: 0; + opacity: 1; + transition: none !important; + animation: none !important; + transform-origin: 0 0; + will-change: transform; } .app-grid { display: grid; @@ -2658,6 +2692,9 @@ button { transition: transform var(--springboard-page-duration) var(--springboard-page-easing); } +.app-icon-item--drag-source { + opacity: 0; +} .app-icon-remove { position: absolute; z-index: 4; diff --git a/frontend/src/components/AppIcon.vue b/frontend/src/components/AppIcon.vue index 230fb3a..d3b447c 100644 --- a/frontend/src/components/AppIcon.vue +++ b/frontend/src/components/AppIcon.vue @@ -30,11 +30,13 @@ const props = withDefaults( app: PhoneAppDefinition compact?: boolean editMode?: boolean + externalDragVisual?: boolean showLabel?: boolean }>(), { compact: false, editMode: false, + externalDragVisual: false, showLabel: true, }, ) @@ -63,14 +65,14 @@ let dragStartPage = 0 let dragPageWidth = 0 let dragPageMetrics: SpringboardDragMetrics | null = null const dragStyle = computed(() => - isDragging.value + isDragging.value && !props.externalDragVisual ? { transform: `translate3d(${springboardPageDragCompensation(dragStartPage, phone.currentPage, dragPageWidth)}px, 0, 0)`, } : undefined, ) const dragPointerStyle = computed(() => - isDragging.value + isDragging.value && !props.externalDragVisual ? { transform: `translate3d(${dragOffset.value.x}px, ${dragOffset.value.y}px, 0)`, } @@ -300,6 +302,7 @@ onBeforeUnmount(() => { class="app-icon-item" :class="{ 'app-icon-item--compact': compact, + 'app-icon-item--drag-source': isDragging && externalDragVisual, 'app-icon-item--dragging': isDragging, 'app-icon-item--editing': editMode, }" diff --git a/frontend/src/components/HomeFolderIcon.vue b/frontend/src/components/HomeFolderIcon.vue index bb25b93..552262c 100644 --- a/frontend/src/components/HomeFolderIcon.vue +++ b/frontend/src/components/HomeFolderIcon.vue @@ -22,11 +22,13 @@ const props = withDefaults( apps: PhoneAppDefinition[] defaultName: string editMode?: boolean + externalDragVisual?: boolean folder: HomeFolder showLabel?: boolean }>(), { editMode: false, + externalDragVisual: false, showLabel: true, }, ) @@ -55,14 +57,14 @@ let stopPointerSession: (() => void) | null = null const folderName = computed(() => props.folder.name || props.defaultName) const dragStyle = computed(() => - isDragging.value + isDragging.value && !props.externalDragVisual ? { transform: `translate3d(${springboardPageDragCompensation(dragStartPage, phone.currentPage, dragPageWidth)}px, 0, 0)`, } : undefined, ) const dragPointerStyle = computed(() => - isDragging.value + isDragging.value && !props.externalDragVisual ? { transform: `translate3d(${dragOffset.value.x}px, ${dragOffset.value.y}px, 0)`, } @@ -232,6 +234,7 @@ onBeforeUnmount(() => {
', + { + appName: 'radio-app', + localStorage: {}, + resourceName: 'lb-radioapp', + settings: createLbPhoneHostSettings({ + deviceName: 'Main phone', + isDarkMode: true, + language: 'en', + preferences: DEFAULT_PHONE_PREFERENCES, + securityEnabled: false, + }), + ui: 'https://cfx-nui-lb-radioapp/ui/dist/index.html', + }, + ) + const runtime = /