Feat: works on my machine
This commit is contained in:
241
stages/landing.go
Normal file
241
stages/landing.go
Normal file
@@ -0,0 +1,241 @@
|
||||
package stages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/models"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
type landingOperationType int
|
||||
|
||||
const (
|
||||
landingOperationChoose landingOperationType = iota
|
||||
landingOperationLoginCred
|
||||
landingOperationRegistCred
|
||||
)
|
||||
|
||||
type focusTargetType int
|
||||
|
||||
const (
|
||||
focusTargetUsername focusTargetType = iota
|
||||
focusTargetPassword
|
||||
)
|
||||
|
||||
type LandingModel struct {
|
||||
*BaseModel
|
||||
op landingOperationType
|
||||
|
||||
focus focusTargetType
|
||||
username textinput.Model
|
||||
password textinput.Model
|
||||
|
||||
info string
|
||||
err error
|
||||
}
|
||||
|
||||
func NewLandingModel(base *BaseModel) *LandingModel {
|
||||
username := textinput.New()
|
||||
username.Placeholder = "Username"
|
||||
username.CharLimit = 32
|
||||
username.Width = 32
|
||||
username.Blur()
|
||||
|
||||
password := textinput.New()
|
||||
password.Placeholder = "Password"
|
||||
password.CharLimit = 32
|
||||
password.Width = 32
|
||||
password.Blur()
|
||||
password.EchoMode = textinput.EchoPassword
|
||||
password.EchoCharacter = '•'
|
||||
|
||||
return &LandingModel{
|
||||
BaseModel: base,
|
||||
op: landingOperationChoose,
|
||||
|
||||
username: username,
|
||||
password: password,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *LandingModel) reset() {
|
||||
m.op = landingOperationChoose
|
||||
m.username.Blur()
|
||||
m.username.Reset()
|
||||
m.password.Blur()
|
||||
m.password.Reset()
|
||||
}
|
||||
|
||||
type postLoginMsg struct{}
|
||||
|
||||
func (m *LandingModel) postLogin() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
resp, err := m.BaseModel.client.R().
|
||||
SetBasicAuth(m.username.Value(), m.password.Value()).
|
||||
Post("/auth/login")
|
||||
if err == nil {
|
||||
switch resp.StatusCode() {
|
||||
case http.StatusOK:
|
||||
m.BaseModel.client.SetBasicAuth(
|
||||
m.username.Value(), m.password.Value())
|
||||
m.info = "login success.\n"
|
||||
m.err = nil
|
||||
case http.StatusUnauthorized:
|
||||
m.err = fmt.Errorf("user not exist or password incorrect, %s",
|
||||
string(resp.Body()))
|
||||
default:
|
||||
m.err = fmt.Errorf("unknown server error, %s",
|
||||
string(resp.Body()))
|
||||
}
|
||||
} else {
|
||||
m.err = fmt.Errorf("failed to post login, %w", err)
|
||||
}
|
||||
return postLoginMsg{}
|
||||
}
|
||||
}
|
||||
|
||||
type postRegisterMsg struct{}
|
||||
|
||||
func (m *LandingModel) postRegister() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
resp, err := m.BaseModel.client.R().
|
||||
SetBody(models.User{
|
||||
Username: m.username.Value(),
|
||||
Password: m.password.Value(),
|
||||
}).
|
||||
Post("/auth/register")
|
||||
if err == nil {
|
||||
switch resp.StatusCode() {
|
||||
case http.StatusOK:
|
||||
m.info = "register success.\n"
|
||||
m.err = nil
|
||||
case http.StatusBadRequest:
|
||||
m.err = fmt.Errorf("username already exist, %s",
|
||||
string(resp.Body()))
|
||||
default:
|
||||
m.err = fmt.Errorf("unknown server error, %s",
|
||||
string(resp.Body()))
|
||||
}
|
||||
} else {
|
||||
m.err = fmt.Errorf("failed to post register, %s",
|
||||
string(resp.Body()))
|
||||
}
|
||||
return postRegisterMsg{}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *LandingModel) Init() tea.Cmd {
|
||||
return tea.ClearScreen
|
||||
}
|
||||
|
||||
func (m *LandingModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
var cmds []tea.Cmd
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "ctrl+c":
|
||||
return m, tea.Quit
|
||||
case "L", "l":
|
||||
if m.op == landingOperationChoose {
|
||||
m.op = landingOperationLoginCred
|
||||
m.focus = focusTargetUsername
|
||||
cmds = append(cmds, m.username.Focus())
|
||||
return m, tea.Batch(cmds...)
|
||||
}
|
||||
case "R", "r":
|
||||
if m.op == landingOperationChoose {
|
||||
m.op = landingOperationRegistCred
|
||||
m.focus = focusTargetUsername
|
||||
cmds = append(cmds, m.username.Focus())
|
||||
return m, tea.Batch(cmds...)
|
||||
}
|
||||
case "shift+tab", "up":
|
||||
if m.op == landingOperationLoginCred ||
|
||||
m.op == landingOperationRegistCred {
|
||||
switch m.focus {
|
||||
case focusTargetUsername:
|
||||
m.username.Blur()
|
||||
m.focus = focusTargetPassword
|
||||
cmds = append(cmds, m.password.Focus())
|
||||
case focusTargetPassword:
|
||||
m.password.Blur()
|
||||
m.focus = focusTargetUsername
|
||||
cmds = append(cmds, m.username.Focus())
|
||||
}
|
||||
}
|
||||
case "tab", "down", "enter":
|
||||
if m.op == landingOperationLoginCred ||
|
||||
m.op == landingOperationRegistCred {
|
||||
switch m.focus {
|
||||
case focusTargetUsername:
|
||||
m.username.Blur()
|
||||
m.focus = focusTargetPassword
|
||||
cmds = append(cmds, m.password.Focus())
|
||||
case focusTargetPassword:
|
||||
if msg.String() == "enter" {
|
||||
switch m.op {
|
||||
case landingOperationLoginCred:
|
||||
cmds = append(cmds, m.postLogin())
|
||||
case landingOperationRegistCred:
|
||||
cmds = append(cmds, m.postRegister())
|
||||
}
|
||||
} else {
|
||||
m.password.Blur()
|
||||
m.focus = focusTargetUsername
|
||||
cmds = append(cmds, m.username.Focus())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case postLoginMsg:
|
||||
if m.err == nil {
|
||||
*m.queue = append(*m.queue,
|
||||
tea.NewProgram(NewLobbyModel(m.BaseModel)))
|
||||
return m, tea.Quit
|
||||
} else {
|
||||
m.reset()
|
||||
}
|
||||
case postRegisterMsg:
|
||||
m.reset()
|
||||
}
|
||||
|
||||
var cmd tea.Cmd
|
||||
m.username, cmd = m.username.Update(msg)
|
||||
cmds = append(cmds, cmd)
|
||||
m.password, cmd = m.password.Update(msg)
|
||||
cmds = append(cmds, cmd)
|
||||
|
||||
return m, tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
func (m *LandingModel) View() string {
|
||||
var b strings.Builder
|
||||
|
||||
switch m.op {
|
||||
case landingOperationChoose:
|
||||
fmt.Fprintf(&b, "Choose Operation\n(L)ogin / (R)egister\n")
|
||||
case landingOperationLoginCred:
|
||||
fmt.Fprintf(&b, "Login: \n")
|
||||
b.WriteString(m.username.View() + "\n")
|
||||
b.WriteString(m.password.View() + "\n")
|
||||
case landingOperationRegistCred:
|
||||
fmt.Fprintf(&b, "Register: \n")
|
||||
b.WriteString(m.username.View() + "\n")
|
||||
b.WriteString(m.password.View() + "\n")
|
||||
}
|
||||
|
||||
if m.info != "" {
|
||||
b.WriteString(m.info + "\n")
|
||||
}
|
||||
|
||||
if m.err != nil {
|
||||
b.WriteString("----------\n")
|
||||
b.WriteString(m.err.Error() + "\n")
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
Reference in New Issue
Block a user