dsh-xueqiu 1.7.2 → 1.8.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/README.en.md CHANGED
@@ -121,6 +121,7 @@ The data layer is defended in depth — safe to leave open for hours:
121
121
 
122
122
  ## Changelog
123
123
 
124
+ - **1.8.0** (2025-08-19) — Pro polish: tabular-nums everywhere (no column jitter), red/green percent chips, and price-change flash animation on watchlist rows.
124
125
  - **1.7.2** (2025-08-19) — News tab pagination: scroll-to-bottom or "load earlier" fetches older items (max_id cursor, deduped); refresh resets to the latest page.
125
126
  - **1.7.1** (2025-08-19) — Fix static install (`dsh plugin add`) crashing `dsh web` startup: dual-mode RPC (harness.handle for dynamic runs, a loopback+same-origin fenced `/xq-rpc` webServer route for static installs) and a proper `__ModuleLoader__` CJS client bundle.
126
127
  - **1.7.0** (2025-08-19) — Hidden-tab polling pause + CN/HK/US market session hints.
package/README.md CHANGED
@@ -151,6 +151,8 @@ dsh-xueqiu/
151
151
 
152
152
  ## 📋 更新日志
153
153
 
154
+ - **1.8.0**(2025-08-19)
155
+ - 专业感升级三件套:全界面等宽数字(tabular-nums,价格跳动不抖列);涨跌幅色块 chip(红涨/绿跌半透明底,扫一眼定位);自选行价格变动闪烁动画(涨红闪/跌绿闪,0.8s 渐隐)。
154
156
  - **1.7.2**(2025-08-19)
155
157
  - 新增:快讯 tab 翻页——滚动到底或点「加载更早」自动加载历史快讯(max_id 游标,自动去重),「刷新」重置回最新一页。
156
158
  - **1.7.1**(2025-08-19)
package/dynamic/client.js CHANGED
@@ -41,6 +41,17 @@ return {
41
41
  '.xq-up{color:var(--dsw-alias-state-error-primary);}\n' +
42
42
  '.xq-down{color:var(--dsw-alias-state-success-primary);}\n' +
43
43
  '.xq-flat{color:var(--dsw-alias-label-secondary);}\n' +
44
+ // 专业感三件套:①等宽数字 ②涨跌幅色块 ③价格闪烁
45
+ '.xq-dock,.xq-badge,.xq-ticker{font-variant-numeric:tabular-nums;}\n' +
46
+ '.xq-pct-chip{display:inline-block;min-width:52px;text-align:center;padding:1px 6px;border-radius:5px;font-size:11.5px;font-weight:600;}\n' +
47
+ '.xq-pct-chip.xq-up{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent);}\n' +
48
+ '.xq-pct-chip.xq-down{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent);}\n' +
49
+ '.xq-pct-chip.xq-flat{background:var(--dsw-alias-bg-layer-2);}\n' +
50
+ '.xq-idx-pct.xq-pct-chip{min-width:46px;padding:0 5px;font-size:10.5px;}\n' +
51
+ '@keyframes xq-flash-up{0%{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 18%, transparent);}100%{background:transparent;}}\n' +
52
+ '@keyframes xq-flash-down{0%{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 18%, transparent);}100%{background:transparent;}}\n' +
53
+ '.xq-flash-up{animation:xq-flash-up .8s ease-out;}\n' +
54
+ '.xq-flash-down{animation:xq-flash-down .8s ease-out;}\n' +
44
55
  '.xq-grid{display:grid;gap:0;border:1px solid var(--dsw-alias-border-l1);border-radius:8px;overflow:hidden;margin-bottom:8px;}\n' +
45
56
  '.xq-grid-hd,.xq-grid-row{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr 84px;align-items:center;}\n' +
46
57
  '.xq-grid-hd{font-size:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);padding:5px 8px;}\n' +
@@ -459,6 +470,9 @@ return {
459
470
  function XueqiuPanel() {
460
471
  const [watchlist, setWatchlist] = React.useState([])
461
472
  const [quotes, setQuotes] = React.useState([])
473
+ // 价格闪烁:记录上一价与变化方向(symbol -> 1|-1),行渲染时挂一次性动画类
474
+ const prevPrices = React.useRef({})
475
+ const [flashDir, setFlashDir] = React.useState({})
462
476
  const [indices, setIndices] = React.useState([])
463
477
  const [hot, setHot] = React.useState([])
464
478
  const [hotMarket, setHotMarket] = React.useState('cn')
@@ -495,7 +509,15 @@ return {
495
509
  setErr('')
496
510
  if (!wl.length) return
497
511
  return call('quote', { symbols: wl }).then(function (data) {
498
- setQuotes((data && data.list) || [])
512
+ const list = (data && data.list) || []
513
+ const dirs = {}
514
+ list.forEach(function (q) {
515
+ const prev = prevPrices.current[q.symbol]
516
+ if (prev !== undefined && q.current !== prev) dirs[q.symbol] = q.current > prev ? 1 : -1
517
+ prevPrices.current[q.symbol] = q.current
518
+ })
519
+ if (Object.keys(dirs).length) setFlashDir(dirs)
520
+ setQuotes(list)
499
521
  })
500
522
  }).catch(function (e) {
501
523
  setErr(String((e && e.message) || e))
@@ -689,7 +711,7 @@ return {
689
711
  el('div', { key: 'n', className: 'xq-idx-name' }, q.name),
690
712
  el('div', { key: 'r', className: 'xq-idx-row' }, [
691
713
  el('span', { key: 'c', className: 'xq-idx-cur ' + colorOf(q.percent) }, fmt(q.current)),
692
- el('span', { key: 'p', className: 'xq-idx-pct ' + colorOf(q.percent) }, fmtPct(q.percent))
714
+ el('span', { key: 'p', className: 'xq-idx-pct xq-pct-chip ' + colorOf(q.percent) }, fmtPct(q.percent))
693
715
  ])
694
716
  ])
695
717
  })
@@ -699,8 +721,8 @@ return {
699
721
  el('div', { key: 'a', className: 'xq-name' }, q.name),
700
722
  el('div', { key: 'b', className: 'xq-sub' }, q.symbol)
701
723
  ]),
702
- el('div', { key: 'c', className: colorOf(q.percent) }, fmt(q.current)),
703
- el('div', { key: 'p', className: colorOf(q.percent) }, fmtPct(q.percent)),
724
+ el('div', { key: 'c', className: colorOf(q.percent) + (flashDir[q.symbol] === 1 ? ' xq-flash-up' : flashDir[q.symbol] === -1 ? ' xq-flash-down' : '') }, fmt(q.current)),
725
+ el('div', { key: 'p' }, el('span', { key: 'pp', className: 'xq-pct-chip ' + colorOf(q.percent) }, fmtPct(q.percent))),
704
726
  el('div', { key: 'v', className: 'xq-sub' }, fmtVol(q.volume)),
705
727
  el('div', { key: 'a2', className: 'xq-actions' }, [
706
728
  el('button', { key: 'd', className: 'xq-btn-mini', onClick: function (e) { e.stopPropagation(); openDetail(q.symbol) } }, '详情'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-xueqiu",
3
- "version": "1.7.2",
3
+ "version": "1.8.0",
4
4
  "description": "雪球 mini 行情面板 — DeepSeek Harness 免登录 A股/港美股实时行情、K线(蜡烛/成交量/均线)、分时图、热榜、搜索、7x24 快讯、热议用户。嵌入式面板 + 可拖拽行情徽标,内置请求节流、TTL 缓存与 Cookie 自动续期。",
5
5
  "keywords": [
6
6
  "dsh",
@@ -60,6 +60,17 @@ exports.default = {
60
60
  '.xq-up{color:var(--dsw-alias-state-error-primary);}\n' +
61
61
  '.xq-down{color:var(--dsw-alias-state-success-primary);}\n' +
62
62
  '.xq-flat{color:var(--dsw-alias-label-secondary);}\n' +
63
+ // 专业感三件套:①等宽数字 ②涨跌幅色块 ③价格闪烁
64
+ '.xq-dock,.xq-badge,.xq-ticker{font-variant-numeric:tabular-nums;}\n' +
65
+ '.xq-pct-chip{display:inline-block;min-width:52px;text-align:center;padding:1px 6px;border-radius:5px;font-size:11.5px;font-weight:600;}\n' +
66
+ '.xq-pct-chip.xq-up{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent);}\n' +
67
+ '.xq-pct-chip.xq-down{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent);}\n' +
68
+ '.xq-pct-chip.xq-flat{background:var(--dsw-alias-bg-layer-2);}\n' +
69
+ '.xq-idx-pct.xq-pct-chip{min-width:46px;padding:0 5px;font-size:10.5px;}\n' +
70
+ '@keyframes xq-flash-up{0%{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 18%, transparent);}100%{background:transparent;}}\n' +
71
+ '@keyframes xq-flash-down{0%{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 18%, transparent);}100%{background:transparent;}}\n' +
72
+ '.xq-flash-up{animation:xq-flash-up .8s ease-out;}\n' +
73
+ '.xq-flash-down{animation:xq-flash-down .8s ease-out;}\n' +
63
74
  '.xq-grid{display:grid;gap:0;border:1px solid var(--dsw-alias-border-l1);border-radius:8px;overflow:hidden;margin-bottom:8px;}\n' +
64
75
  '.xq-grid-hd,.xq-grid-row{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr 84px;align-items:center;}\n' +
65
76
  '.xq-grid-hd{font-size:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);padding:5px 8px;}\n' +
@@ -478,6 +489,9 @@ exports.default = {
478
489
  function XueqiuPanel() {
479
490
  const [watchlist, setWatchlist] = React.useState([])
480
491
  const [quotes, setQuotes] = React.useState([])
492
+ // 价格闪烁:记录上一价与变化方向(symbol -> 1|-1),行渲染时挂一次性动画类
493
+ const prevPrices = React.useRef({})
494
+ const [flashDir, setFlashDir] = React.useState({})
481
495
  const [indices, setIndices] = React.useState([])
482
496
  const [hot, setHot] = React.useState([])
483
497
  const [hotMarket, setHotMarket] = React.useState('cn')
@@ -514,7 +528,15 @@ exports.default = {
514
528
  setErr('')
515
529
  if (!wl.length) return
516
530
  return call('quote', { symbols: wl }).then(function (data) {
517
- setQuotes((data && data.list) || [])
531
+ const list = (data && data.list) || []
532
+ const dirs = {}
533
+ list.forEach(function (q) {
534
+ const prev = prevPrices.current[q.symbol]
535
+ if (prev !== undefined && q.current !== prev) dirs[q.symbol] = q.current > prev ? 1 : -1
536
+ prevPrices.current[q.symbol] = q.current
537
+ })
538
+ if (Object.keys(dirs).length) setFlashDir(dirs)
539
+ setQuotes(list)
518
540
  })
519
541
  }).catch(function (e) {
520
542
  setErr(String((e && e.message) || e))
@@ -708,7 +730,7 @@ exports.default = {
708
730
  el('div', { key: 'n', className: 'xq-idx-name' }, q.name),
709
731
  el('div', { key: 'r', className: 'xq-idx-row' }, [
710
732
  el('span', { key: 'c', className: 'xq-idx-cur ' + colorOf(q.percent) }, fmt(q.current)),
711
- el('span', { key: 'p', className: 'xq-idx-pct ' + colorOf(q.percent) }, fmtPct(q.percent))
733
+ el('span', { key: 'p', className: 'xq-idx-pct xq-pct-chip ' + colorOf(q.percent) }, fmtPct(q.percent))
712
734
  ])
713
735
  ])
714
736
  })
@@ -718,8 +740,8 @@ exports.default = {
718
740
  el('div', { key: 'a', className: 'xq-name' }, q.name),
719
741
  el('div', { key: 'b', className: 'xq-sub' }, q.symbol)
720
742
  ]),
721
- el('div', { key: 'c', className: colorOf(q.percent) }, fmt(q.current)),
722
- el('div', { key: 'p', className: colorOf(q.percent) }, fmtPct(q.percent)),
743
+ el('div', { key: 'c', className: colorOf(q.percent) + (flashDir[q.symbol] === 1 ? ' xq-flash-up' : flashDir[q.symbol] === -1 ? ' xq-flash-down' : '') }, fmt(q.current)),
744
+ el('div', { key: 'p' }, el('span', { key: 'pp', className: 'xq-pct-chip ' + colorOf(q.percent) }, fmtPct(q.percent))),
723
745
  el('div', { key: 'v', className: 'xq-sub' }, fmtVol(q.volume)),
724
746
  el('div', { key: 'a2', className: 'xq-actions' }, [
725
747
  el('button', { key: 'd', className: 'xq-btn-mini', onClick: function (e) { e.stopPropagation(); openDetail(q.symbol) } }, '详情'),