2021-11-13 06:38:12 +02:00
|
|
|
// gorc project
|
2021-11-14 06:31:51 +02:00
|
|
|
// Copyright (C) 2021 IllusionMan1212
|
2021-11-13 06:38:12 +02:00
|
|
|
//
|
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation; either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License along
|
|
|
|
|
// with this program; if not, see https://www.gnu.org/licenses.
|
|
|
|
|
|
|
|
|
|
package app
|
|
|
|
|
|
|
|
|
|
import (
|
2021-11-14 06:19:46 +02:00
|
|
|
"bufio"
|
2021-11-13 06:38:12 +02:00
|
|
|
"log"
|
|
|
|
|
"os"
|
|
|
|
|
|
2021-11-14 06:19:46 +02:00
|
|
|
"github.com/charmbracelet/bubbles/textinput"
|
2021-11-13 06:38:12 +02:00
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
2021-11-14 06:19:46 +02:00
|
|
|
"github.com/illusionman1212/gorc/client"
|
2021-11-13 06:38:12 +02:00
|
|
|
"github.com/illusionman1212/gorc/ui"
|
|
|
|
|
"github.com/illusionman1212/gorc/ui/login"
|
2021-11-14 06:19:46 +02:00
|
|
|
"github.com/illusionman1212/gorc/ui/mainscreen"
|
2021-11-13 06:38:12 +02:00
|
|
|
"golang.org/x/term"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Screen int
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
Login = iota
|
|
|
|
|
MainScreen
|
|
|
|
|
)
|
|
|
|
|
|
2021-11-14 06:19:46 +02:00
|
|
|
type UI struct {
|
2021-11-13 06:38:12 +02:00
|
|
|
windowWidth int
|
|
|
|
|
windowHeight int
|
|
|
|
|
currentScreen Screen
|
2021-11-14 06:19:46 +02:00
|
|
|
login login.State
|
|
|
|
|
mainScreen mainscreen.State
|
|
|
|
|
}
|
2021-11-13 06:38:12 +02:00
|
|
|
|
2021-11-14 06:19:46 +02:00
|
|
|
type State struct {
|
|
|
|
|
ui UI
|
|
|
|
|
client *client.Client
|
2021-11-13 06:38:12 +02:00
|
|
|
}
|
|
|
|
|
|
2021-11-14 06:19:46 +02:00
|
|
|
func initialUiState() UI {
|
2021-11-13 06:38:12 +02:00
|
|
|
width, height, err := term.GetSize(int(os.Stdout.Fd()))
|
|
|
|
|
if err != nil {
|
2021-11-14 06:19:46 +02:00
|
|
|
// TODO: properly handle this error
|
2021-11-13 06:38:12 +02:00
|
|
|
log.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-14 06:19:46 +02:00
|
|
|
return UI{
|
|
|
|
|
login: login.NewLogin(),
|
2021-12-13 09:38:07 +02:00
|
|
|
mainScreen: mainscreen.NewMainScreen(),
|
2021-11-14 06:19:46 +02:00
|
|
|
windowWidth: width,
|
|
|
|
|
windowHeight: height,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func InitialState() State {
|
2021-11-13 06:38:12 +02:00
|
|
|
s := State{
|
2021-11-14 06:19:46 +02:00
|
|
|
client: &client.Client{},
|
|
|
|
|
ui: initialUiState(),
|
2021-11-13 06:38:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s State) Init() tea.Cmd {
|
2021-11-14 06:19:46 +02:00
|
|
|
return textinput.Blink
|
2021-11-13 06:38:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s State) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
|
|
switch msg := msg.(type) {
|
|
|
|
|
case tea.KeyMsg:
|
|
|
|
|
switch msg.String() {
|
|
|
|
|
case "ctrl+c":
|
|
|
|
|
// TODO: clean up and gracefully quit by leaving the IRC channel/server and then quit bubble.
|
2021-12-09 03:48:42 +02:00
|
|
|
if s.client.TlsConn != nil {
|
|
|
|
|
s.client.TlsConn.Close()
|
|
|
|
|
}
|
|
|
|
|
if s.client.TcpConn != nil {
|
|
|
|
|
s.client.TcpConn.Close()
|
2021-11-14 06:19:46 +02:00
|
|
|
}
|
2021-11-13 06:38:12 +02:00
|
|
|
return s, tea.Quit
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case tea.WindowSizeMsg:
|
2021-11-14 06:19:46 +02:00
|
|
|
s.ui.windowWidth = msg.Width
|
|
|
|
|
s.ui.windowHeight = msg.Height
|
2021-11-13 06:38:12 +02:00
|
|
|
|
|
|
|
|
ui.MainStyle = ui.MainStyle.
|
|
|
|
|
Width(msg.Width).
|
|
|
|
|
Height(msg.Height)
|
|
|
|
|
|
2021-12-13 09:38:07 +02:00
|
|
|
s.ui.mainScreen.Viewport.Width = msg.Width
|
|
|
|
|
s.ui.mainScreen.Viewport.Height = msg.Height - mainscreen.InputBoxHeight
|
|
|
|
|
|
2021-11-13 06:38:12 +02:00
|
|
|
return s, nil
|
2021-11-14 06:19:46 +02:00
|
|
|
case login.ConnectingMsg:
|
|
|
|
|
host := s.ui.login.Inputs[0].Value()
|
|
|
|
|
port := s.ui.login.Inputs[1].Value()
|
|
|
|
|
channel := s.ui.login.Inputs[2].Value()
|
|
|
|
|
nickname := s.ui.login.Inputs[3].Value()
|
|
|
|
|
password := s.ui.login.Inputs[4].Value()
|
|
|
|
|
tlsEnabled := s.ui.login.TLS
|
|
|
|
|
|
|
|
|
|
s.ui.currentScreen = MainScreen
|
|
|
|
|
|
|
|
|
|
// create new client with the provided host and port
|
|
|
|
|
client := client.NewClient(host, port, tlsEnabled)
|
|
|
|
|
client.Register(nickname, password, channel)
|
|
|
|
|
s.client = client
|
2021-11-29 23:22:35 +02:00
|
|
|
s.ui.mainScreen.Client = client
|
2021-11-14 06:19:46 +02:00
|
|
|
|
2021-12-09 03:48:42 +02:00
|
|
|
if tlsEnabled {
|
|
|
|
|
r := bufio.NewReaderSize(client.TlsConn, 512)
|
|
|
|
|
s.ui.mainScreen.Reader = r
|
|
|
|
|
} else {
|
|
|
|
|
r := bufio.NewReaderSize(client.TcpConn, 512)
|
|
|
|
|
s.ui.mainScreen.Reader = r
|
|
|
|
|
}
|
2021-11-14 06:19:46 +02:00
|
|
|
|
|
|
|
|
return s, mainscreen.InitialRead
|
2021-11-13 06:38:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// switch between which screen is currently active and update its state
|
2021-11-14 06:19:46 +02:00
|
|
|
switch s.ui.currentScreen {
|
2021-11-13 06:38:12 +02:00
|
|
|
case Login:
|
2021-11-14 06:19:46 +02:00
|
|
|
state, cmd := s.ui.login.Update(msg)
|
|
|
|
|
s.ui.login = state
|
|
|
|
|
return s, cmd
|
|
|
|
|
case MainScreen:
|
|
|
|
|
state, cmd := s.ui.mainScreen.Update(msg)
|
|
|
|
|
s.ui.mainScreen = state
|
|
|
|
|
return s, cmd
|
2021-11-13 06:38:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s State) View() string {
|
|
|
|
|
// switch between which screen is currently active and render it.
|
2021-11-14 06:19:46 +02:00
|
|
|
switch s.ui.currentScreen {
|
2021-11-13 06:38:12 +02:00
|
|
|
case Login:
|
2021-11-14 06:19:46 +02:00
|
|
|
return s.ui.login.View()
|
|
|
|
|
case MainScreen:
|
|
|
|
|
return s.ui.mainScreen.View()
|
2021-11-13 06:38:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "Error: this screen shouldn't ever show"
|
|
|
|
|
}
|