123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- // package win_main -- главное окно приложения
- package win_main
- import (
- _ "embed"
- "fmt"
- "log"
- "net/url"
- "runtime"
- "sync"
- "time"
- "github.com/zserge/lorca"
- // "wartank/desktop/win_users"
- "wartank/pkg/components/safebool"
- "wartank/pkg/types"
- )
- const (
- strWinMainName = "win_main" // Контрольная строка для сторожа потоков
- )
- //go:embed win_main.html
- var strWinHtml string
- // WinMain -- главное окно приложения
- type WinMain struct {
- desktop types.IDesktop
- store types.IStore
- win lorca.UI
- block sync.Mutex
- isWork *safebool.SafeBool
- ws types.IWebSocket
- }
- // NewWinMain -- возвращает новое окно десктопа
- func NewWinMain(desktop types.IDesktop) (*WinMain, error) {
- if desktop == nil {
- return nil, fmt.Errorf("NewWinMain(): IDesktop == nil")
- }
- sf := &WinMain{
- desktop: desktop,
- store: desktop.Store(),
- isWork: safebool.NewSafeBool(),
- ws: desktop.Ws(),
- }
- args := []string{}
- if runtime.GOOS == "linux" {
- args = append(args, "--class=Lorca")
- }
- var err error
- sf.win, err = lorca.New("data:text/html,"+url.PathEscape(strWinHtml), "", 640, 480, args...)
- if err != nil {
- return nil, fmt.Errorf("NewWinMain(): in create win, err=\n\t%w", err)
- }
- go sf.close()
- return sf, nil
- }
- // Работает в отдельном потоке, главный цикл окна
- func (sf *WinMain) Run() {
- log.Println("WinMain.Run()")
- sf.win.Bind("close_win", sf.onClose)
- sf.win.Bind("bot_list", sf.onUsers)
- go sf.timeServer()
- <-sf.win.Done() // Ожидание закрытия окна
- sf.desktop.CancelApp()
- }
- // Открывает окно с пользователями
- func (sf *WinMain) onUsers() {
- log.Println("WinMain.onUsers()")
- go sf.desktop.DictBot().Show()
- }
- // Проверяет наличие работающего сервера, работает в отдельном потоке
- func (sf *WinMain) timeServer() {
- for {
- time.Sleep(time.Second * 2)
- timeBeg := time.Now().UTC().UnixMicro()
- dictResp, err := sf.ws.Read("/server/time")
- if err != nil {
- log.Printf("WinMain.timeServer(): in send request to server, err=\n\t%v\n", err)
- sf.desktop.CancelApp()
- return
- }
- timeEnd := time.Now().UTC().UnixMicro() - timeBeg
- strErr := dictResp["err"]
- if strErr != "" {
- js := fmt.Sprintf(`
- function SetTimeServer(){
- var _el = document.getById("/server/time");
- _el.innerText=%q;
- }
- SetTimeServer()
- `, err)
- sf.win.Eval(js)
- continue
- }
- strTime := dictResp["/server/time"]
- js := fmt.Sprintf(`
- function SetTimeServer(){
- var _el = document.getElementById("/server/time");
- _el.innerText=%q;
- }
- SetTimeServer()
- `, strTime)
- sf.win.Eval(js)
- js = fmt.Sprintf(`
- function SetPingServer(){
- var _el = document.getElementById("/server/ping");
- _el.innerText="%v мкСек";
- }
- SetPingServer()
- `, timeEnd)
- sf.win.Eval(js)
- }
- }
- // Закрывает приложение
- func (sf *WinMain) onClose() {
- log.Println("WinMain.onClose()")
- sf.win.Close()
- }
- // close -- ожидает отмены глобального контекста
- func (sf *WinMain) close() {
- <-sf.desktop.CtxApp().Done()
- log.Println("WinMain.close()")
- sf.block.Lock()
- defer sf.block.Unlock()
- if !sf.isWork.Get() {
- return
- }
- sf.isWork.Reset()
- sf.win.Close()
- sf.desktop.Wg().Done(strWinMainName)
- }
|