dsh-xueqiu 1.4.0 → 1.5.0
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/dynamic/client.js +44 -6
- package/dynamic/host.js +7 -1
- package/package.json +1 -1
- package/src/client/index.js +44 -6
- package/src/index.js +7 -1
package/dynamic/client.js
CHANGED
|
@@ -5,7 +5,9 @@ return {
|
|
|
5
5
|
'.xq-dock{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;overflow:hidden;font-size:13px;line-height:1.45;color:var(--dsw-alias-label-primary);margin-bottom:6px;}\n' +
|
|
6
6
|
'.xq-dock *{box-sizing:border-box;}\n' +
|
|
7
7
|
'.xq-dock-head{display:flex;align-items:center;gap:8px;padding:7px 12px;border-bottom:1px solid var(--dsw-alias-border-l1);}\n' +
|
|
8
|
-
'.xq-dock-body{max-height:
|
|
8
|
+
'.xq-dock-body{height:52vh;max-height:80vh;overflow-y:auto;padding:8px 12px 10px;}\n' +
|
|
9
|
+
'.xq-dock-resize{display:flex;align-items:center;justify-content:center;height:12px;cursor:ns-resize;user-select:none;border-top:1px solid var(--dsw-alias-border-l1);}\n' +
|
|
10
|
+
'.xq-dock-resize span{display:block;width:36px;height:3px;border-radius:2px;background:var(--dsw-alias-border-l2);}\n' +
|
|
9
11
|
'.xq-badge{position:fixed;right:16px;bottom:64px;display:flex;align-items:center;gap:8px;padding:5px 12px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);box-shadow:0 6px 24px rgba(0,0,0,.25);font-size:11.5px;line-height:1.4;color:var(--dsw-alias-label-primary);cursor:grab;user-select:none;pointer-events:auto;z-index:1200;}\n' +
|
|
10
12
|
'.xq-badge:active{cursor:grabbing;}\n' +
|
|
11
13
|
'.xq-badge b{color:var(--dsw-alias-brand-primary);}\n' +
|
|
@@ -171,7 +173,7 @@ return {
|
|
|
171
173
|
|
|
172
174
|
// ---------- 共享 UI 状态:面板开合 / 当前标签 / 徽章位置 ----------
|
|
173
175
|
const ui = {
|
|
174
|
-
open: false, tab: 'market', badgePos: null, hydrated: false,
|
|
176
|
+
open: false, tab: 'market', badgePos: null, dockH: null, hydrated: false,
|
|
175
177
|
_fns: [],
|
|
176
178
|
subscribe: function (fn) {
|
|
177
179
|
this._fns.push(fn)
|
|
@@ -195,13 +197,16 @@ return {
|
|
|
195
197
|
}
|
|
196
198
|
|
|
197
199
|
const saveUi = ctx.debounce(function () {
|
|
198
|
-
call('ui.set', { tab: ui.tab, open: ui.open, badgePos: ui.badgePos }).catch(function () { /* 忽略 */ })
|
|
200
|
+
call('ui.set', { tab: ui.tab, open: ui.open, badgePos: ui.badgePos, dockH: ui.dockH }).catch(function () { /* 忽略 */ })
|
|
199
201
|
}, 800)
|
|
200
202
|
|
|
201
203
|
// 徽章拖拽引用(实例唯一)
|
|
202
204
|
let badgeDrag = null
|
|
203
205
|
let badgeMoved = false
|
|
204
206
|
|
|
207
|
+
// 面板高度拖拽引用(实例唯一,避免组件重渲染丢失状态)
|
|
208
|
+
const dockResize = { active: false, startY: 0, startH: 0 }
|
|
209
|
+
|
|
205
210
|
// ---------- K线蜡烛图(成交量 + 均线 + 十字光标/悬浮详情) ----------
|
|
206
211
|
function KlineChart(props) {
|
|
207
212
|
const rows = props.rows || []
|
|
@@ -856,6 +861,9 @@ return {
|
|
|
856
861
|
if (d && d.badgePos && isFinite(Number(d.badgePos.x)) && isFinite(Number(d.badgePos.y))) {
|
|
857
862
|
ui.set({ badgePos: { x: Number(d.badgePos.x), y: Number(d.badgePos.y) } })
|
|
858
863
|
}
|
|
864
|
+
if (d && typeof d.dockH === 'number' && isFinite(d.dockH)) {
|
|
865
|
+
ui.set({ dockH: d.dockH })
|
|
866
|
+
}
|
|
859
867
|
ui.set({ hydrated: true })
|
|
860
868
|
}).catch(function () { ui.set({ hydrated: true }) })
|
|
861
869
|
const off = ui.subscribe(function () { force(function (x) { return x + 1 }) })
|
|
@@ -866,10 +874,35 @@ return {
|
|
|
866
874
|
}
|
|
867
875
|
|
|
868
876
|
function DockPanel() {
|
|
877
|
+
const [, force] = React.useState(0)
|
|
869
878
|
React.useEffect(function () {
|
|
870
|
-
const off = ui.subscribe(function () { if (ui.hydrated) saveUi() })
|
|
879
|
+
const off = ui.subscribe(function () { if (ui.hydrated) saveUi(); force(function (x) { return x + 1 }) })
|
|
871
880
|
return off
|
|
872
881
|
}, [])
|
|
882
|
+
function onDown(e) {
|
|
883
|
+
if (e.pointerType === 'mouse' && e.button !== 0) return
|
|
884
|
+
dockResize.active = true
|
|
885
|
+
dockResize.startY = e.clientY
|
|
886
|
+
dockResize.startH = ui.dockH || defaultDockH()
|
|
887
|
+
try { e.currentTarget.setPointerCapture(e.pointerId) } catch (err) { /* ignore */ }
|
|
888
|
+
}
|
|
889
|
+
function onMove(e) {
|
|
890
|
+
if (!dockResize.active) return
|
|
891
|
+
const vp = viewport()
|
|
892
|
+
const maxH = Math.round((vp ? vp.h : 800) * 0.85)
|
|
893
|
+
let h = dockResize.startH + (e.clientY - dockResize.startY)
|
|
894
|
+
h = Math.min(Math.max(160, h), Math.min(maxH, 1200))
|
|
895
|
+
ui.set({ dockH: h })
|
|
896
|
+
}
|
|
897
|
+
function onUp(e) {
|
|
898
|
+
dockResize.active = false
|
|
899
|
+
try { if (e.currentTarget.hasPointerCapture(e.pointerId)) e.currentTarget.releasePointerCapture(e.pointerId) } catch (err) { /* ignore */ }
|
|
900
|
+
}
|
|
901
|
+
function defaultDockH() {
|
|
902
|
+
try { if (typeof window !== 'undefined' && window.innerHeight) return Math.round(window.innerHeight * 0.52) } catch (e) { /* ignore */ }
|
|
903
|
+
return 420
|
|
904
|
+
}
|
|
905
|
+
const bodyStyle = ui.dockH ? { height: ui.dockH + 'px' } : null
|
|
873
906
|
return el('div', { className: 'xq-dock' }, [
|
|
874
907
|
el('div', { key: 'head', className: 'xq-dock-head' }, [
|
|
875
908
|
el('span', { key: 'logo', className: 'xq-logo' }, [el('b', { key: 'b' }, '雪球'), ' mini']),
|
|
@@ -878,9 +911,14 @@ return {
|
|
|
878
911
|
el('span', { key: 'sp', className: 'xq-spacer' }),
|
|
879
912
|
el('button', { key: 'min', className: 'xq-btn-mini', title: '收起(点右下角徽章重新打开)', onClick: function () { ui.set({ open: false }) } }, '收起 —')
|
|
880
913
|
]),
|
|
881
|
-
el('div', { key: 'body', className: 'xq-dock-body' }, [
|
|
914
|
+
el('div', { key: 'body', className: 'xq-dock-body', style: bodyStyle }, [
|
|
882
915
|
el(XueqiuPanel, { key: 'panel' })
|
|
883
|
-
])
|
|
916
|
+
]),
|
|
917
|
+
el('div', {
|
|
918
|
+
key: 'rs', className: 'xq-dock-resize', title: '拖动调整面板高度(双击复位)',
|
|
919
|
+
onPointerDown: onDown, onPointerMove: onMove, onPointerUp: onUp, onPointerCancel: onUp,
|
|
920
|
+
onDoubleClick: function () { ui.set({ dockH: null }) }
|
|
921
|
+
}, [el('span', { key: 'g' }, null)])
|
|
884
922
|
])
|
|
885
923
|
}
|
|
886
924
|
|
package/dynamic/host.js
CHANGED
|
@@ -464,9 +464,11 @@ return {
|
|
|
464
464
|
|
|
465
465
|
async function actUiGet() {
|
|
466
466
|
const s = await loadUiState()
|
|
467
|
+
const hNum = Number(s.dockH)
|
|
467
468
|
return {
|
|
468
469
|
tab: s.tab || 'market', open: s.open !== false,
|
|
469
|
-
|
|
470
|
+
dockH: (s.dockH !== undefined && isFinite(hNum) && hNum >= 160 && hNum <= 1200) ? hNum : null,
|
|
471
|
+
badgePos: (s.badgePos && isFinite(Number(s.badgePos.x)) && isFinite(Number(s.badgePos.y())))
|
|
470
472
|
? { x: Number(s.badgePos.x), y: Number(s.badgePos.y) } : null
|
|
471
473
|
}
|
|
472
474
|
}
|
|
@@ -478,6 +480,10 @@ return {
|
|
|
478
480
|
if (args.badgePos && typeof args.badgePos === 'object' && isFinite(Number(args.badgePos.x)) && isFinite(Number(args.badgePos.y))) {
|
|
479
481
|
s.badgePos = { x: Number(args.badgePos.x), y: Number(args.badgePos.y) }
|
|
480
482
|
}
|
|
483
|
+
if (args.dockH !== undefined) {
|
|
484
|
+
const dh = Number(args.dockH)
|
|
485
|
+
if (isFinite(dh)) s.dockH = Math.min(Math.max(dh, 160), 1200)
|
|
486
|
+
}
|
|
481
487
|
await saveUiState()
|
|
482
488
|
return { ok: true }
|
|
483
489
|
}
|
package/package.json
CHANGED
package/src/client/index.js
CHANGED
|
@@ -5,7 +5,9 @@ return {
|
|
|
5
5
|
'.xq-dock{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;overflow:hidden;font-size:13px;line-height:1.45;color:var(--dsw-alias-label-primary);margin-bottom:6px;}\n' +
|
|
6
6
|
'.xq-dock *{box-sizing:border-box;}\n' +
|
|
7
7
|
'.xq-dock-head{display:flex;align-items:center;gap:8px;padding:7px 12px;border-bottom:1px solid var(--dsw-alias-border-l1);}\n' +
|
|
8
|
-
'.xq-dock-body{max-height:
|
|
8
|
+
'.xq-dock-body{height:52vh;max-height:80vh;overflow-y:auto;padding:8px 12px 10px;}\n' +
|
|
9
|
+
'.xq-dock-resize{display:flex;align-items:center;justify-content:center;height:12px;cursor:ns-resize;user-select:none;border-top:1px solid var(--dsw-alias-border-l1);}\n' +
|
|
10
|
+
'.xq-dock-resize span{display:block;width:36px;height:3px;border-radius:2px;background:var(--dsw-alias-border-l2);}\n' +
|
|
9
11
|
'.xq-badge{position:fixed;right:16px;bottom:64px;display:flex;align-items:center;gap:8px;padding:5px 12px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);box-shadow:0 6px 24px rgba(0,0,0,.25);font-size:11.5px;line-height:1.4;color:var(--dsw-alias-label-primary);cursor:grab;user-select:none;pointer-events:auto;z-index:1200;}\n' +
|
|
10
12
|
'.xq-badge:active{cursor:grabbing;}\n' +
|
|
11
13
|
'.xq-badge b{color:var(--dsw-alias-brand-primary);}\n' +
|
|
@@ -171,7 +173,7 @@ return {
|
|
|
171
173
|
|
|
172
174
|
// ---------- 共享 UI 状态:面板开合 / 当前标签 / 徽章位置 ----------
|
|
173
175
|
const ui = {
|
|
174
|
-
open: false, tab: 'market', badgePos: null, hydrated: false,
|
|
176
|
+
open: false, tab: 'market', badgePos: null, dockH: null, hydrated: false,
|
|
175
177
|
_fns: [],
|
|
176
178
|
subscribe: function (fn) {
|
|
177
179
|
this._fns.push(fn)
|
|
@@ -195,13 +197,16 @@ return {
|
|
|
195
197
|
}
|
|
196
198
|
|
|
197
199
|
const saveUi = ctx.debounce(function () {
|
|
198
|
-
call('ui.set', { tab: ui.tab, open: ui.open, badgePos: ui.badgePos }).catch(function () { /* 忽略 */ })
|
|
200
|
+
call('ui.set', { tab: ui.tab, open: ui.open, badgePos: ui.badgePos, dockH: ui.dockH }).catch(function () { /* 忽略 */ })
|
|
199
201
|
}, 800)
|
|
200
202
|
|
|
201
203
|
// 徽章拖拽引用(实例唯一)
|
|
202
204
|
let badgeDrag = null
|
|
203
205
|
let badgeMoved = false
|
|
204
206
|
|
|
207
|
+
// 面板高度拖拽引用(实例唯一,避免组件重渲染丢失状态)
|
|
208
|
+
const dockResize = { active: false, startY: 0, startH: 0 }
|
|
209
|
+
|
|
205
210
|
// ---------- K线蜡烛图(成交量 + 均线 + 十字光标/悬浮详情) ----------
|
|
206
211
|
function KlineChart(props) {
|
|
207
212
|
const rows = props.rows || []
|
|
@@ -856,6 +861,9 @@ return {
|
|
|
856
861
|
if (d && d.badgePos && isFinite(Number(d.badgePos.x)) && isFinite(Number(d.badgePos.y))) {
|
|
857
862
|
ui.set({ badgePos: { x: Number(d.badgePos.x), y: Number(d.badgePos.y) } })
|
|
858
863
|
}
|
|
864
|
+
if (d && typeof d.dockH === 'number' && isFinite(d.dockH)) {
|
|
865
|
+
ui.set({ dockH: d.dockH })
|
|
866
|
+
}
|
|
859
867
|
ui.set({ hydrated: true })
|
|
860
868
|
}).catch(function () { ui.set({ hydrated: true }) })
|
|
861
869
|
const off = ui.subscribe(function () { force(function (x) { return x + 1 }) })
|
|
@@ -866,10 +874,35 @@ return {
|
|
|
866
874
|
}
|
|
867
875
|
|
|
868
876
|
function DockPanel() {
|
|
877
|
+
const [, force] = React.useState(0)
|
|
869
878
|
React.useEffect(function () {
|
|
870
|
-
const off = ui.subscribe(function () { if (ui.hydrated) saveUi() })
|
|
879
|
+
const off = ui.subscribe(function () { if (ui.hydrated) saveUi(); force(function (x) { return x + 1 }) })
|
|
871
880
|
return off
|
|
872
881
|
}, [])
|
|
882
|
+
function onDown(e) {
|
|
883
|
+
if (e.pointerType === 'mouse' && e.button !== 0) return
|
|
884
|
+
dockResize.active = true
|
|
885
|
+
dockResize.startY = e.clientY
|
|
886
|
+
dockResize.startH = ui.dockH || defaultDockH()
|
|
887
|
+
try { e.currentTarget.setPointerCapture(e.pointerId) } catch (err) { /* ignore */ }
|
|
888
|
+
}
|
|
889
|
+
function onMove(e) {
|
|
890
|
+
if (!dockResize.active) return
|
|
891
|
+
const vp = viewport()
|
|
892
|
+
const maxH = Math.round((vp ? vp.h : 800) * 0.85)
|
|
893
|
+
let h = dockResize.startH + (e.clientY - dockResize.startY)
|
|
894
|
+
h = Math.min(Math.max(160, h), Math.min(maxH, 1200))
|
|
895
|
+
ui.set({ dockH: h })
|
|
896
|
+
}
|
|
897
|
+
function onUp(e) {
|
|
898
|
+
dockResize.active = false
|
|
899
|
+
try { if (e.currentTarget.hasPointerCapture(e.pointerId)) e.currentTarget.releasePointerCapture(e.pointerId) } catch (err) { /* ignore */ }
|
|
900
|
+
}
|
|
901
|
+
function defaultDockH() {
|
|
902
|
+
try { if (typeof window !== 'undefined' && window.innerHeight) return Math.round(window.innerHeight * 0.52) } catch (e) { /* ignore */ }
|
|
903
|
+
return 420
|
|
904
|
+
}
|
|
905
|
+
const bodyStyle = ui.dockH ? { height: ui.dockH + 'px' } : null
|
|
873
906
|
return el('div', { className: 'xq-dock' }, [
|
|
874
907
|
el('div', { key: 'head', className: 'xq-dock-head' }, [
|
|
875
908
|
el('span', { key: 'logo', className: 'xq-logo' }, [el('b', { key: 'b' }, '雪球'), ' mini']),
|
|
@@ -878,9 +911,14 @@ return {
|
|
|
878
911
|
el('span', { key: 'sp', className: 'xq-spacer' }),
|
|
879
912
|
el('button', { key: 'min', className: 'xq-btn-mini', title: '收起(点右下角徽章重新打开)', onClick: function () { ui.set({ open: false }) } }, '收起 —')
|
|
880
913
|
]),
|
|
881
|
-
el('div', { key: 'body', className: 'xq-dock-body' }, [
|
|
914
|
+
el('div', { key: 'body', className: 'xq-dock-body', style: bodyStyle }, [
|
|
882
915
|
el(XueqiuPanel, { key: 'panel' })
|
|
883
|
-
])
|
|
916
|
+
]),
|
|
917
|
+
el('div', {
|
|
918
|
+
key: 'rs', className: 'xq-dock-resize', title: '拖动调整面板高度(双击复位)',
|
|
919
|
+
onPointerDown: onDown, onPointerMove: onMove, onPointerUp: onUp, onPointerCancel: onUp,
|
|
920
|
+
onDoubleClick: function () { ui.set({ dockH: null }) }
|
|
921
|
+
}, [el('span', { key: 'g' }, null)])
|
|
884
922
|
])
|
|
885
923
|
}
|
|
886
924
|
|
package/src/index.js
CHANGED
|
@@ -464,9 +464,11 @@ export default {
|
|
|
464
464
|
|
|
465
465
|
async function actUiGet() {
|
|
466
466
|
const s = await loadUiState()
|
|
467
|
+
const hNum = Number(s.dockH)
|
|
467
468
|
return {
|
|
468
469
|
tab: s.tab || 'market', open: s.open !== false,
|
|
469
|
-
|
|
470
|
+
dockH: (s.dockH !== undefined && isFinite(hNum) && hNum >= 160 && hNum <= 1200) ? hNum : null,
|
|
471
|
+
badgePos: (s.badgePos && isFinite(Number(s.badgePos.x)) && isFinite(Number(s.badgePos.y())))
|
|
470
472
|
? { x: Number(s.badgePos.x), y: Number(s.badgePos.y) } : null
|
|
471
473
|
}
|
|
472
474
|
}
|
|
@@ -478,6 +480,10 @@ export default {
|
|
|
478
480
|
if (args.badgePos && typeof args.badgePos === 'object' && isFinite(Number(args.badgePos.x)) && isFinite(Number(args.badgePos.y))) {
|
|
479
481
|
s.badgePos = { x: Number(args.badgePos.x), y: Number(args.badgePos.y) }
|
|
480
482
|
}
|
|
483
|
+
if (args.dockH !== undefined) {
|
|
484
|
+
const dh = Number(args.dockH)
|
|
485
|
+
if (isFinite(dh)) s.dockH = Math.min(Math.max(dh, 160), 1200)
|
|
486
|
+
}
|
|
481
487
|
await saveUiState()
|
|
482
488
|
return { ok: true }
|
|
483
489
|
}
|