dsh-notify-yimit 0.1.3 → 0.1.4

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.
@@ -19,14 +19,182 @@ function Send-Report([object]$obj) {
19
19
  } catch { }
20
20
  }
21
21
 
22
+ # 编辑模式几何回传:样板窗当前 left/top/width/height(工作区相对坐标)。
23
+ function Send-Geometry($w) {
24
+ try {
25
+ $work = [System.Windows.SystemParameters]::WorkArea
26
+ Send-Report @{
27
+ type = 'geometry'
28
+ left = [Math]::Round($w.Left - $work.Left)
29
+ top = [Math]::Round($w.Top - $work.Top)
30
+ width = [Math]::Round($w.ActualWidth)
31
+ height = [Math]::Round($w.ActualHeight)
32
+ }
33
+ } catch { }
34
+ }
35
+
36
+ # 编辑模式样板窗:拖拽移动 + 右下角手柄缩放;拖拽/缩放结束后回传 geometry。
37
+ # 位置与宽度写回配置后,所有后续浮窗按新几何弹出。
38
+ function New-EditSample($cmd) {
39
+ $bg = Parse-Color ([string]$cmd.bg) "#203a5c"
40
+ $fg = Parse-Color ([string]$cmd.fg) "#e8f0fb"
41
+ $bgBrush = New-Object System.Windows.Media.SolidColorBrush($bg)
42
+ $fgBrush = New-Object System.Windows.Media.SolidColorBrush($fg)
43
+
44
+ $win = New-Object System.Windows.Window
45
+ $win.WindowStyle = [System.Windows.WindowStyle]::None
46
+ $win.AllowsTransparency = $true
47
+ $win.Background = [System.Windows.Media.Brushes]::Transparent
48
+ $win.Topmost = $true
49
+ $win.ShowInTaskbar = $false
50
+ if ($null -ne $cmd.width) { $win.Width = [double]$cmd.width } else { $win.Width = 340 }
51
+ $win.SizeToContent = [System.Windows.SizeToContent]::Height
52
+
53
+ $border = New-Object System.Windows.Controls.Border
54
+ $border.Background = $bgBrush
55
+ $border.BorderBrush = $fgBrush
56
+ $border.BorderThickness = New-Object System.Windows.Thickness(1)
57
+ $border.CornerRadius = New-Object System.Windows.CornerRadius(12)
58
+ $border.Margin = New-Object System.Windows.Thickness(12)
59
+
60
+ $root = New-Object System.Windows.Controls.Grid
61
+ $root.Margin = New-Object System.Windows.Thickness(14,12,14,12)
62
+ $border.Child = $root
63
+
64
+ $stack = New-Object System.Windows.Controls.StackPanel
65
+ $titleText = New-Object System.Windows.Controls.TextBlock
66
+ $titleText.Text = if ([string]::IsNullOrEmpty([string]$cmd.title)) { "Notification preview" } else { [string]$cmd.title }
67
+ $titleText.Foreground = $fgBrush
68
+ $titleText.FontFamily = New-Object System.Windows.Media.FontFamily("Segoe UI, Microsoft YaHei UI")
69
+ $titleText.FontSize = 13
70
+ $titleText.FontWeight = [System.Windows.FontWeights]::SemiBold
71
+ $titleText.Margin = New-Object System.Windows.Thickness(0,0,0,6)
72
+ $stack.Children.Add($titleText) | Out-Null
73
+ $bodyText = New-Object System.Windows.Controls.TextBlock
74
+ $bodyText.Text = "拖动移动 · 拖拽窗口左右边缘调整宽度 · 完成后在设置页点「完成编辑」"
75
+ $bodyText.Foreground = $fgBrush
76
+ $bodyText.FontFamily = New-Object System.Windows.Media.FontFamily("Segoe UI, Microsoft YaHei UI")
77
+ $bodyText.FontSize = 12
78
+ $bodyText.TextWrapping = [System.Windows.TextWrapping]::Wrap
79
+ $stack.Children.Add($bodyText) | Out-Null
80
+ $root.Children.Add($stack) | Out-Null
81
+
82
+ # 左右边缘缩放条(像 Windows 窗口一样拖拽边缘调宽度):8px 宽、通高,
83
+ # 半透明文字色填充提示可拖拽区域,光标为左右双向箭头。
84
+ $edgeBrush = New-Object System.Windows.Media.SolidColorBrush([System.Windows.Media.Color]::FromArgb(38, $fg.R, $fg.G, $fg.B))
85
+ $leftStrip = New-Object System.Windows.Controls.Border
86
+ $leftStrip.Width = 8
87
+ $leftStrip.Cursor = [System.Windows.Input.Cursors]::SizeWE
88
+ $leftStrip.HorizontalAlignment = [System.Windows.HorizontalAlignment]::Left
89
+ $leftStrip.VerticalAlignment = [System.Windows.VerticalAlignment]::Stretch
90
+ $leftStrip.Background = $edgeBrush
91
+ $leftStrip.CornerRadius = New-Object System.Windows.CornerRadius(12,0,0,12)
92
+ $rightStrip = New-Object System.Windows.Controls.Border
93
+ $rightStrip.Width = 8
94
+ $rightStrip.Cursor = [System.Windows.Input.Cursors]::SizeWE
95
+ $rightStrip.HorizontalAlignment = [System.Windows.HorizontalAlignment]::Right
96
+ $rightStrip.VerticalAlignment = [System.Windows.VerticalAlignment]::Stretch
97
+ $rightStrip.Background = $edgeBrush
98
+ $rightStrip.CornerRadius = New-Object System.Windows.CornerRadius(0,12,12,0)
99
+
100
+ # 外层 Grid:边框 + 左右缩放条叠放(缩放条覆盖窗口左右边缘)
101
+ $outer = New-Object System.Windows.Controls.Grid
102
+ $outer.Children.Add($border) | Out-Null
103
+ $outer.Children.Add($leftStrip) | Out-Null
104
+ $outer.Children.Add($rightStrip) | Out-Null
105
+
106
+ # 共享拖拽/缩放状态(事件回调看不到函数局部变量,放 Tag)
107
+ $win.Tag = @{ resizing = $false; startX = 0.0; startWidth = 0.0; startLeft = 0.0; edge = 'right' }
108
+
109
+ $win.Add_Loaded({
110
+ $work = [System.Windows.SystemParameters]::WorkArea
111
+ $pos = $cmd.position
112
+ if ($null -ne $pos -and $null -ne $pos.left -and $null -ne $pos.top) {
113
+ $win.Left = [double]$pos.left + $work.Left
114
+ $win.Top = [double]$pos.top + $work.Top
115
+ } else {
116
+ $win.Left = $work.Right - $win.ActualWidth - 20
117
+ $win.Top = $work.Bottom - $win.ActualHeight - 20
118
+ }
119
+ Send-Geometry $win
120
+ }.GetNewClosure()) | Out-Null
121
+
122
+ # 拖拽移动(缩放条区域除外):DragMove 阻塞至松开,结束后收敛到工作区内并回传几何。
123
+ $win.Add_MouseLeftButtonDown({
124
+ if ($win.Tag.resizing) { $win.Tag.resizing = $false; return }
125
+ try {
126
+ $win.DragMove()
127
+ } catch { }
128
+ try {
129
+ $work = [System.Windows.SystemParameters]::WorkArea
130
+ $win.Left = [Math]::Max($work.Left, [Math]::Min($win.Left, $work.Right - $win.ActualWidth))
131
+ $win.Top = [Math]::Max($work.Top, [Math]::Min($win.Top, $work.Bottom - $win.ActualHeight))
132
+ } catch { }
133
+ Send-Geometry $win
134
+ }.GetNewClosure()) | Out-Null
135
+
136
+ # 拖拽边缘缩放宽度(260–520):右缘拖右变宽;左缘拖左变宽且右缘固定(窗口左移)。
137
+ # 注意:$strip/$edge/$win 都作为函数参数,闭包才能可靠捕获。
138
+ function Add-EdgeResize($strip, [string]$edge, $w) {
139
+ $strip.Add_MouseLeftButtonDown({
140
+ $w.Tag.resizing = $true
141
+ $w.Tag.edge = $edge
142
+ $w.Tag.startX = $_.GetPosition($w).X
143
+ $w.Tag.startWidth = $w.ActualWidth
144
+ $w.Tag.startLeft = $w.Left
145
+ $strip.CaptureMouse()
146
+ $_.Handled = $true
147
+ }.GetNewClosure()) | Out-Null
148
+ $strip.Add_MouseMove({
149
+ if ($w.Tag.resizing) {
150
+ $dx = $_.GetPosition($w).X - $w.Tag.startX
151
+ if ($w.Tag.edge -eq 'left') {
152
+ $nw = [Math]::Max(260, [Math]::Min(520, [Math]::Round($w.Tag.startWidth - $dx)))
153
+ $w.Width = $nw
154
+ $w.Left = $w.Tag.startLeft + ($w.Tag.startWidth - $w.Width)
155
+ } else {
156
+ $nw = [Math]::Max(260, [Math]::Min(520, [Math]::Round($w.Tag.startWidth + $dx)))
157
+ $w.Width = $nw
158
+ }
159
+ $_.Handled = $true
160
+ }
161
+ }.GetNewClosure()) | Out-Null
162
+ $strip.Add_MouseLeftButtonUp({
163
+ if ($w.Tag.resizing) {
164
+ $w.Tag.resizing = $false
165
+ if ($strip.IsMouseCaptured) { $strip.ReleaseMouseCapture() }
166
+ Send-Geometry $w
167
+ $_.Handled = $true
168
+ }
169
+ }.GetNewClosure()) | Out-Null
170
+ }
171
+ Add-EdgeResize $leftStrip 'left' $win
172
+ Add-EdgeResize $rightStrip 'right' $win
173
+
174
+ $win.Add_Closed({
175
+ if ($script:editSample -eq $win) { $script:editSample = $null }
176
+ }.GetNewClosure()) | Out-Null
177
+
178
+ $win.Content = $outer
179
+ return $win
180
+ }
181
+
22
182
  $script:toasts = @{}
23
183
  $script:exitRequested = $false
184
+ # 编辑模式样板窗(不进入 toasts 注册表,不参与堆叠;edit-end 时关闭)。
185
+ $script:editSample = $null
24
186
 
25
187
  function Parse-Color([string]$hex, [string]$fallback) {
26
188
  $h = $hex.TrimStart('#')
27
- if ($h.Length -eq 3) { $h = ($h.ToCharArray() | ForEach-Object { "$$_" }) -join '' }
189
+ if ($h.Length -eq 3) { $h = ($h.ToCharArray() | ForEach-Object { "$_$_" }) -join '' }
28
190
  if ($h.Length -eq 6) { $h = "FF$h" }
29
- if ($h.Length -ne 8 -or $h -notmatch '^[0-9a-fA-F]{8}$') { $h = $fallback.TrimStart('#') }
191
+ if ($h.Length -ne 8 -or $h -notmatch '^[0-9a-fA-F]{8}$') {
192
+ # 非法/缺失输入:改用回退色并同样做 3/6 位展开 + 补 FF(此前 FF 步骤在回退赋值之前,
193
+ # 回退为 6 位时未补前缀,Substring 越界抛异常)。
194
+ $h = $fallback.TrimStart('#')
195
+ if ($h.Length -eq 3) { $h = ($h.ToCharArray() | ForEach-Object { "$_$_" }) -join '' }
196
+ if ($h.Length -eq 6) { $h = "FF$h" }
197
+ }
30
198
  return [System.Windows.Media.Color]::FromArgb(
31
199
  [Convert]::ToInt32($h.Substring(0,2), 16),
32
200
  [Convert]::ToInt32($h.Substring(2,2), 16),
@@ -136,7 +304,8 @@ function New-ToastWindow($cmd) {
136
304
  $win.Background = [System.Windows.Media.Brushes]::Transparent
137
305
  $win.Topmost = $true
138
306
  $win.ShowInTaskbar = $false
139
- $win.Width = 340
307
+ # 通知窗口样式:宽度来自配置(默认 340);高度自适应内容。
308
+ if ($null -ne $cmd.width) { $win.Width = [double]$cmd.width } else { $win.Width = 340 }
140
309
  $win.SizeToContent = [System.Windows.SizeToContent]::Height
141
310
  if (-not [string]::IsNullOrEmpty([string]$cmd.winTitle)) { $win.Title = [string]$cmd.winTitle }
142
311
 
@@ -199,8 +368,16 @@ function New-ToastWindow($cmd) {
199
368
 
200
369
  $win.Add_Loaded({
201
370
  $work = [System.Windows.SystemParameters]::WorkArea
202
- $targetLeft = $work.Right - $win.ActualWidth - 20
203
- $targetTop = $work.Bottom - $win.ActualHeight - 20 - [int]$cmd.offsetY
371
+ # 通知窗口位置:配置了自定义位置(position)则按其坐标(工作区相对)+ 堆叠偏移;
372
+ # 否则默认右下贴边(右/下留边 20)。
373
+ $pos = $cmd.position
374
+ if ($null -ne $pos -and $null -ne $pos.left -and $null -ne $pos.top) {
375
+ $targetLeft = [double]$pos.left + $work.Left
376
+ $targetTop = [double]$pos.top + $work.Top - [int]$cmd.offsetY
377
+ } else {
378
+ $targetLeft = $work.Right - $win.ActualWidth - 20
379
+ $targetTop = $work.Bottom - $win.ActualHeight - 20 - [int]$cmd.offsetY
380
+ }
204
381
  $win.Left = $targetLeft
205
382
  $win.Top = $targetTop + 32
206
383
  $win.Opacity = 0
@@ -295,12 +472,39 @@ function Invoke-Command([string]$line) {
295
472
  $slide = New-Object System.Windows.Media.Animation.DoubleAnimation($rec.Win.Top, $top, [TimeSpan]::FromMilliseconds(220))
296
473
  $slide.EasingFunction = $easeMove
297
474
  $rec.Win.BeginAnimation([System.Windows.Window]::TopProperty, $slide)
475
+ # 可选横向定位:left 数字 = 绝对 X(工作区相对);left 'default' = 默认右下贴边
476
+ # (工作区右缘 - 宽度 - 20)。用于编辑调整位置/恢复默认后,在屏浮窗立即到位。
477
+ if ($null -ne $cmd.left) {
478
+ $newLeft = 0.0
479
+ if ($cmd.left -eq 'default') {
480
+ $work = [System.Windows.SystemParameters]::WorkArea
481
+ $newLeft = $work.Right - $rec.Win.ActualWidth - 20
482
+ } else {
483
+ $newLeft = [double]$cmd.left
484
+ }
485
+ $slideL = New-Object System.Windows.Media.Animation.DoubleAnimation($rec.Win.Left, $newLeft, [TimeSpan]::FromMilliseconds(220))
486
+ $slideL.EasingFunction = $easeMove
487
+ $rec.Win.BeginAnimation([System.Windows.Window]::LeftProperty, $slideL)
488
+ }
298
489
  }
299
490
  }
300
491
  'close' {
301
492
  $rec = $script:toasts[[string]$cmd.key]
302
493
  if ($rec -ne $null) { Close-WithFade $rec.Win }
303
494
  }
495
+ 'size' {
496
+ $rec = $script:toasts[[string]$cmd.key]
497
+ if ($rec -ne $null -and $null -ne $cmd.width) { $rec.Win.Width = [double]$cmd.width }
498
+ }
499
+ 'edit' {
500
+ # 编辑模式:关闭旧样板(如有),弹新样板窗(可拖拽/缩放)。
501
+ if ($script:editSample -ne $null) { try { $script:editSample.Close() } catch { } ; $script:editSample = $null }
502
+ $w = New-EditSample $cmd
503
+ if ($w -ne $null) { $w.Show(); $script:editSample = $w }
504
+ }
505
+ 'edit-end' {
506
+ if ($script:editSample -ne $null) { try { $script:editSample.Close() } catch { } ; $script:editSample = $null }
507
+ }
304
508
  'shutdown' { $script:exitRequested = $true }
305
509
  }
306
510
  }
@@ -340,6 +544,10 @@ $cmdTimer.Add_Tick({
340
544
  foreach ($key in @($script:toasts.Keys)) {
341
545
  try { $script:toasts[$key].Win.Close() } catch { }
342
546
  }
547
+ if ($script:editSample -ne $null) {
548
+ try { $script:editSample.Close() } catch { }
549
+ $script:editSample = $null
550
+ }
343
551
  [System.Windows.Threading.Dispatcher]::CurrentDispatcher.InvokeShutdown()
344
552
  }
345
553
  } catch { }
@@ -10,6 +10,16 @@ import {
10
10
  const kindColorSchema = z.object({
11
11
  bg: z.string(),
12
12
  fg: z.string(),
13
+ enabled: z.boolean(),
14
+ })
15
+
16
+ const toastSchema = z.object({
17
+ width: z.number(),
18
+ gap: z.number(),
19
+ position: z.object({
20
+ left: z.number(),
21
+ top: z.number(),
22
+ }).nullable(),
13
23
  })
14
24
 
15
25
  const configSchema = z.object({
@@ -21,6 +31,7 @@ const configSchema = z.object({
21
31
  bgColor: z.string(),
22
32
  textColor: z.string(),
23
33
  locale: z.enum(['zh', 'en']),
34
+ toast: toastSchema,
24
35
  colors: z.object({
25
36
  completed: kindColorSchema,
26
37
  error: kindColorSchema,
@@ -153,6 +164,28 @@ export const TYPERT = {
153
164
  parameters: [],
154
165
  result: _browsers$codec,
155
166
  },
167
+ {
168
+ id: 'dsh-notify-yimit#notify/startEditMode',
169
+ service: 'notify',
170
+ namespace: 'notify',
171
+ method: 'startEditMode',
172
+ invocation: {
173
+ kind: 'direct'
174
+ },
175
+ parameters: [],
176
+ result: _ack$codec,
177
+ },
178
+ {
179
+ id: 'dsh-notify-yimit#notify/endEditMode',
180
+ service: 'notify',
181
+ namespace: 'notify',
182
+ method: 'endEditMode',
183
+ invocation: {
184
+ kind: 'direct'
185
+ },
186
+ parameters: [],
187
+ result: _ack$codec,
188
+ },
156
189
  ],
157
190
  model: {
158
191
  services: [{
@@ -191,4 +224,4 @@ export const TYPERT = {
191
224
  },
192
225
  }
193
226
 
194
- export default TYPERT
227
+ export default TYPERT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-notify-yimit",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "DeepSeek Harness 通知插件:任务完成 / 任务出错 / 运行中(实时活动)/ 等待审批 / 等待回答 时,通过 Windows 系统通知或插件自定义样式通知提醒用户,支持点击跳转到对应会话;设置页集成在 DSH 设置界面。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",