-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodel.go
More file actions
132 lines (113 loc) · 2.61 KB
/
Copy pathmodel.go
File metadata and controls
132 lines (113 loc) · 2.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// [Input] 服务器列表、用户输入事件
// [Output] Bubble Tea Model
// [Pos] TUI 状态模型,管理选择器状态与过滤逻辑
package main
import (
"fmt"
"strings"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
)
// appMode 应用模式
type appMode int
const (
ModeSSH appMode = iota
ModeSFTP
)
// model Bubble Tea 主模型
type model struct {
allServers []Server // 全量服务器列表
filtered []Server // 过滤后的列表
cursor int // 当前光标位置
input textinput.Model // 搜索输入框
selected *Server // 选中的服务器
mode appMode // 当前模式
quitting bool
}
// newModel 创建模型实例
func newModel(servers []Server) model {
ti := textinput.New()
ti.Placeholder = "输入关键字搜索服务器..."
ti.Focus()
ti.CharLimit = 50
ti.Width = 40
return model{
allServers: servers,
filtered: servers,
cursor: 0,
input: ti,
}
}
// Init 初始化
func (m model) Init() tea.Cmd {
return textinput.Blink
}
// Update 处理事件
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.Type {
case tea.KeyCtrlC, tea.KeyEsc:
m.quitting = true
return m, tea.Quit
case tea.KeyTab:
if m.mode == ModeSSH {
m.mode = ModeSFTP
} else {
m.mode = ModeSSH
}
case tea.KeyUp:
if m.cursor > 0 {
m.cursor--
}
case tea.KeyDown:
if m.cursor < len(m.filtered)-1 {
m.cursor++
}
case tea.KeyEnter:
if len(m.filtered) > 0 && m.cursor < len(m.filtered) {
s := m.filtered[m.cursor]
m.selected = &s
}
return m, tea.Quit
default:
// 搜索框输入时实时过滤
var cmd tea.Cmd
m.input, cmd = m.input.Update(msg)
m.filterServers()
// 过滤后重置光标
if m.cursor >= len(m.filtered) {
m.cursor = max(0, len(m.filtered)-1)
}
return m, cmd
}
}
return m, nil
}
// filterServers 根据搜索关键字过滤服务器
func (m *model) filterServers() {
keyword := strings.ToLower(m.input.Value())
if keyword == "" {
m.filtered = m.allServers
return
}
var result []Server
for _, s := range m.allServers {
if matchServer(s, keyword) {
result = append(result, s)
}
}
m.filtered = result
}
// matchServer 检查服务器是否匹配关键字
func matchServer(s Server, keyword string) bool {
searchable := strings.ToLower(fmt.Sprintf("%s %s %s %s %d",
s.Name, s.Group, s.Host, s.User, s.Port))
return strings.Contains(searchable, keyword)
}
func max(a, b int) int {
if a > b {
return a
}
return b
}