edit form movie
This commit is contained in:
parent
68c32ba962
commit
06ead2b299
|
@ -25,31 +25,42 @@ func NewEMDB(baseURL string, apiKey string) *EMDB {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EMDB) GetMovies() ([]model.Movie, error) {
|
func (e *EMDB) GetMovies() ([]model.Movie, error) {
|
||||||
url := fmt.Sprintf("%s/movie", e.baseURL)
|
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var movies []model.Movie
|
var movies []model.Movie
|
||||||
if err := json.Unmarshal(body, &movies); err != nil {
|
for i := 0; i < 5; i++ {
|
||||||
return nil, err
|
movies = append(movies, model.Movie{
|
||||||
|
ID: fmt.Sprintf("id-%d", i),
|
||||||
|
TMDBID: int64(i),
|
||||||
|
IMDBID: fmt.Sprintf("tt%07d", i),
|
||||||
|
Title: fmt.Sprintf("Movie %d", i),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return movies, nil
|
return movies, nil
|
||||||
|
|
||||||
|
//url := fmt.Sprintf("%s/movie", e.baseURL)
|
||||||
|
//req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||||
|
//if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
//}
|
||||||
|
//req.Header.Add("Authorization", e.apiKey)
|
||||||
|
//
|
||||||
|
//resp, err := e.c.Do(req)
|
||||||
|
//if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//if resp.StatusCode != http.StatusOK {
|
||||||
|
// return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//body, err := io.ReadAll(resp.Body)
|
||||||
|
//defer resp.Body.Close()
|
||||||
|
//
|
||||||
|
//var movies []model.Movie
|
||||||
|
//if err := json.Unmarshal(body, &movies); err != nil {
|
||||||
|
// return nil, err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//return movies, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EMDB) AddMovie(movie model.Movie) (model.Movie, error) {
|
func (e *EMDB) AddMovie(movie model.Movie) (model.Movie, error) {
|
||||||
|
@ -87,3 +98,39 @@ func (e *EMDB) AddMovie(movie model.Movie) (model.Movie, error) {
|
||||||
|
|
||||||
return newMovie, nil
|
return newMovie, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *EMDB) StoreMovie(movie model.Movie) (model.Movie, error) {
|
||||||
|
body, err := json.Marshal(movie)
|
||||||
|
if err != nil {
|
||||||
|
return model.Movie{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s/movie/%s", e.baseURL, movie.ID)
|
||||||
|
req, err := http.NewRequest(http.MethodPut, url, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return model.Movie{}, err
|
||||||
|
}
|
||||||
|
req.Header.Add("Authorization", e.apiKey)
|
||||||
|
|
||||||
|
resp, err := e.c.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return model.Movie{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return model.Movie{}, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
newBody, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return model.Movie{}, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var newMovie model.Movie
|
||||||
|
if err := json.Unmarshal(newBody, &newMovie); err != nil {
|
||||||
|
return model.Movie{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return newMovie, nil
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
port = flag.Int("port", 8080, "port to listen on")
|
port = flag.Int("port", 8085, "port to listen on")
|
||||||
dbPath = flag.String("dbpath", "test.db", "path to sqlite db")
|
dbPath = flag.String("dbpath", "test.db", "path to sqlite db")
|
||||||
apiKey = flag.String("apikey", "hoi", "api key to use")
|
apiKey = flag.String("apikey", "hoi", "api key to use")
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,28 +2,67 @@ package tui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"ewintr.nl/emdb/client"
|
"ewintr.nl/emdb/client"
|
||||||
|
"ewintr.nl/emdb/model"
|
||||||
"github.com/charmbracelet/bubbles/list"
|
"github.com/charmbracelet/bubbles/list"
|
||||||
|
"github.com/charmbracelet/bubbles/textinput"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type UpdateForm tea.Msg
|
||||||
|
type StoredMovie struct{}
|
||||||
|
|
||||||
type tabEMDB struct {
|
type tabEMDB struct {
|
||||||
initialized bool
|
initialized bool
|
||||||
list list.Model
|
|
||||||
emdb *client.EMDB
|
emdb *client.EMDB
|
||||||
|
mode string
|
||||||
|
focused string
|
||||||
|
colWidth int
|
||||||
|
list list.Model
|
||||||
|
formLabels []string
|
||||||
|
formInputs []textinput.Model
|
||||||
|
formFocus int
|
||||||
logger *Logger
|
logger *Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTabEMDB(emdb *client.EMDB, logger *Logger) (tea.Model, tea.Cmd) {
|
func NewTabEMDB(emdb *client.EMDB, logger *Logger) (tea.Model, tea.Cmd) {
|
||||||
list := list.New([]list.Item{}, list.NewDefaultDelegate(), 0, 0)
|
del := list.NewDefaultDelegate()
|
||||||
|
list := list.New([]list.Item{}, del, 0, 0)
|
||||||
list.Title = "Movies"
|
list.Title = "Movies"
|
||||||
list.SetShowHelp(false)
|
list.SetShowHelp(false)
|
||||||
|
|
||||||
|
formLabels := []string{
|
||||||
|
"ID",
|
||||||
|
"TMDB ID",
|
||||||
|
"IMDB ID",
|
||||||
|
"Title",
|
||||||
|
"English Title",
|
||||||
|
"Year",
|
||||||
|
"Director",
|
||||||
|
"Summary",
|
||||||
|
"Rating",
|
||||||
|
"Comment",
|
||||||
|
}
|
||||||
|
formInputs := make([]textinput.Model, len(formLabels))
|
||||||
|
for i := range formLabels {
|
||||||
|
formInputs[i] = textinput.New()
|
||||||
|
formInputs[i].Prompt = ""
|
||||||
|
formInputs[i].Width = 50
|
||||||
|
formInputs[i].CharLimit = 500
|
||||||
|
}
|
||||||
|
|
||||||
m := tabEMDB{
|
m := tabEMDB{
|
||||||
emdb: emdb,
|
focused: "form",
|
||||||
logger: logger,
|
emdb: emdb,
|
||||||
list: list,
|
logger: logger,
|
||||||
|
mode: "view",
|
||||||
|
list: list,
|
||||||
|
formLabels: formLabels,
|
||||||
|
formInputs: formInputs,
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Log("search emdb...")
|
logger.Log("search emdb...")
|
||||||
|
@ -37,26 +76,151 @@ func (m tabEMDB) Init() tea.Cmd {
|
||||||
func (m tabEMDB) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (m tabEMDB) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
var cmds []tea.Cmd
|
var cmds []tea.Cmd
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case TabSizeMsg:
|
case TabSizeMsg:
|
||||||
if !m.initialized {
|
if !m.initialized {
|
||||||
m.initialized = true
|
m.initialized = true
|
||||||
}
|
}
|
||||||
m.list.SetSize(msg.Width, msg.Height)
|
m.colWidth = msg.Width / 2
|
||||||
|
m.list.SetSize(m.colWidth, msg.Height)
|
||||||
|
m.list, cmd = m.list.Update(msg)
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
case Movies:
|
case Movies:
|
||||||
m.logger.Log(fmt.Sprintf("found %d movies in in emdb", len(msg)))
|
m.logger.Log(fmt.Sprintf("found %d movies in in emdb", len(msg)))
|
||||||
m.list.SetItems(msg.listItems())
|
m.list.SetItems(msg.listItems())
|
||||||
|
m.list.Select(0)
|
||||||
|
m.list, cmd = m.list.Update(msg)
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
case StoredMovie:
|
||||||
|
m.logger.Log("stored movie, fetching movie list")
|
||||||
|
cmds = append(cmds, FetchMovieList(m.emdb))
|
||||||
|
case tea.KeyMsg:
|
||||||
|
m.Log("key msg")
|
||||||
|
switch m.mode {
|
||||||
|
case "edit":
|
||||||
|
m.Log("processing edit mode")
|
||||||
|
switch msg.String() {
|
||||||
|
case "tab", "shift+tab", "up", "down":
|
||||||
|
s := msg.String()
|
||||||
|
if s == "up" || s == "shift+tab" {
|
||||||
|
m.formFocus--
|
||||||
|
} else {
|
||||||
|
m.formFocus++
|
||||||
|
}
|
||||||
|
if m.formFocus > len(m.formInputs) {
|
||||||
|
m.formFocus = 0
|
||||||
|
}
|
||||||
|
if m.formFocus < 0 {
|
||||||
|
m.formFocus = len(m.formInputs)
|
||||||
|
}
|
||||||
|
for i := 0; i <= len(m.formInputs)-1; i++ {
|
||||||
|
if i == m.formFocus {
|
||||||
|
cmds = append(cmds, m.formInputs[i].Focus())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m.formInputs[i].Blur()
|
||||||
|
}
|
||||||
|
case "enter":
|
||||||
|
m.mode = "view"
|
||||||
|
cmds = append(cmds, m.StoreMovie())
|
||||||
|
default:
|
||||||
|
cmds = append(cmds, m.updateFormInputs(msg))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
m.Log("processing view mode")
|
||||||
|
switch msg.String() {
|
||||||
|
case "up":
|
||||||
|
m.list, cmd = m.list.Update(msg)
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
m.SetForm(m.list.SelectedItem().(Movie))
|
||||||
|
case "down":
|
||||||
|
m.list, cmd = m.list.Update(msg)
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
m.SetForm(m.list.SelectedItem().(Movie))
|
||||||
|
case "e":
|
||||||
|
m.mode = "edit"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m.list, cmd = m.list.Update(msg)
|
|
||||||
cmds = append(cmds, cmd)
|
|
||||||
|
|
||||||
return m, tea.Batch(cmds...)
|
return m, tea.Batch(cmds...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *tabEMDB) updateFormInputs(msg tea.Msg) tea.Cmd {
|
||||||
|
cmds := make([]tea.Cmd, len(m.formInputs))
|
||||||
|
for i := range m.formInputs {
|
||||||
|
m.formInputs[i], cmds[i] = m.formInputs[i].Update(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tea.Batch(cmds...)
|
||||||
|
}
|
||||||
|
|
||||||
func (m tabEMDB) View() string {
|
func (m tabEMDB) View() string {
|
||||||
return m.list.View()
|
labels := make([]string, len(m.formLabels))
|
||||||
|
for i := range m.formLabels {
|
||||||
|
labels[i] = fmt.Sprintf("%s: ", m.formLabels[i])
|
||||||
|
}
|
||||||
|
fields := make([]string, len(m.formLabels))
|
||||||
|
for i := range m.formLabels {
|
||||||
|
fields[i] = m.formInputs[i].View()
|
||||||
|
}
|
||||||
|
labelView := strings.Join(labels, "\n")
|
||||||
|
fieldsView := strings.Join(fields, "\n")
|
||||||
|
form := lipgloss.JoinHorizontal(lipgloss.Top, labelView, fieldsView)
|
||||||
|
|
||||||
|
colLeft := lipgloss.NewStyle().Width(m.colWidth).Render(m.list.View())
|
||||||
|
colRight := lipgloss.NewStyle().Width(m.colWidth).Render(form)
|
||||||
|
|
||||||
|
return lipgloss.JoinHorizontal(lipgloss.Top, colLeft, colRight)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *tabEMDB) SetForm(movie Movie) {
|
||||||
|
m.formInputs[0].SetValue(movie.m.ID)
|
||||||
|
m.formInputs[1].SetValue(fmt.Sprintf("%d", movie.m.TMDBID))
|
||||||
|
m.formInputs[2].SetValue(movie.m.IMDBID)
|
||||||
|
m.formInputs[3].SetValue(movie.m.Title)
|
||||||
|
m.formInputs[4].SetValue(movie.m.EnglishTitle)
|
||||||
|
m.formInputs[5].SetValue(fmt.Sprintf("%d", movie.m.Year))
|
||||||
|
m.formInputs[6].SetValue(strings.Join(movie.m.Directors, ","))
|
||||||
|
m.formInputs[7].SetValue(movie.m.Summary)
|
||||||
|
m.formInputs[8].SetValue(fmt.Sprintf("%d", movie.m.Rating))
|
||||||
|
m.formInputs[9].SetValue(movie.m.Comment)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *tabEMDB) StoreMovie() tea.Cmd {
|
||||||
|
return func() tea.Msg {
|
||||||
|
tmdbId, err := strconv.Atoi(m.formInputs[1].Value())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("tmbID cannot be converted to an int: %w", err)
|
||||||
|
}
|
||||||
|
year, err := strconv.Atoi(m.formInputs[5].Value())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("year cannot be converted to an int: %w", err)
|
||||||
|
}
|
||||||
|
rating, err := strconv.Atoi(m.formInputs[8].Value())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("rating cannot be converted to an int: %w", err)
|
||||||
|
}
|
||||||
|
movie := Movie{
|
||||||
|
m: model.Movie{
|
||||||
|
ID: m.formInputs[0].Value(),
|
||||||
|
TMDBID: int64(tmdbId),
|
||||||
|
IMDBID: m.formInputs[2].Value(),
|
||||||
|
Title: m.formInputs[3].Value(),
|
||||||
|
EnglishTitle: m.formInputs[4].Value(),
|
||||||
|
Year: year,
|
||||||
|
Directors: strings.Split(m.formInputs[6].Value(), ","),
|
||||||
|
Summary: m.formInputs[7].Value(),
|
||||||
|
Rating: rating,
|
||||||
|
Comment: m.formInputs[9].Value(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
m.Log(fmt.Sprintf("storing movie %s", movie.Title()))
|
||||||
|
if _, err := m.emdb.AddMovie(movie.m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return StoredMovie{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *tabEMDB) Log(s string) {
|
func (m *tabEMDB) Log(s string) {
|
||||||
|
|
|
@ -69,10 +69,6 @@ func (t *TabSet) Update(msg tea.Msg) tea.Cmd {
|
||||||
case TabResetMsg:
|
case TabResetMsg:
|
||||||
name := string(msg.(TabResetMsg))
|
name := string(msg.(TabResetMsg))
|
||||||
t.tabs[name], cmd = t.tabs[name].Update(msg)
|
t.tabs[name], cmd = t.tabs[name].Update(msg)
|
||||||
|
|
||||||
//case ImportMovieMsg:
|
|
||||||
// t.Select("emdb")
|
|
||||||
// t.tabs["emdb"], cmd = t.tabs["emdb"].Update(msg)
|
|
||||||
default:
|
default:
|
||||||
name := t.order[t.active]
|
name := t.order[t.active]
|
||||||
t.tabs[name], cmd = t.tabs[name].Update(msg)
|
t.tabs[name], cmd = t.tabs[name].Update(msg)
|
||||||
|
|
Loading…
Reference in New Issue