@ash-qw/dsh-theme-prts 0.1.93 → 0.1.94
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/CHANGELOG.md +6 -1
- package/README.en.md +21 -50
- package/README.md +22 -51
- package/lib/client.js +199 -19
- package/package.json +1 -1
- package/src/client/conversation-scale-adapter.js +37 -10
- package/src/client/operations-shell-v2.js +120 -4
- package/src/client/particle-field-adapter.js +45 -3
- package/src/client/resize-shield-adapter.js +5 -0
- package/src/styles/prts.css +40 -11
package/package.json
CHANGED
|
@@ -107,7 +107,8 @@ const PREVIEW_TOUCH_DURATION = 1200
|
|
|
107
107
|
const SNAP_DELAY = 110
|
|
108
108
|
const TOUCH_WAVE_DURATION = 620
|
|
109
109
|
const HISTORY_PAGE_SETTLE_LIMIT = 4000
|
|
110
|
-
const GEOMETRY_SETTLE_FRAME_LIMIT =
|
|
110
|
+
const GEOMETRY_SETTLE_FRAME_LIMIT = 8
|
|
111
|
+
const GEOMETRY_SETTLE_STABLE_FRAMES = 2
|
|
111
112
|
let scaleInstanceSeed = 0
|
|
112
113
|
|
|
113
114
|
function clamp(value, minimum, maximum) {
|
|
@@ -767,6 +768,7 @@ export function createConversationScaleAdapter({ document, window, sessions }) {
|
|
|
767
768
|
let geometryDirty = true
|
|
768
769
|
let geometrySettleFrame
|
|
769
770
|
let geometrySettleFramesRemaining = 0
|
|
771
|
+
let geometrySettleStableFrames = 0
|
|
770
772
|
let geometrySettleSignature
|
|
771
773
|
let observedOperationWidth
|
|
772
774
|
let observedOperationHeight
|
|
@@ -789,6 +791,7 @@ export function createConversationScaleAdapter({ document, window, sessions }) {
|
|
|
789
791
|
const currentTime = timestamp => Number.isFinite(timestamp)
|
|
790
792
|
? timestamp
|
|
791
793
|
: window?.performance?.now?.() ?? Date.now()
|
|
794
|
+
const phoneScaleHidden = () => Number(window?.innerWidth) <= 640
|
|
792
795
|
|
|
793
796
|
function currentGeometrySignature() {
|
|
794
797
|
if (!operation || !scroller) return undefined
|
|
@@ -817,11 +820,20 @@ export function createConversationScaleAdapter({ document, window, sessions }) {
|
|
|
817
820
|
if (!started || failed || geometrySettleFramesRemaining <= 0) return
|
|
818
821
|
geometrySettleFramesRemaining -= 1
|
|
819
822
|
const signature = currentGeometrySignature()
|
|
820
|
-
if (signature
|
|
823
|
+
if (signature === undefined) {
|
|
824
|
+
geometrySettleStableFrames = 0
|
|
825
|
+
} else if (signature !== geometrySettleSignature) {
|
|
821
826
|
geometrySettleSignature = signature
|
|
827
|
+
geometrySettleStableFrames = 1
|
|
822
828
|
geometryDirty = true
|
|
823
829
|
obstructionDirty = true
|
|
824
830
|
schedule()
|
|
831
|
+
} else {
|
|
832
|
+
geometrySettleStableFrames += 1
|
|
833
|
+
}
|
|
834
|
+
if (geometrySettleStableFrames >= GEOMETRY_SETTLE_STABLE_FRAMES) {
|
|
835
|
+
geometrySettleFramesRemaining = 0
|
|
836
|
+
return
|
|
825
837
|
}
|
|
826
838
|
if (geometrySettleFramesRemaining > 0) {
|
|
827
839
|
geometrySettleFrame = requestFrame(sampleGeometryStabilization)
|
|
@@ -829,8 +841,9 @@ export function createConversationScaleAdapter({ document, window, sessions }) {
|
|
|
829
841
|
}
|
|
830
842
|
|
|
831
843
|
function requestGeometryStabilization() {
|
|
832
|
-
if (!started || failed) return
|
|
844
|
+
if (!started || failed || phoneScaleHidden()) return
|
|
833
845
|
geometrySettleFramesRemaining = GEOMETRY_SETTLE_FRAME_LIMIT
|
|
846
|
+
geometrySettleStableFrames = 0
|
|
834
847
|
if (geometrySettleFrame === undefined) {
|
|
835
848
|
geometrySettleFrame = requestFrame(sampleGeometryStabilization)
|
|
836
849
|
}
|
|
@@ -840,11 +853,17 @@ export function createConversationScaleAdapter({ document, window, sessions }) {
|
|
|
840
853
|
cancelFrame(geometrySettleFrame)
|
|
841
854
|
geometrySettleFrame = undefined
|
|
842
855
|
geometrySettleFramesRemaining = 0
|
|
856
|
+
geometrySettleStableFrames = 0
|
|
843
857
|
geometrySettleSignature = undefined
|
|
844
858
|
}
|
|
845
859
|
|
|
846
860
|
function onHostGeometryChange() {
|
|
861
|
+
if (phoneScaleHidden()) {
|
|
862
|
+
stopGeometryStabilization()
|
|
863
|
+
return
|
|
864
|
+
}
|
|
847
865
|
requestGeometryStabilization()
|
|
866
|
+
schedule(true)
|
|
848
867
|
}
|
|
849
868
|
|
|
850
869
|
function reducedMotion() {
|
|
@@ -1058,7 +1077,6 @@ export function createConversationScaleAdapter({ document, window, sessions }) {
|
|
|
1058
1077
|
scanPending = true
|
|
1059
1078
|
fullScanPending = true
|
|
1060
1079
|
}
|
|
1061
|
-
if (resizeActive) return
|
|
1062
1080
|
if (frame !== undefined || failed) return
|
|
1063
1081
|
frame = requestFrame(flush)
|
|
1064
1082
|
}
|
|
@@ -2200,6 +2218,13 @@ export function createConversationScaleAdapter({ document, window, sessions }) {
|
|
|
2200
2218
|
if (typeof ResizeObserver === 'function') {
|
|
2201
2219
|
resizeObserver = new ResizeObserver((entries = []) => {
|
|
2202
2220
|
geometryDirty = true
|
|
2221
|
+
if (phoneScaleHidden()) {
|
|
2222
|
+
stopGeometryStabilization()
|
|
2223
|
+
if (resizeSettleTimer !== undefined) window?.clearTimeout?.(resizeSettleTimer)
|
|
2224
|
+
resizeSettleTimer = undefined
|
|
2225
|
+
setScaleResizeState(false)
|
|
2226
|
+
return
|
|
2227
|
+
}
|
|
2203
2228
|
requestGeometryStabilization()
|
|
2204
2229
|
const operationEntry = entries.find(entry => entry.target === operation)
|
|
2205
2230
|
const width = Number(operationEntry?.contentRect?.width)
|
|
@@ -2219,12 +2244,8 @@ export function createConversationScaleAdapter({ document, window, sessions }) {
|
|
|
2219
2244
|
return
|
|
2220
2245
|
}
|
|
2221
2246
|
if (!resizeActive) {
|
|
2247
|
+
schedule()
|
|
2222
2248
|
setScaleResizeState(true)
|
|
2223
|
-
if (frame !== undefined) {
|
|
2224
|
-
if (window?.cancelAnimationFrame) window.cancelAnimationFrame(frame)
|
|
2225
|
-
else window?.clearTimeout?.(frame)
|
|
2226
|
-
frame = undefined
|
|
2227
|
-
}
|
|
2228
2249
|
}
|
|
2229
2250
|
if (resizeSettleTimer !== undefined) window?.clearTimeout?.(resizeSettleTimer)
|
|
2230
2251
|
resizeSettleTimer = window?.setTimeout?.(() => {
|
|
@@ -2241,7 +2262,13 @@ export function createConversationScaleAdapter({ document, window, sessions }) {
|
|
|
2241
2262
|
const external = mutations.filter(mutation =>
|
|
2242
2263
|
!mutation.target?.closest?.('[data-prts-conversation-scale], [data-prts-conversation-preview], [data-prts-conversation-history-hint], [data-prts-conversation-history-status]')
|
|
2243
2264
|
)
|
|
2244
|
-
if (
|
|
2265
|
+
if (phoneScaleHidden()) return
|
|
2266
|
+
if (external.some(mutation =>
|
|
2267
|
+
operation?.contains?.(mutation.target)
|
|
2268
|
+
|| mutation.target?.contains?.(operation)
|
|
2269
|
+
|| mutation.target?.matches?.('header, [data-host-header], [data-slot*="header" i]')
|
|
2270
|
+
|| mutationAffectsOverlay(mutation)
|
|
2271
|
+
)) requestGeometryStabilization()
|
|
2245
2272
|
const historyRelevant = external.some(mutation =>
|
|
2246
2273
|
mutation.type === 'childList'
|
|
2247
2274
|
&& operation?.contains?.(mutation.target)
|
|
@@ -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>
|
|
@@ -52,6 +58,10 @@ export function createOperationsShell({
|
|
|
52
58
|
let railViewport
|
|
53
59
|
let railDefaultHidden = false
|
|
54
60
|
let railViewportQuery
|
|
61
|
+
let railPointerQuery
|
|
62
|
+
let railHoverQuery
|
|
63
|
+
let railPointer
|
|
64
|
+
let railHoldTimer
|
|
55
65
|
let settingsOverlay
|
|
56
66
|
let schemeToggle
|
|
57
67
|
let schemeIntent
|
|
@@ -72,6 +82,89 @@ export function createOperationsShell({
|
|
|
72
82
|
try { return window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches === true } catch { return false }
|
|
73
83
|
}
|
|
74
84
|
|
|
85
|
+
function phoneRailGesture() {
|
|
86
|
+
if (railMode !== 'overlay' || Number(window.innerWidth) > PHONE_RAIL_BREAKPOINT) return false
|
|
87
|
+
return railPointerQuery?.matches === true
|
|
88
|
+
|| railHoverQuery?.matches === true
|
|
89
|
+
|| Number(window.navigator?.maxTouchPoints) > 0
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function clearRailGesture({ release = true } = {}) {
|
|
93
|
+
if (railHoldTimer !== undefined) window.clearTimeout(railHoldTimer)
|
|
94
|
+
railHoldTimer = undefined
|
|
95
|
+
const pointer = railPointer
|
|
96
|
+
railPointer = undefined
|
|
97
|
+
if (release && pointer) {
|
|
98
|
+
try { railLauncher?.releasePointerCapture?.(pointer.pointerId) } catch {}
|
|
99
|
+
}
|
|
100
|
+
railLauncher?.removeAttribute('data-prts-rail-gesture-active')
|
|
101
|
+
railLauncher?.removeAttribute('data-prts-rail-gesture-ready')
|
|
102
|
+
railLauncher?.style?.removeProperty('--prts-rail-gesture-progress')
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function armRailGesture() {
|
|
106
|
+
railHoldTimer = undefined
|
|
107
|
+
if (!railPointer || !phoneRailGesture()) return
|
|
108
|
+
railPointer.armed = true
|
|
109
|
+
railLauncher?.setAttribute('data-prts-rail-gesture-active', '')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function onRailPointerDown(event) {
|
|
113
|
+
if (!phoneRailGesture() || railPointer || (event.button ?? 0) !== 0) return
|
|
114
|
+
const pointerId = event.pointerId ?? 1
|
|
115
|
+
railPointer = {
|
|
116
|
+
pointerId,
|
|
117
|
+
startX: Number(event.clientX) || 0,
|
|
118
|
+
startY: Number(event.clientY) || 0,
|
|
119
|
+
armed: false,
|
|
120
|
+
ready: false,
|
|
121
|
+
}
|
|
122
|
+
try { railLauncher?.setPointerCapture?.(pointerId) } catch {}
|
|
123
|
+
railHoldTimer = window.setTimeout(armRailGesture, RAIL_HOLD_DELAY_MS)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function onRailPointerMove(event) {
|
|
127
|
+
const pointer = railPointer
|
|
128
|
+
if (!pointer || (event.pointerId ?? 1) !== pointer.pointerId) return
|
|
129
|
+
const deltaX = (Number(event.clientX) || 0) - pointer.startX
|
|
130
|
+
const deltaY = (Number(event.clientY) || 0) - pointer.startY
|
|
131
|
+
if (!pointer.armed) {
|
|
132
|
+
if (Math.hypot(deltaX, deltaY) > RAIL_HOLD_MOVE_TOLERANCE) clearRailGesture()
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
event.preventDefault?.()
|
|
136
|
+
if (Math.abs(deltaX) > Math.max(RAIL_HOLD_MOVE_TOLERANCE, Math.max(0, deltaY) / RAIL_SWIPE_AXIS_RATIO)) {
|
|
137
|
+
clearRailGesture()
|
|
138
|
+
return
|
|
139
|
+
}
|
|
140
|
+
const progress = Math.min(1, Math.max(0, deltaY) / RAIL_SWIPE_THRESHOLD)
|
|
141
|
+
pointer.ready = deltaY >= RAIL_SWIPE_THRESHOLD
|
|
142
|
+
&& deltaY >= Math.abs(deltaX) * RAIL_SWIPE_AXIS_RATIO
|
|
143
|
+
railLauncher?.style?.setProperty('--prts-rail-gesture-progress', Math.round(progress * 12) + 'px')
|
|
144
|
+
railLauncher?.toggleAttribute('data-prts-rail-gesture-ready', pointer.ready)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function onRailPointerUp(event) {
|
|
148
|
+
const pointer = railPointer
|
|
149
|
+
if (!pointer || (event.pointerId ?? 1) !== pointer.pointerId) return
|
|
150
|
+
const shouldOpen = pointer.armed && pointer.ready
|
|
151
|
+
clearRailGesture()
|
|
152
|
+
if (shouldOpen) openRail()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function onRailLostPointerCapture(event) {
|
|
156
|
+
if (!railPointer || (event.pointerId ?? 1) !== railPointer.pointerId) return
|
|
157
|
+
clearRailGesture({ release: false })
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function onRailClick(event) {
|
|
161
|
+
if (phoneRailGesture() && Number(event?.detail) > 0) {
|
|
162
|
+
event.preventDefault?.()
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
toggleRail()
|
|
166
|
+
}
|
|
167
|
+
|
|
75
168
|
function playSchemePress() {
|
|
76
169
|
if (!schemeToggle || reducedMotion()) return
|
|
77
170
|
const revision = ++schemePressRevision
|
|
@@ -257,7 +350,8 @@ export function createOperationsShell({
|
|
|
257
350
|
const overlay = railMode === 'overlay'
|
|
258
351
|
const open = overlay && root.hasAttribute('data-prts-rail-open')
|
|
259
352
|
railLauncher.setAttribute('aria-expanded', String(open))
|
|
260
|
-
|
|
353
|
+
const closedLabel = phoneRailGesture() ? '长按并向下滑动打开 P.R.T.S. 导航' : '打开 P.R.T.S. 导航'
|
|
354
|
+
railLauncher.setAttribute('aria-label', open ? '关闭 P.R.T.S. 导航' : closedLabel)
|
|
261
355
|
if (overlay && !open) {
|
|
262
356
|
navRail.setAttribute('aria-hidden', 'true')
|
|
263
357
|
navRail.setAttribute('inert', '')
|
|
@@ -294,6 +388,7 @@ export function createOperationsShell({
|
|
|
294
388
|
if (!viewportChanged && !modeChanged && !forceClose) return railMode
|
|
295
389
|
railViewport = nextViewport
|
|
296
390
|
railMode = nextMode
|
|
391
|
+
clearRailGesture()
|
|
297
392
|
root.dataset.prtsRailMode = nextMode
|
|
298
393
|
root.removeAttribute('data-prts-rail-open')
|
|
299
394
|
syncRailState()
|
|
@@ -320,13 +415,19 @@ export function createOperationsShell({
|
|
|
320
415
|
}
|
|
321
416
|
|
|
322
417
|
function onResponsiveChange() {
|
|
418
|
+
clearRailGesture()
|
|
323
419
|
setRailViewport(window.innerWidth)
|
|
420
|
+
syncRailState()
|
|
324
421
|
settingsOverlay?.scheduleScalePreviewRefresh?.()
|
|
325
422
|
}
|
|
326
423
|
|
|
327
424
|
function bindResponsiveQueries() {
|
|
328
425
|
railViewportQuery = window.matchMedia?.('(min-width: 1180px)')
|
|
426
|
+
railPointerQuery = window.matchMedia?.('(pointer: coarse)')
|
|
427
|
+
railHoverQuery = window.matchMedia?.('(hover: none)')
|
|
329
428
|
railViewportQuery?.addEventListener?.('change', onResponsiveChange)
|
|
429
|
+
railPointerQuery?.addEventListener?.('change', onResponsiveChange)
|
|
430
|
+
railHoverQuery?.addEventListener?.('change', onResponsiveChange)
|
|
330
431
|
}
|
|
331
432
|
function disableTheme() { onThemeDisable() }
|
|
332
433
|
|
|
@@ -367,7 +468,12 @@ export function createOperationsShell({
|
|
|
367
468
|
conversationObserver.observe(operationRegion, { childList: true, subtree: true, attributes: true, attributeFilter: ['hidden', 'data-chat-flow-kind', 'data-message-role'] })
|
|
368
469
|
schemeObserver = new window.MutationObserver(syncSchemeToggle)
|
|
369
470
|
schemeObserver.observe(root, { attributes: true, attributeFilter: ['data-prts-scheme'] })
|
|
370
|
-
railLauncher.addEventListener('click',
|
|
471
|
+
railLauncher.addEventListener('click', onRailClick)
|
|
472
|
+
railLauncher.addEventListener('pointerdown', onRailPointerDown)
|
|
473
|
+
railLauncher.addEventListener('pointermove', onRailPointerMove)
|
|
474
|
+
railLauncher.addEventListener('pointerup', onRailPointerUp)
|
|
475
|
+
railLauncher.addEventListener('pointercancel', clearRailGesture)
|
|
476
|
+
railLauncher.addEventListener('lostpointercapture', onRailLostPointerCapture)
|
|
371
477
|
document.addEventListener('keydown', onRailKeydown)
|
|
372
478
|
document.addEventListener('click', onDocumentClick)
|
|
373
479
|
schemeToggle.addEventListener('click', toggleScheme)
|
|
@@ -384,10 +490,16 @@ export function createOperationsShell({
|
|
|
384
490
|
}
|
|
385
491
|
|
|
386
492
|
function dispose() {
|
|
493
|
+
clearRailGesture()
|
|
387
494
|
cancelSchemePointer()
|
|
388
495
|
clearSchemeClickSuppression()
|
|
389
496
|
clearSchemePressDelays()
|
|
390
|
-
railLauncher?.removeEventListener('click',
|
|
497
|
+
railLauncher?.removeEventListener('click', onRailClick)
|
|
498
|
+
railLauncher?.removeEventListener('pointerdown', onRailPointerDown)
|
|
499
|
+
railLauncher?.removeEventListener('pointermove', onRailPointerMove)
|
|
500
|
+
railLauncher?.removeEventListener('pointerup', onRailPointerUp)
|
|
501
|
+
railLauncher?.removeEventListener('pointercancel', clearRailGesture)
|
|
502
|
+
railLauncher?.removeEventListener('lostpointercapture', onRailLostPointerCapture)
|
|
391
503
|
document.removeEventListener('keydown', onRailKeydown)
|
|
392
504
|
document.removeEventListener('click', onDocumentClick)
|
|
393
505
|
schemeToggle?.removeEventListener('click', toggleScheme)
|
|
@@ -399,7 +511,11 @@ export function createOperationsShell({
|
|
|
399
511
|
window.removeEventListener?.('blur', cancelSchemePointer)
|
|
400
512
|
themeDisable?.removeEventListener('click', disableTheme)
|
|
401
513
|
railViewportQuery?.removeEventListener?.('change', onResponsiveChange)
|
|
514
|
+
railPointerQuery?.removeEventListener?.('change', onResponsiveChange)
|
|
515
|
+
railHoverQuery?.removeEventListener?.('change', onResponsiveChange)
|
|
402
516
|
railViewportQuery = undefined
|
|
517
|
+
railPointerQuery = undefined
|
|
518
|
+
railHoverQuery = undefined
|
|
403
519
|
resizeShield.dispose()
|
|
404
520
|
settingsOverlay?.dispose()
|
|
405
521
|
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 &&
|
|
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()
|
|
@@ -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)
|
package/src/styles/prts.css
CHANGED
|
@@ -294,18 +294,23 @@ html[data-dsh-prts][data-prts-rail-mode="overlay"] [data-prts-rail-launcher]:is(
|
|
|
294
294
|
|
|
295
295
|
@media (hover: none), (pointer: coarse) {
|
|
296
296
|
html[data-dsh-prts][data-prts-rail-mode="overlay"] [data-prts-rail-launcher] {
|
|
297
|
-
top:
|
|
298
|
-
|
|
299
|
-
height: 40px;
|
|
300
|
-
opacity: .92;
|
|
301
|
-
transform: none;
|
|
297
|
+
top: 50%; width: 24px; height: 88px; opacity: .58;
|
|
298
|
+
transform: translateY(-50%); touch-action: none;
|
|
302
299
|
}
|
|
303
|
-
|
|
304
|
-
html[data-dsh-prts][data-prts-rail-
|
|
305
|
-
|
|
300
|
+
html[data-dsh-prts] [data-prts-rail-launcher] > span { opacity: 0; }
|
|
301
|
+
html[data-dsh-prts] [data-prts-rail-launcher][data-prts-rail-gesture-active] { width: 40px; opacity: 1; }
|
|
302
|
+
html[data-dsh-prts] [data-prts-rail-gesture-cue] {
|
|
303
|
+
position: absolute; inset: calc(27px + var(--prts-rail-gesture-progress, 0px)) 10px auto auto;
|
|
304
|
+
display: block; opacity: 0; font: 700 14px/8px sans-serif;
|
|
305
|
+
}
|
|
306
|
+
html[data-dsh-prts] [data-prts-rail-gesture-active] [data-prts-rail-gesture-cue] {
|
|
307
|
+
opacity: 1; animation: prts-rail-swipe-cue 720ms ease-in-out infinite;
|
|
306
308
|
}
|
|
309
|
+
html[data-dsh-prts] [data-prts-rail-gesture-ready] [data-prts-rail-gesture-cue] { filter: drop-shadow(0 0 3px currentColor); }
|
|
307
310
|
}
|
|
308
311
|
|
|
312
|
+
@keyframes prts-rail-swipe-cue { 50% { opacity: .45; } }
|
|
313
|
+
|
|
309
314
|
html[data-dsh-prts] [data-prts-rail-brand] {
|
|
310
315
|
height: 64px;
|
|
311
316
|
display: grid;
|
|
@@ -811,12 +816,18 @@ html[data-dsh-prts] [data-prts-region="operation"] {
|
|
|
811
816
|
color: var(--prts-ink);
|
|
812
817
|
}
|
|
813
818
|
|
|
814
|
-
html[data-dsh-prts][data-prts-
|
|
815
|
-
|
|
819
|
+
html[data-dsh-prts] [data-prts-region="frame"][data-sidebar-collapsed] [data-prts-region="sessions"] :is(
|
|
820
|
+
[data-slot="sidebar.workspaces"],
|
|
821
|
+
[data-slot="sidebar.settings"]
|
|
822
|
+
) {
|
|
816
823
|
opacity: 0;
|
|
817
824
|
pointer-events: none;
|
|
818
825
|
}
|
|
819
826
|
|
|
827
|
+
html[data-dsh-prts] [data-sidebar-collapsed] :is([data-prts-owned-facility], [data-prts-owned-facility-spine], [data-prts-owned-facility-vector]) {
|
|
828
|
+
visibility: hidden; content-visibility: hidden;
|
|
829
|
+
}
|
|
830
|
+
|
|
820
831
|
html[data-dsh-prts] [data-prts-region="sessions"] > *,
|
|
821
832
|
html[data-dsh-prts] [data-prts-region="sessions"] [data-slot="sidebar"] {
|
|
822
833
|
height: 100%;
|
|
@@ -827,11 +838,15 @@ html[data-dsh-prts] [data-prts-region="sessions"] [data-rc7-sidebar-root] {
|
|
|
827
838
|
width: 100% !important;
|
|
828
839
|
min-width: var(--prts-sessions-width);
|
|
829
840
|
padding: 14px 10px;
|
|
830
|
-
overflow
|
|
841
|
+
overflow: hidden auto;
|
|
831
842
|
background: transparent !important;
|
|
832
843
|
color: var(--prts-ink);
|
|
833
844
|
}
|
|
834
845
|
|
|
846
|
+
html[data-dsh-prts] [data-prts-region="sessions"] [data-slot="sidebar.workspaces"] [role="tree"] {
|
|
847
|
+
overflow-x: hidden;
|
|
848
|
+
}
|
|
849
|
+
|
|
835
850
|
html[data-dsh-prts] [data-prts-region="sessions"] > * > [data-slot="sidebar"] > :first-child > button[aria-label*="new session" i] {
|
|
836
851
|
display: none !important;
|
|
837
852
|
}
|
|
@@ -1362,6 +1377,7 @@ html[data-dsh-prts-settings] .prts-plugin-settings {
|
|
|
1362
1377
|
width: 100%;
|
|
1363
1378
|
display: grid;
|
|
1364
1379
|
gap: 16px;
|
|
1380
|
+
container: prts-plugin-settings / inline-size;
|
|
1365
1381
|
color: inherit;
|
|
1366
1382
|
font: inherit;
|
|
1367
1383
|
}
|
|
@@ -1474,6 +1490,19 @@ html[data-dsh-prts-settings] .prts-plugin-settings button[role='switch']:disable
|
|
|
1474
1490
|
}
|
|
1475
1491
|
}
|
|
1476
1492
|
|
|
1493
|
+
@container prts-plugin-settings (max-width: 22rem) {
|
|
1494
|
+
html[data-dsh-prts-settings] .prts-plugin-settings__row {
|
|
1495
|
+
flex-direction: column;
|
|
1496
|
+
align-items: stretch;
|
|
1497
|
+
gap: 10px;
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
html[data-dsh-prts-settings] .prts-plugin-settings button[role='switch'] {
|
|
1501
|
+
align-self: flex-end;
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
|
|
1477
1506
|
|
|
1478
1507
|
@media (max-width: 640px) {
|
|
1479
1508
|
html[data-dsh-prts] {
|