"vscode:/vscode.git/clone" did not exist on "3bec6514156f492e0dca171251d6d928842a3e89"
dcuinfo.go 9.15 KB
Newer Older
liming6's avatar
liming6 committed
1
2
3
package tui

import (
liming6's avatar
liming6 committed
4
	"fmt"
5
	"get-container/utils"
6
	"regexp"
liming6's avatar
liming6 committed
7
8
	"strconv"
	"strings"
liming6's avatar
liming6 committed
9

liming6's avatar
liming6 committed
10
	"github.com/charmbracelet/bubbles/progress"
liming6's avatar
liming6 committed
11
	tea "github.com/charmbracelet/bubbletea"
liming6's avatar
liming6 committed
12
	"github.com/charmbracelet/lipgloss"
liming6's avatar
liming6 committed
13
14
	"github.com/lucasb-eyer/go-colorful"
	"github.com/muesli/gamut"
15
	"github.com/muesli/termenv"
liming6's avatar
liming6 committed
16
17
18
)

type ModelDCUInfo struct {
19
20
21
22
23
24
25
26
27
28
	width, height          int            // 屏幕尺寸
	pro                    progress.Model // 进度条
	proLowLeight           progress.Model // 低亮度进度条
	proWidth               int            // 进度条宽度
	modMsg                 *ModelMsg      // 缓存的模型信息
	actionMsg              *ActionMsg     // 缓存的动作信息
	darkModule             bool           // 是否为黑暗模式
	top, middle, bottom    string         // 缓存的边框
	topL, middleL, bottomL string         // 缓存的低亮度边框
	subLin                 int            // 边框更新标志
liming6's avatar
liming6 committed
29
30
}

liming6's avatar
liming6 committed
31
32
33
34
35
36
const (
	TopLine    = `╞═══════════════════════════════╪══════════════════════╪══════════════════════╪`
	MiddleLine = `├───────────────────────────────┼──────────────────────┼──────────────────────┼`
	BottomLine = `╞═══════════════════════════════╧══════════════════════╧══════════════════════╪`

	OtherWidth       = 8
liming6's avatar
liming6 committed
37
38
	StaticWidth      = 79 // 固定表格的宽度
	ProgressMinWidth = 15 // 进度条最小宽度
liming6's avatar
liming6 committed
39
40
)

41
42
43
44
var (
	ReDCUName = regexp.MustCompile(`(?i)^[A-Z0-9-_]*`)
)

45
func NewModelDCUInfo(w, h int) *ModelDCUInfo {
46
	return &ModelDCUInfo{width: w, height: h, darkModule: false}
liming6's avatar
liming6 committed
47
48
}

liming6's avatar
liming6 committed
49
func (m *ModelDCUInfo) Init() tea.Cmd {
50
	if m.width < StaticWidth+ProgressMinWidth+OtherWidth {
liming6's avatar
liming6 committed
51
52
53
		return tea.Quit
	}
	m.proWidth = ProgressMinWidth
54
55
	if m.width > StaticWidth+ProgressMinWidth+OtherWidth {
		m.proWidth = m.width - OtherWidth - StaticWidth
liming6's avatar
liming6 committed
56
	}
liming6's avatar
liming6 committed
57
58
59
60
	m.pro = progress.New(progress.WithColorProfile(termenv.TrueColor), progress.WithGradient("#0000ffff", "#ff0000ff"), progress.WithWidth(m.proWidth-5), progress.WithoutPercentage())
	c1, _ := colorful.MakeColor(gamut.Darker(lipgloss.Color("#0000ffff"), 0.8))
	c2, _ := colorful.MakeColor(gamut.Darker(lipgloss.Color("#ff0000ff"), 0.8))
	m.proLowLeight = progress.New(progress.WithColorProfile(termenv.TrueColor), progress.WithGradient(c1.Hex(), c2.Hex()), progress.WithWidth(m.proWidth-5), progress.WithoutPercentage())
liming6's avatar
liming6 committed
61
62
63
	return nil
}

liming6's avatar
liming6 committed
64
65
66
func (m *ModelDCUInfo) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := inputMsg.(type) {
	case *ModelMsg:
67
68
69
70
71
		m.modMsg = msg
		return m, nil
	case tea.WindowSizeMsg:
		m.height = msg.Height
		m.width = msg.Width
liming6's avatar
liming6 committed
72
		return m, nil
liming6's avatar
liming6 committed
73
74
	case *ActionMsg:
		m.actionMsg = msg
liming6's avatar
liming6 committed
75
		if msg.Action != nil && msg.VM == VMMain {
76
77
78
79
			m.darkModule = true
		} else {
			m.darkModule = false
		}
liming6's avatar
liming6 committed
80
		return m, nil
liming6's avatar
liming6 committed
81
	}
liming6's avatar
liming6 committed
82
83
84
85
	return m, nil
}

func (m *ModelDCUInfo) View() string {
86
87
88
	if m.modMsg == nil {
		return ""
	}
liming6's avatar
liming6 committed
89
	lineWidth := 0
90
91
	qmap, qlock := m.modMsg.DCUInfo.GetQuitInfo()
	smap, slock := m.modMsg.DCUInfo.GetSlowInfo()
liming6's avatar
liming6 committed
92
	strBuilder := strings.Builder{}
liming6's avatar
liming6 committed
93
94
95
96
97
	strCache := strings.Builder{}
	var targetDCU int = -1
	if m.actionMsg != nil && m.actionMsg.TargetDCUIndex != nil {
		targetDCU = *m.actionMsg.TargetDCUIndex
	}
98
99
100
101
	var borderStr string = myBorder.Left
	if m.darkModule {
		borderStr = LowLeightStyle.Render(borderStr)
	}
102
	infos := make([]string, 0)
liming6's avatar
liming6 committed
103
	for i := range 64 {
104
105
106
107
108
		qinfo, haveq := qmap[i]
		sinfo, haves := smap[i]
		if !(haveq || haves) {
			continue
		}
109
110
		isLowStyle := (targetDCU != qinfo.Id && targetDCU != -1) || m.darkModule
		strBuilder.WriteString(borderStr)
liming6's avatar
liming6 committed
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(strconv.Itoa(qinfo.Id), 4, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(ReDCUName.FindString(qinfo.Name), 8, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(qinfo.PerformanceLevel, 15, lipgloss.Right))
		strCache.WriteByte(' ')

		if isLowStyle {
			str := strCache.String()
			strBuilder.WriteString(LowLeightStyle.Render(str))
		} else {
			strBuilder.WriteString(strCache.String())
		}
		strCache.Reset()
127
		strBuilder.WriteString(borderStr)
liming6's avatar
liming6 committed
128
129
130
131
132
133
134
135
136

		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(qinfo.BusId, 13, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr("Off", 6, lipgloss.Right))
		strCache.WriteByte(' ')
		if isLowStyle {
			str := strCache.String()
			strBuilder.WriteString(LowLeightStyle.Render(str))
liming6's avatar
liming6 committed
137
		} else {
liming6's avatar
liming6 committed
138
			strBuilder.WriteString(strCache.String())
liming6's avatar
liming6 committed
139
		}
liming6's avatar
liming6 committed
140
141
142
143
		strCache.Reset()

		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr("Off", 16, lipgloss.Left))
144
		strBuilder.WriteString(borderStr)
liming6's avatar
liming6 committed
145
		strCache.WriteByte(' ')
146
		if sinfo.Ecc.Load() {
liming6's avatar
liming6 committed
147
148
149
150
151
152
153
154
			strCache.WriteString(FormatStr("On", 3, lipgloss.Right))
		} else {
			strCache.WriteString(FormatStr("Off", 3, lipgloss.Right))
		}
		strCache.WriteByte(' ')
		if isLowStyle {
			str := strCache.String()
			strBuilder.WriteString(LowLeightStyle.Render(str))
liming6's avatar
liming6 committed
155
		} else {
liming6's avatar
liming6 committed
156
			strBuilder.WriteString(strCache.String())
liming6's avatar
liming6 committed
157
		}
liming6's avatar
liming6 committed
158
		strCache.Reset()
159
		strBuilder.WriteString(borderStr)
liming6's avatar
liming6 committed
160
161
162
163
164
165
166
167
168
169

		if isLowStyle {
			strBuilder.WriteString(LowLeightStyle.Render(" DCU: "))
			strBuilder.WriteString(m.proLowLeight.ViewAs(float64(qinfo.DCUUTil / 100)))
			strBuilder.WriteString(LowLeightStyle.Render(fmt.Sprintf(" %3d%% ", int(qinfo.DCUUTil))))
		} else {
			strBuilder.WriteString(" DCU: ")
			strBuilder.WriteString(m.pro.ViewAs(float64(qinfo.DCUUTil / 100)))
			strBuilder.WriteString(fmt.Sprintf(" %3d%% ", int(qinfo.DCUUTil)))
		}
170
		strBuilder.WriteString(borderStr)
liming6's avatar
liming6 committed
171
		strBuilder.WriteByte('\n')
172
		strBuilder.WriteString(borderStr)
liming6's avatar
liming6 committed
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(qinfo.Fan, 4, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(fmt.Sprintf("%.1fC", qinfo.Temp), 6, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(fmt.Sprintf("%.1fW / %.1fW", qinfo.PwrAvg, qinfo.PwrCap), 17, lipgloss.Right))
		strCache.WriteByte(' ')

		if isLowStyle {
			str := strCache.String()
			strBuilder.WriteString(LowLeightStyle.Render(str))
		} else {
			strBuilder.WriteString(strCache.String())
		}
		strCache.Reset()
189
		strBuilder.WriteString(borderStr)
liming6's avatar
liming6 committed
190
191
192
193
194
195
196
197
198
199
200
201
202

		if isLowStyle {
			strCache.WriteByte(' ')
			strCache.WriteString(FormatStr(fmt.Sprintf("%dMiB / %dMiB", qinfo.MemUsed/uint64(utils.MiB), qinfo.MemTotal/uint64(utils.MiB)), 20, lipgloss.Right))
			strCache.WriteByte(' ')
			strBuilder.WriteString(LowLeightStyle.Render(strCache.String()))
			strCache.Reset()
		} else {
			strBuilder.WriteByte(' ')
			strBuilder.WriteString(FormatStr(fmt.Sprintf("%dMiB / %dMiB", qinfo.MemUsed/uint64(utils.MiB), qinfo.MemTotal/uint64(utils.MiB)), 20, lipgloss.Right))
			strBuilder.WriteByte(' ')
		}

203
		strBuilder.WriteString(borderStr)
liming6's avatar
liming6 committed
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

		if isLowStyle {
			strCache.WriteByte(' ')
			strCache.WriteString(FormatStr(fmt.Sprintf("%.1f%%", qinfo.DCUUTil), 6, lipgloss.Left))
			strCache.WriteByte(' ')
			strCache.WriteString(FormatStr(sinfo.PwrMode.Load().(string), 13, lipgloss.Right))
			strCache.WriteByte(' ')
			strBuilder.WriteString(LowLeightStyle.Render(strCache.String()))
			strCache.Reset()
		} else {
			strBuilder.WriteByte(' ')
			strBuilder.WriteString(FormatStr(fmt.Sprintf("%.1f%%", qinfo.DCUUTil), 6, lipgloss.Left))
			strBuilder.WriteByte(' ')
			strBuilder.WriteString(FormatStr(sinfo.PwrMode.Load().(string), 13, lipgloss.Right))
			strBuilder.WriteByte(' ')
		}

221
		strBuilder.WriteString(borderStr)
liming6's avatar
liming6 committed
222
223
224
225
226
227
228
229
230
231
232
233
234
235

		if isLowStyle {
			strCache.WriteString(" Mem: ")
			strCache.WriteString(m.proLowLeight.ViewAs(float64(qinfo.MemUsed) / float64(qinfo.MemTotal)))
			strCache.WriteString(LowLeightStyle.Render(fmt.Sprintf(" %3d%% ", int(100*float64(qinfo.MemUsed)/float64(qinfo.MemTotal)))))
			strBuilder.WriteString(LowLeightStyle.Render(strCache.String()))
			strCache.Reset()
		} else {
			strBuilder.WriteString(" Mem: ")
			strBuilder.WriteString(m.pro.ViewAs(float64(qinfo.MemUsed) / float64(qinfo.MemTotal)))
			strBuilder.WriteByte(' ')
			strBuilder.WriteString(fmt.Sprintf("%3d%%", int(100*float64(qinfo.MemUsed)/float64(qinfo.MemTotal))))
			strBuilder.WriteByte(' ')
		}
236
237
		strBuilder.WriteString(borderStr)
		strBuilder.WriteByte('\n')
238
		infos = append(infos, strBuilder.String())
liming6's avatar
liming6 committed
239
240
		strBuilder.Reset()
	}
241
242
	slock.Unlock()
	qlock.Unlock()
liming6's avatar
liming6 committed
243
244
245
	if len(infos) > 0 {
		lineWidth = lipgloss.Width(infos[0])
	}
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
	subLen := max(lineWidth-StaticWidth-1, 0)
	if subLen != m.subLin {
		top := TopLine + strings.Repeat("═", subLen) + "╕"
		middle := MiddleLine + strings.Repeat("─", subLen) + "┤"
		bottom := BottomLine + strings.Repeat("═", subLen) + "╡"
		m.topL = LowLeightStyle.Render(top) + "\n"
		m.middleL = LowLeightStyle.Render(middle) + "\n"
		m.bottomL = LowLeightStyle.Render(bottom) + "\n"
		m.top = top + "\n"
		m.middle = middle + "\n"
		m.bottom = bottom + "\n"
	}
	if m.darkModule {
		return m.topL + strings.Join(infos, m.middleL) + m.bottomL
	} else {
		return m.top + strings.Join(infos, m.middle) + m.bottom
liming6's avatar
liming6 committed
262
	}
liming6's avatar
liming6 committed
263
}