desktop.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // package desktop -- консольный клиент для вар-танка
  2. package desktop
  3. import (
  4. "fmt"
  5. "time"
  6. "github.com/charmbracelet/bubbles/textinput"
  7. tea "github.com/charmbracelet/bubbletea"
  8. "wartank/desktop/client_serv"
  9. "wartank/desktop/win_config"
  10. "wartank/desktop/win_config_server"
  11. "wartank/desktop/win_config_server_host_input"
  12. "wartank/desktop/win_config_server_login_input"
  13. "wartank/desktop/win_config_server_pass_input"
  14. "wartank/desktop/win_default"
  15. "wartank/desktop/win_server_connect"
  16. "wartank/pkg/alias"
  17. "wartank/pkg/cons"
  18. "wartank/pkg/types"
  19. )
  20. // Desktop -- консольный клиент для вар-танка
  21. type Desktop struct {
  22. TeaModel
  23. winName alias.AWinName // Режим показа на экране
  24. p *tea.Program // Объект приложения
  25. client *client_serv.ClientServ // Клиент подключния к бото-серверу
  26. isConnect bool // Признак подключения к бот-серверу
  27. isLogin bool // Признак логина на сервер
  28. isMakeAdmin bool // Признак создания админа
  29. dictWin map[alias.AWinName]types.ITermWin // Список окон показа
  30. }
  31. var desk *Desktop
  32. func NewDesktop() (*Desktop, error) {
  33. sf := &Desktop{
  34. client: client_serv.NewClientServ(),
  35. dictWin: make(map[alias.AWinName]types.ITermWin),
  36. }
  37. sf.TeaModel = NewModel()
  38. sf.p = tea.NewProgram(sf, tea.WithAltScreen(), tea.WithANSICompressor())
  39. desk = sf
  40. { // Создание окон
  41. { // WinDefault
  42. winDefault, err := win_default.NewWinDefault(sf)
  43. if err != nil {
  44. return nil, fmt.Errorf("NewDesktop(): in create WinDefault, err=\n\t%w", err)
  45. }
  46. sf.dictWin[winDefault.Name()] = winDefault
  47. }
  48. { // WinConfig
  49. winConfig, err := win_config.NewWinConfig(sf)
  50. if err != nil {
  51. return nil, fmt.Errorf("NewDesktop(): in create WinConfig, err=\n\t%w", err)
  52. }
  53. sf.dictWin[winConfig.Name()] = winConfig
  54. }
  55. { // WinConfigServer
  56. winConfigServer, err := win_config_server.NewWinConfigServer(sf)
  57. if err != nil {
  58. return nil, fmt.Errorf("NewDesktop(): in create WinConfigServer, err=\n\t%w", err)
  59. }
  60. sf.dictWin[winConfigServer.Name()] = winConfigServer
  61. }
  62. { // WinConfigServerHostInput
  63. winConfigServerHostInput, err := win_config_server_host_input.NewWinConfigServerHostInput(sf)
  64. if err != nil {
  65. return nil, fmt.Errorf("NewDesktop(): in create WinConfigServerHostInput, err=\n\t%w", err)
  66. }
  67. sf.dictWin[winConfigServerHostInput.Name()] = winConfigServerHostInput
  68. }
  69. { // WinConfigServerLoginInput
  70. winConfigServerLoginInput, err := win_config_server_login_input.NewWinConfigServerLoginInput(sf)
  71. if err != nil {
  72. return nil, fmt.Errorf("NewDesktop(): in create WinConfigServerLoginInput, err=\n\t%w", err)
  73. }
  74. sf.dictWin[winConfigServerLoginInput.Name()] = winConfigServerLoginInput
  75. }
  76. { // WinConfigServerPassInput
  77. winConfigServerPassInput, err := win_config_server_pass_input.NewWinConfigServerPasswordInput(sf)
  78. if err != nil {
  79. return nil, fmt.Errorf("NewDesktop(): in create WinConfigServerPasswordInput, err=\n\t%w", err)
  80. }
  81. sf.dictWin[winConfigServerPassInput.Name()] = winConfigServerPassInput
  82. }
  83. { // WinServerConnect
  84. winServerConnect, err := win_server_connect.NewWinServerConnect(sf)
  85. if err != nil {
  86. return nil, fmt.Errorf("NewDesktop(): in create WinServerConnect, err=\n\t%w", err)
  87. }
  88. sf.dictWin[winServerConnect.Name()] = winServerConnect
  89. }
  90. }
  91. sf.winName = cons.WinDefault
  92. go sf.tick()
  93. return sf, nil
  94. }
  95. // SetWin -- устанавливает главное окно
  96. func (sf *Desktop) SetWin(winName alias.AWinName) {
  97. sf.winName = winName
  98. }
  99. type TeaModel struct {
  100. textInput textinput.Model
  101. host string // Имя хоста сервера (с портом)
  102. login string // Логин для сервера
  103. pass string // Пароль для сервера
  104. }
  105. func NewModel() TeaModel {
  106. ti := textinput.New()
  107. ti.Placeholder = "localhost"
  108. ti.Focus()
  109. ti.CharLimit = 156
  110. ti.Width = 20
  111. m := TeaModel{
  112. textInput: ti,
  113. }
  114. return m
  115. }
  116. func (sf *Desktop) tick() {
  117. for {
  118. time.Sleep(time.Second * 1)
  119. msg := tea.MouseEvent{}
  120. // m.Update(msg)
  121. sf.p.Send(msg)
  122. }
  123. }
  124. // Run -- запускает в работу консольный клиент
  125. func (sf *Desktop) Run() error {
  126. if _, err := sf.p.Run(); err != nil {
  127. return fmt.Errorf("Deskto.Run(): err=\n\t%w", err)
  128. }
  129. return nil
  130. }
  131. // Init -- инициализация перед запуском главного цикла
  132. func (sf *Desktop) Init() tea.Cmd {
  133. // Просто вернуть `nil`, т.е. никаких команд
  134. return textinput.Blink
  135. }
  136. // Update -- обновление консоли по требованию
  137. func (sf *Desktop) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
  138. var cmd tea.Cmd
  139. switch msg := msg.(type) {
  140. // Может клавиша нажата
  141. case tea.KeyMsg:
  142. switch msg.String() { // Да, нажато, а что именно?
  143. case "ctrl+q": // Надо выйти из программы
  144. return sf, tea.Quit
  145. }
  146. }
  147. mod_, cmd_ := sf.dictWin[sf.winName].Update(msg)
  148. if mod_ != nil {
  149. return mod_, cmd_
  150. }
  151. /*
  152. case ModeServerMakeAdmin:
  153. switch msg := msg.(type) {
  154. // Может клавиша нажата
  155. case tea.KeyMsg:
  156. switch msg.String() { // Да, нажато, а что именно?
  157. case "esc": // Нажатие "esc" прекращает создание админа
  158. desk.winName = ModeConfig
  159. }
  160. }
  161. case ModeShowMenuBot:
  162. // Может клавиша нажата
  163. switch msg := msg.(type) {
  164. case tea.KeyMsg:
  165. switch msg.String() { // Да, нажато, а что именно?
  166. case "esc": // Нажатие "esc" прекращает показ меню
  167. desk.winName = ModeConfig
  168. }
  169. }
  170. // Возвращает обновлённую модель дляe Bubble Tea runtime для обработки.
  171. //Здесь команду возвращать надо.
  172. */
  173. return desk, cmd
  174. }
  175. func (sf *Desktop) View() string {
  176. s := time.Now().Local().Format("[ WarTank ] = 2006-01-02 15:04:05.000")
  177. s += fmt.Sprintf("\tХост=%q\tЛогин=%q\tПароль=%q\tПодключено=%v\tЛогин=%v\tЕстьАдмин=%v\n\n", desk.host, desk.login, desk.pass, desk.isConnect, desk.isLogin, desk.isMakeAdmin)
  178. s += desk.dictWin[desk.winName].View()
  179. /*
  180. case ModeServerMakeAdmin: // Режим содания админа на бот-сервере
  181. s += desk.winServerMakeAdmin()
  182. case ModeShowMenuBot: // Меню бото-фермы
  183. s += desk.winMenuBotoFerma()
  184. }
  185. */
  186. return s
  187. }
  188. /*
  189. func (sf *Desktop) winMenuBotoFerma() string {
  190. s := "=Меню бото-фермы вар-танк=\n\n"
  191. s += "[1]-Список ботов\n"
  192. s += "[2]-Добавить бота\n"
  193. s += "[3]-Удалить бота\n"
  194. s += "\n\n[ctrl+q]-выход [esc]-отмена\n"
  195. return s
  196. }
  197. func (sf *Desktop) winServerMakeAdmin() string {
  198. s := "=Создание админа на бот-сервере вар-танк=\n\n"
  199. if !desk.isMakeAdmin {
  200. err := desk.client.MakeAdmin(desk.pass)
  201. if err != nil {
  202. s += fmt.Sprintf("Desktop.winServerMakeAdmin(): err=\n\t%v", err)
  203. s += "\n\n[ctrl+q]-выход [esc]-отмена\n"
  204. return s
  205. }
  206. }
  207. s += "Desktop.winServerMakeAdmin(): ok\n"
  208. desk.isMakeAdmin = true
  209. s += "\n\n[ctrl+q]-выход [esc]-отмена\n"
  210. return s
  211. }
  212. func (sf *Desktop) winServerLogin() string {
  213. }
  214. */
  215. // IsLogin -- возвращает признак логина на сервер ботов
  216. func (sf *Desktop) IsLogin() bool {
  217. return sf.isLogin
  218. }
  219. // IsConnect -- возвращает признак подключения на сервер ботов
  220. func (sf *Desktop) IsConnect() bool {
  221. return sf.isConnect
  222. }
  223. // SetHost -- устанавливает имя хоста бото-фермы
  224. func (sf *Desktop) SetHost(hostName string) {
  225. sf.host = hostName
  226. }
  227. // SetLogin -- устанавливает логин бото-фермы
  228. func (sf *Desktop) SetLogin(login string) {
  229. sf.login = login
  230. }
  231. // SetPass -- устанавливает пароль бото-фермы
  232. func (sf *Desktop) SetPass(password string) {
  233. sf.pass = password
  234. }
  235. // Connect -- подключает клиент к бото-ферме
  236. func (sf *Desktop) Connect() error {
  237. err := sf.client.Connect(sf.host)
  238. sf.isConnect = false
  239. if err != nil {
  240. return fmt.Errorf("Desktop.Connect(): err=\n\t%v", err)
  241. }
  242. sf.isConnect = true
  243. return nil
  244. }
  245. // MakeLogin -- выполняет вход на бото-ферму
  246. func (sf *Desktop) MakeLogin() error {
  247. err := sf.client.Login(sf.login, sf.pass)
  248. sf.isLogin = false
  249. if err != nil {
  250. return fmt.Errorf("Desktop.MakeLogin(): in login to server, err=\n\t%v", err)
  251. }
  252. sf.isLogin = true
  253. return nil
  254. }