@ash-qw/dsh-theme-prts 0.1.93 → 0.1.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ash-qw/dsh-theme-prts",
3
- "version": "0.1.93",
3
+ "version": "0.1.95",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Unofficial Arknights P.R.T.S.-inspired UI theme for DeepSeek Harness Web",
@@ -70,7 +70,7 @@
70
70
  "node": ">=18"
71
71
  },
72
72
  "devDependencies": {
73
- "@playwright/test": "1.55.0",
73
+ "@playwright/test": "1.55.1",
74
74
  "jsdom": "24.1.3"
75
75
  }
76
76
  }
@@ -9,6 +9,7 @@ const COMPOSER_RELEVANCE_SELECTOR = [
9
9
  'button[aria-haspopup="listbox"]',
10
10
  '[role="menu"]',
11
11
  '[role="listbox"]',
12
+ '[data-trigger-menu]',
12
13
  '[data-slot="conversation.input.overlay"]',
13
14
  ].join(', ')
14
15
  const PRESET_TRIGGER_SELECTOR = [
@@ -27,7 +28,7 @@ function controlledPopup(document, trigger) {
27
28
  }
28
29
 
29
30
  function localPopup(trigger) {
30
- const selector = '[role="menu"], [role="listbox"], [class*="mufS8W_card"]'
31
+ const selector = '[role="menu"], [role="listbox"], [data-trigger-menu], [class*="mufS8W_card"]'
31
32
  const sibling = trigger.nextElementSibling
32
33
  if (sibling?.matches(selector)) return sibling
33
34
  return trigger.parentElement?.querySelector(`:scope > ${selector}`) ?? null
@@ -36,7 +37,7 @@ function localPopup(trigger) {
36
37
  function overlayPopup(document) {
37
38
  const overlay = document.querySelector('[data-slot="conversation.input.overlay"]')
38
39
  if (!overlay) return null
39
- return overlay.querySelector('[role="listbox"], [role="menu"], [class*="mufS8W_card"]')
40
+ return overlay.querySelector('[data-trigger-menu], [role="listbox"], [role="menu"], [class*="mufS8W_card"]')
40
41
  }
41
42
 
42
43
  function linkedMenu(document, trigger) {
@@ -48,9 +49,9 @@ function linkedMenu(document, trigger) {
48
49
  function markPopup(popup, kind) {
49
50
  if (!popup) return
50
51
  mark(popup, MENU_ATTRIBUTE, kind)
51
- const card = popup.closest?.('[class*="mufS8W_card"]')
52
+ const card = popup.closest?.('[data-trigger-menu], [class*="mufS8W_card"]')
52
53
  mark(card, MENU_ATTRIBUTE, kind)
53
- for (const nested of popup.querySelectorAll?.('[role="menu"], [role="listbox"], [class*="mufS8W_card"]') ?? []) {
54
+ for (const nested of popup.querySelectorAll?.('[role="menu"], [role="listbox"], [data-trigger-menu], [class*="mufS8W_card"]') ?? []) {
54
55
  mark(nested, MENU_ATTRIBUTE, kind)
55
56
  }
56
57
  }
@@ -162,7 +163,7 @@ export function createComposerGlassAdapter({ document, window }) {
162
163
 
163
164
  const overlay = document?.querySelector?.('[data-slot="conversation.input.overlay"]')
164
165
  if (overlay) {
165
- for (const popup of overlay.querySelectorAll('[role="menu"], [role="listbox"], [class*="mufS8W_card"]')) {
166
+ for (const popup of overlay.querySelectorAll('[data-trigger-menu], [role="menu"], [role="listbox"], [class*="mufS8W_card"]')) {
166
167
  markPopup(popup, popup.hasAttribute('aria-busy') ? 'model' : 'action')
167
168
  }
168
169
  }
@@ -12,7 +12,6 @@ import { createThemeController } from './theme-controller-v2.js'
12
12
  import { createParticleFieldAdapter } from './particle-field-adapter.js'
13
13
  import { createToBottomAdapter } from './to-bottom-adapter.js'
14
14
  import { createConversationControlAdapter } from './conversation-control-adapter.js'
15
- import { createConversationScaleAdapter } from './conversation-scale-adapter.js'
16
15
  import { createLayoutStabilityDiagnostics } from './layout-stability-diagnostics.js'
17
16
  import { createSidebarControlAdapter } from './sidebar-control-adapter.js'
18
17
  import { createFloatingGlassAdapter } from './floating-glass-adapter.js'
@@ -68,10 +67,8 @@ export function applyPrtsPlugin(ctx, environment) {
68
67
  particleField.setSchemeTransitionActive(active)
69
68
  },
70
69
  })
71
- const sessions = contextService(ctx, 'sessions')
72
70
  const toBottom = createToBottomAdapter({ document, window })
73
71
  const conversationControls = createConversationControlAdapter({ document, window })
74
- const conversationScale = createConversationScaleAdapter({ document, window, sessions })
75
72
  const layoutDiagnostics = createLayoutStabilityDiagnostics({ document, window })
76
73
  const sidebarControls = createSidebarControlAdapter({ document, window })
77
74
  const floatingGlass = createFloatingGlassAdapter({ document, window })
@@ -153,7 +150,6 @@ export function applyPrtsPlugin(ctx, environment) {
153
150
  particleField.update({ ...preferences, enabled: false })
154
151
  toBottom.dispose()
155
152
  conversationControls.dispose()
156
- conversationScale.dispose()
157
153
  layoutDiagnostics.dispose()
158
154
  sidebarControls.dispose()
159
155
  floatingGlass.dispose()
@@ -194,9 +190,6 @@ export function applyPrtsPlugin(ctx, environment) {
194
190
  onRetrySave() {
195
191
  retryPersistence()
196
192
  },
197
- getConversationScalePreview(value) {
198
- return conversationScale.getCalibrationState(value)
199
- },
200
193
  })
201
194
  if (!operations.update(preferences, status, settingsPersistence)) {
202
195
  if (!mountWarningIssued) {
@@ -216,8 +209,6 @@ export function applyPrtsPlugin(ctx, environment) {
216
209
  assistantGlass.start()
217
210
  toBottom.start()
218
211
  conversationControls.start()
219
- conversationScale.update(preferences)
220
- conversationScale.start()
221
212
  layoutDiagnostics.start()
222
213
  sidebarControls.start()
223
214
  floatingGlass.start()
@@ -315,7 +306,6 @@ export function applyPrtsPlugin(ctx, environment) {
315
306
  particleField.dispose()
316
307
  toBottom.dispose()
317
308
  conversationControls.dispose()
318
- conversationScale.dispose()
319
309
  layoutDiagnostics.dispose()
320
310
  sidebarControls.dispose()
321
311
  floatingGlass.dispose()
@@ -361,7 +351,7 @@ export function applyPrtsPlugin(ctx, environment) {
361
351
 
362
352
  export function apply(ctx) {
363
353
  const React = require('react')
364
- const { defineStore } = require('@deepseek-ai/dsh-client-runtime/client')
354
+ const { defineStore } = require('@deepseek-ai/dsh-client-store')
365
355
  applyPrtsPlugin(ctx, {
366
356
  document,
367
357
  window,
@@ -1,6 +1,12 @@
1
1
  import { createThemeSettingsOverlay, themeSettingsMarkup } from './theme-settings-workbench.js'
2
2
  import { createResizeShieldAdapter } from './resize-shield-adapter.js'
3
3
 
4
+ const PHONE_RAIL_BREAKPOINT = 640
5
+ const RAIL_HOLD_DELAY_MS = 350
6
+ const RAIL_HOLD_MOVE_TOLERANCE = 8
7
+ const RAIL_SWIPE_THRESHOLD = 32
8
+ const RAIL_SWIPE_AXIS_RATIO = 1.25
9
+
4
10
  function setText(root, selector, value) {
5
11
  const node = root?.querySelector(selector)
6
12
  const next = String(value ?? '')
@@ -9,7 +15,7 @@ function setText(root, selector, value) {
9
15
 
10
16
  function markup(emblem) {
11
17
  return `<div data-prts-shell data-plugin="dsh-theme-prts">
12
- <button type="button" data-prts-rail-launcher aria-label="打开 P.R.T.S. 导航" aria-controls="prts-nav-rail" aria-expanded="false"><span aria-hidden="true">P.R.T.S.</span></button>
18
+ <button type="button" data-prts-rail-launcher aria-label="打开 P.R.T.S. 导航" aria-controls="prts-nav-rail" aria-expanded="false"><span aria-hidden="true">P.R.T.S.</span><i data-prts-rail-gesture-cue aria-hidden="true">⌄<br>⌄</i></button>
13
19
  <nav id="prts-nav-rail" data-prts-nav-rail aria-label="P.R.T.S. 导航">
14
20
  <button type="button" data-prts-rail-brand aria-label="P.R.T.S. 终端设置" aria-controls="prts-theme-settings" aria-expanded="false">${emblem || ''}<span>P.R.T.S.</span></button>
15
21
  <div data-prts-nav-bottom>
@@ -40,7 +46,6 @@ export function createOperationsShell({
40
46
  onPreferenceChange = () => {},
41
47
  onPreferencePreview = () => {},
42
48
  onVisualReset = () => {},
43
- getConversationScalePreview = () => ({ visible: false, reason: 'unmeasured', mode: 'hidden' }),
44
49
  onRetrySave = () => {},
45
50
  }) {
46
51
  const root = document.documentElement
@@ -52,6 +57,10 @@ export function createOperationsShell({
52
57
  let railViewport
53
58
  let railDefaultHidden = false
54
59
  let railViewportQuery
60
+ let railPointerQuery
61
+ let railHoverQuery
62
+ let railPointer
63
+ let railHoldTimer
55
64
  let settingsOverlay
56
65
  let schemeToggle
57
66
  let schemeIntent
@@ -72,6 +81,89 @@ export function createOperationsShell({
72
81
  try { return window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches === true } catch { return false }
73
82
  }
74
83
 
84
+ function phoneRailGesture() {
85
+ if (railMode !== 'overlay' || Number(window.innerWidth) > PHONE_RAIL_BREAKPOINT) return false
86
+ return railPointerQuery?.matches === true
87
+ || railHoverQuery?.matches === true
88
+ || Number(window.navigator?.maxTouchPoints) > 0
89
+ }
90
+
91
+ function clearRailGesture({ release = true } = {}) {
92
+ if (railHoldTimer !== undefined) window.clearTimeout(railHoldTimer)
93
+ railHoldTimer = undefined
94
+ const pointer = railPointer
95
+ railPointer = undefined
96
+ if (release && pointer) {
97
+ try { railLauncher?.releasePointerCapture?.(pointer.pointerId) } catch {}
98
+ }
99
+ railLauncher?.removeAttribute('data-prts-rail-gesture-active')
100
+ railLauncher?.removeAttribute('data-prts-rail-gesture-ready')
101
+ railLauncher?.style?.removeProperty('--prts-rail-gesture-progress')
102
+ }
103
+
104
+ function armRailGesture() {
105
+ railHoldTimer = undefined
106
+ if (!railPointer || !phoneRailGesture()) return
107
+ railPointer.armed = true
108
+ railLauncher?.setAttribute('data-prts-rail-gesture-active', '')
109
+ }
110
+
111
+ function onRailPointerDown(event) {
112
+ if (!phoneRailGesture() || railPointer || (event.button ?? 0) !== 0) return
113
+ const pointerId = event.pointerId ?? 1
114
+ railPointer = {
115
+ pointerId,
116
+ startX: Number(event.clientX) || 0,
117
+ startY: Number(event.clientY) || 0,
118
+ armed: false,
119
+ ready: false,
120
+ }
121
+ try { railLauncher?.setPointerCapture?.(pointerId) } catch {}
122
+ railHoldTimer = window.setTimeout(armRailGesture, RAIL_HOLD_DELAY_MS)
123
+ }
124
+
125
+ function onRailPointerMove(event) {
126
+ const pointer = railPointer
127
+ if (!pointer || (event.pointerId ?? 1) !== pointer.pointerId) return
128
+ const deltaX = (Number(event.clientX) || 0) - pointer.startX
129
+ const deltaY = (Number(event.clientY) || 0) - pointer.startY
130
+ if (!pointer.armed) {
131
+ if (Math.hypot(deltaX, deltaY) > RAIL_HOLD_MOVE_TOLERANCE) clearRailGesture()
132
+ return
133
+ }
134
+ event.preventDefault?.()
135
+ if (Math.abs(deltaX) > Math.max(RAIL_HOLD_MOVE_TOLERANCE, Math.max(0, deltaY) / RAIL_SWIPE_AXIS_RATIO)) {
136
+ clearRailGesture()
137
+ return
138
+ }
139
+ const progress = Math.min(1, Math.max(0, deltaY) / RAIL_SWIPE_THRESHOLD)
140
+ pointer.ready = deltaY >= RAIL_SWIPE_THRESHOLD
141
+ && deltaY >= Math.abs(deltaX) * RAIL_SWIPE_AXIS_RATIO
142
+ railLauncher?.style?.setProperty('--prts-rail-gesture-progress', Math.round(progress * 12) + 'px')
143
+ railLauncher?.toggleAttribute('data-prts-rail-gesture-ready', pointer.ready)
144
+ }
145
+
146
+ function onRailPointerUp(event) {
147
+ const pointer = railPointer
148
+ if (!pointer || (event.pointerId ?? 1) !== pointer.pointerId) return
149
+ const shouldOpen = pointer.armed && pointer.ready
150
+ clearRailGesture()
151
+ if (shouldOpen) openRail()
152
+ }
153
+
154
+ function onRailLostPointerCapture(event) {
155
+ if (!railPointer || (event.pointerId ?? 1) !== railPointer.pointerId) return
156
+ clearRailGesture({ release: false })
157
+ }
158
+
159
+ function onRailClick(event) {
160
+ if (phoneRailGesture() && Number(event?.detail) > 0) {
161
+ event.preventDefault?.()
162
+ return
163
+ }
164
+ toggleRail()
165
+ }
166
+
75
167
  function playSchemePress() {
76
168
  if (!schemeToggle || reducedMotion()) return
77
169
  const revision = ++schemePressRevision
@@ -129,7 +221,6 @@ export function createOperationsShell({
129
221
  )
130
222
  const active = Boolean(candidate)
131
223
  root.dataset.prtsConversationState = active ? 'active' : 'idle'
132
- settingsOverlay?.refreshScalePreview()
133
224
  }
134
225
 
135
226
  function toggleScheme(event) {
@@ -257,7 +348,8 @@ export function createOperationsShell({
257
348
  const overlay = railMode === 'overlay'
258
349
  const open = overlay && root.hasAttribute('data-prts-rail-open')
259
350
  railLauncher.setAttribute('aria-expanded', String(open))
260
- railLauncher.setAttribute('aria-label', open ? '关闭 P.R.T.S. 导航' : '打开 P.R.T.S. 导航')
351
+ const closedLabel = phoneRailGesture() ? '长按并向下滑动打开 P.R.T.S. 导航' : '打开 P.R.T.S. 导航'
352
+ railLauncher.setAttribute('aria-label', open ? '关闭 P.R.T.S. 导航' : closedLabel)
261
353
  if (overlay && !open) {
262
354
  navRail.setAttribute('aria-hidden', 'true')
263
355
  navRail.setAttribute('inert', '')
@@ -294,6 +386,7 @@ export function createOperationsShell({
294
386
  if (!viewportChanged && !modeChanged && !forceClose) return railMode
295
387
  railViewport = nextViewport
296
388
  railMode = nextMode
389
+ clearRailGesture()
297
390
  root.dataset.prtsRailMode = nextMode
298
391
  root.removeAttribute('data-prts-rail-open')
299
392
  syncRailState()
@@ -320,13 +413,18 @@ export function createOperationsShell({
320
413
  }
321
414
 
322
415
  function onResponsiveChange() {
416
+ clearRailGesture()
323
417
  setRailViewport(window.innerWidth)
324
- settingsOverlay?.scheduleScalePreviewRefresh?.()
418
+ syncRailState()
325
419
  }
326
420
 
327
421
  function bindResponsiveQueries() {
328
422
  railViewportQuery = window.matchMedia?.('(min-width: 1180px)')
423
+ railPointerQuery = window.matchMedia?.('(pointer: coarse)')
424
+ railHoverQuery = window.matchMedia?.('(hover: none)')
329
425
  railViewportQuery?.addEventListener?.('change', onResponsiveChange)
426
+ railPointerQuery?.addEventListener?.('change', onResponsiveChange)
427
+ railHoverQuery?.addEventListener?.('change', onResponsiveChange)
330
428
  }
331
429
  function disableTheme() { onThemeDisable() }
332
430
 
@@ -356,7 +454,6 @@ export function createOperationsShell({
356
454
  onPreferencePreview,
357
455
  onResetVisual: onVisualReset,
358
456
  onRetrySave,
359
- getConversationScalePreview,
360
457
  })
361
458
  resizeShield.start([
362
459
  operationRegion,
@@ -367,7 +464,12 @@ export function createOperationsShell({
367
464
  conversationObserver.observe(operationRegion, { childList: true, subtree: true, attributes: true, attributeFilter: ['hidden', 'data-chat-flow-kind', 'data-message-role'] })
368
465
  schemeObserver = new window.MutationObserver(syncSchemeToggle)
369
466
  schemeObserver.observe(root, { attributes: true, attributeFilter: ['data-prts-scheme'] })
370
- railLauncher.addEventListener('click', toggleRail)
467
+ railLauncher.addEventListener('click', onRailClick)
468
+ railLauncher.addEventListener('pointerdown', onRailPointerDown)
469
+ railLauncher.addEventListener('pointermove', onRailPointerMove)
470
+ railLauncher.addEventListener('pointerup', onRailPointerUp)
471
+ railLauncher.addEventListener('pointercancel', clearRailGesture)
472
+ railLauncher.addEventListener('lostpointercapture', onRailLostPointerCapture)
371
473
  document.addEventListener('keydown', onRailKeydown)
372
474
  document.addEventListener('click', onDocumentClick)
373
475
  schemeToggle.addEventListener('click', toggleScheme)
@@ -384,10 +486,16 @@ export function createOperationsShell({
384
486
  }
385
487
 
386
488
  function dispose() {
489
+ clearRailGesture()
387
490
  cancelSchemePointer()
388
491
  clearSchemeClickSuppression()
389
492
  clearSchemePressDelays()
390
- railLauncher?.removeEventListener('click', toggleRail)
493
+ railLauncher?.removeEventListener('click', onRailClick)
494
+ railLauncher?.removeEventListener('pointerdown', onRailPointerDown)
495
+ railLauncher?.removeEventListener('pointermove', onRailPointerMove)
496
+ railLauncher?.removeEventListener('pointerup', onRailPointerUp)
497
+ railLauncher?.removeEventListener('pointercancel', clearRailGesture)
498
+ railLauncher?.removeEventListener('lostpointercapture', onRailLostPointerCapture)
391
499
  document.removeEventListener('keydown', onRailKeydown)
392
500
  document.removeEventListener('click', onDocumentClick)
393
501
  schemeToggle?.removeEventListener('click', toggleScheme)
@@ -399,7 +507,11 @@ export function createOperationsShell({
399
507
  window.removeEventListener?.('blur', cancelSchemePointer)
400
508
  themeDisable?.removeEventListener('click', disableTheme)
401
509
  railViewportQuery?.removeEventListener?.('change', onResponsiveChange)
510
+ railPointerQuery?.removeEventListener?.('change', onResponsiveChange)
511
+ railHoverQuery?.removeEventListener?.('change', onResponsiveChange)
402
512
  railViewportQuery = undefined
513
+ railPointerQuery = undefined
514
+ railHoverQuery = undefined
403
515
  resizeShield.dispose()
404
516
  settingsOverlay?.dispose()
405
517
  conversationObserver?.disconnect()
@@ -557,6 +557,7 @@ export function createParticleFieldAdapter({ document, window, emblem = '', embl
557
557
 
558
558
 
559
559
  function particleTraversalSpeed(value = preferences) {
560
+ if (phoneStatic()) return 0
560
561
  const numeric = Number(value?.particleTraversalSpeed)
561
562
  return Number.isFinite(numeric) ? clamp(numeric, 0, 2) : 1
562
563
  }
@@ -1123,6 +1124,19 @@ export function createParticleFieldAdapter({ document, window, emblem = '', embl
1123
1124
  const entry = entries.find(candidate => candidate.target === operation) ?? entries[0]
1124
1125
  const contentRect = entry?.contentRect
1125
1126
  pendingResizeSize = contentRect ? sizeFromRect(contentRect) : readOperationSize()
1127
+ if (phoneStatic()) {
1128
+ const nextSize = pendingResizeSize
1129
+ clearResizeState()
1130
+ const changed = applyFieldSize(nextSize)
1131
+ if (changed && particles.length) snapParticlesToCurrentLayout()
1132
+ resizeCommits += changed ? 1 : 0
1133
+ syncCanvasBackingStore()
1134
+ geometryDirty = false
1135
+ cancelFrame()
1136
+ draw(Number(window.performance?.now?.()) || 0)
1137
+ cancelFrame()
1138
+ return
1139
+ }
1126
1140
  if (resizeFrame !== undefined) return
1127
1141
  resizeFrame = window.requestAnimationFrame?.(() => {
1128
1142
  resizeFrame = undefined
@@ -1532,7 +1546,7 @@ export function createParticleFieldAdapter({ document, window, emblem = '', embl
1532
1546
  if (heroActive) leaveHero()
1533
1547
  }
1534
1548
  function onScroll() {
1535
- if (!scroller) return
1549
+ if (!scroller || phoneStatic()) return
1536
1550
  if (heroActive) {
1537
1551
  scheduleFrame()
1538
1552
  return
@@ -1581,6 +1595,7 @@ export function createParticleFieldAdapter({ document, window, emblem = '', embl
1581
1595
  }
1582
1596
 
1583
1597
  function registerContentMutations(mutations) {
1598
+ if (phoneStatic()) return
1584
1599
  let weight = mutations.length
1585
1600
  for (const mutation of mutations) {
1586
1601
  for (const node of [...mutation.addedNodes, ...mutation.removedNodes]) {
@@ -1693,8 +1708,35 @@ export function createParticleFieldAdapter({ document, window, emblem = '', embl
1693
1708
  cancelFrame()
1694
1709
  }
1695
1710
 
1711
+ function rebindScroller(nextScroller) {
1712
+ scroller?.removeAttribute('data-prts-hero-active')
1713
+ scroller?.removeEventListener('scroll', onScroll)
1714
+ cancelHydrationResume()
1715
+ hydrationPaused = false
1716
+ mutationBurstScore = 0
1717
+ if (mutationBurstTimer !== undefined) window.clearTimeout?.(mutationBurstTimer)
1718
+ mutationBurstTimer = undefined
1719
+ heroMarker = undefined
1720
+ heroActive = false
1721
+ scroller = nextScroller
1722
+ scroller.addEventListener('scroll', onScroll, { passive: true })
1723
+ syncHeroState()
1724
+ if (!heroActive) {
1725
+ resetTraversal()
1726
+ if (!phoneStatic()) restoreTraversalFromScroll()
1727
+ commitTransitionTargets(segment, true)
1728
+ }
1729
+ scheduleFrame()
1730
+ }
1731
+
1696
1732
  function mount(nextOperation, nextScroller) {
1697
- if (operation === nextOperation && scroller === nextScroller && ambient?.isConnected && canvas?.isConnected) return
1733
+ if (operation === nextOperation && ambient?.isConnected && canvas?.isConnected) {
1734
+ if (scroller === nextScroller) return
1735
+ if (nextScroller) {
1736
+ rebindScroller(nextScroller)
1737
+ return
1738
+ }
1739
+ }
1698
1740
  unmount()
1699
1741
  operation = nextOperation
1700
1742
  scroller = nextScroller
@@ -1705,7 +1747,7 @@ export function createParticleFieldAdapter({ document, window, emblem = '', embl
1705
1747
  glow = created.glow
1706
1748
  canvas = document.createElement('canvas')
1707
1749
  canvas.setAttribute('data-prts-particle-layer', '')
1708
- canvas.setAttribute('aria-label', '随对话滚动轮换阵营标识的粒子画布')
1750
+ canvas.setAttribute('aria-label', phoneStatic() ? '静态阵营标识粒子画布' : '随对话滚动轮换阵营标识的粒子画布')
1709
1751
  canvas.style.visibility = 'hidden'
1710
1752
  if (typeof window.CanvasRenderingContext2D === 'function') context = canvas.getContext('2d')
1711
1753
  targetCache.clear()
@@ -1,15 +1,5 @@
1
1
  export const PRTS_STORAGE_KEY = 'dsh.ui.prts.v1'
2
2
 
3
- export const CONVERSATION_SCALE_DISTANCE_MIN = 16
4
- export const CONVERSATION_SCALE_DISTANCE_MAX = 240
5
- export const CONVERSATION_SCALE_DISTANCE_STEP = 8
6
- export const CONVERSATION_SCALE_DISTANCE_DEFAULT = 96
7
-
8
- export const CONVERSATION_SCALE_FOCUS_CONTRAST_MIN = 0
9
- export const CONVERSATION_SCALE_FOCUS_CONTRAST_MAX = 100
10
- export const CONVERSATION_SCALE_FOCUS_CONTRAST_STEP = 10
11
- export const CONVERSATION_SCALE_FOCUS_CONTRAST_DEFAULT = 70
12
-
13
3
  export const PARTICLE_TRAVERSAL_SPEED_MIN = 0
14
4
  export const PARTICLE_TRAVERSAL_SPEED_MAX = 2
15
5
  export const PARTICLE_TRAVERSAL_SPEED_STEP = 0.25
@@ -28,8 +18,6 @@ export const DEFAULT_PREFERENCES = Object.freeze({
28
18
  particleTraversalSpeed: PARTICLE_TRAVERSAL_SPEED_DEFAULT,
29
19
  particlePattern: 'orthogonal',
30
20
  railDefaultHidden: false,
31
- conversationScaleMaxDistance: CONVERSATION_SCALE_DISTANCE_DEFAULT,
32
- conversationScaleFocusContrast: CONVERSATION_SCALE_FOCUS_CONTRAST_DEFAULT,
33
21
  })
34
22
 
35
23
  export const VISUAL_PRESETS = Object.freeze({
@@ -70,7 +58,7 @@ export const PREFERENCE_GROUPS = Object.freeze({
70
58
  particles: Object.freeze(['conversationParticleDensity', 'heroParticleDensity', 'particleTraversalSpeed']),
71
59
  material: Object.freeze(['glass']),
72
60
  accessibility: Object.freeze(['motion', 'bootAnimation']),
73
- navigation: Object.freeze(['railDefaultHidden', 'conversationScaleMaxDistance', 'conversationScaleFocusContrast']),
61
+ navigation: Object.freeze(['railDefaultHidden']),
74
62
  })
75
63
 
76
64
  const TEXTURES = new Set(['off', 'restrained', 'full'])
@@ -107,20 +95,6 @@ function enumOr(value, allowed, fallback) {
107
95
  return allowed.has(value) ? value : fallback
108
96
  }
109
97
 
110
- function scaleDistanceOr(value, fallback) {
111
- const numeric = Number(value)
112
- if (!Number.isFinite(numeric)) return fallback
113
- const clamped = Math.min(CONVERSATION_SCALE_DISTANCE_MAX, Math.max(CONVERSATION_SCALE_DISTANCE_MIN, numeric))
114
- return Math.round(clamped / CONVERSATION_SCALE_DISTANCE_STEP) * CONVERSATION_SCALE_DISTANCE_STEP
115
- }
116
-
117
- function scaleFocusContrastOr(value, fallback) {
118
- const numeric = Number(value)
119
- if (!Number.isFinite(numeric)) return fallback
120
- const clamped = Math.min(CONVERSATION_SCALE_FOCUS_CONTRAST_MAX, Math.max(CONVERSATION_SCALE_FOCUS_CONTRAST_MIN, numeric))
121
- return Math.round(clamped / CONVERSATION_SCALE_FOCUS_CONTRAST_STEP) * CONVERSATION_SCALE_FOCUS_CONTRAST_STEP
122
- }
123
-
124
98
  function particleTraversalSpeedOr(value, fallback) {
125
99
  const numeric = Number(value)
126
100
  if (!Number.isFinite(numeric)) return fallback
@@ -170,14 +144,6 @@ export function normalizePreferences(value) {
170
144
  ),
171
145
  particlePattern: 'orthogonal',
172
146
  railDefaultHidden: booleanOr(input.railDefaultHidden, DEFAULT_PREFERENCES.railDefaultHidden),
173
- conversationScaleMaxDistance: scaleDistanceOr(
174
- input.conversationScaleMaxDistance,
175
- DEFAULT_PREFERENCES.conversationScaleMaxDistance,
176
- ),
177
- conversationScaleFocusContrast: scaleFocusContrastOr(
178
- input.conversationScaleFocusContrast,
179
- DEFAULT_PREFERENCES.conversationScaleFocusContrast,
180
- ),
181
147
  }
182
148
  normalized.preset = matchedVisualPreset(normalized)
183
149
  return normalized
@@ -29,6 +29,11 @@ export function createResizeShieldAdapter({
29
29
 
30
30
  function onResize() {
31
31
  if (!started) return
32
+ if (Number(window?.innerWidth) <= 640) {
33
+ clearTimer()
34
+ setActive(false)
35
+ return
36
+ }
32
37
  setActive(true)
33
38
  clearTimer()
34
39
  settleTimer = window?.setTimeout?.(settle, settleDelay)