Skip to content

Commit

Permalink
Merge pull request #35 from JunNishimura/#34
Browse files Browse the repository at this point in the history
improve authorize finish step
  • Loading branch information
JunNishimura authored Aug 6, 2023
2 parents 594ba2e + f273c44 commit 6f591ef
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 29 deletions.
19 changes: 17 additions & 2 deletions auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
spotifyauth "github.com/JunNishimura/spotify/v2/auth"
"github.com/google/uuid"
"github.com/pkg/browser"
"golang.org/x/oauth2"
)

const (
Expand Down Expand Up @@ -68,8 +69,8 @@ func (a *Client) completeAuth(w http.ResponseWriter, r *http.Request) {
log.Fatalf("state mismatch: got = %s, expected = %s\n", getState, a.state)
}

if err := a.cfg.SetToken(token); err != nil {
log.Fatalf("fail to set token: %v", err)
if err := a.setToken(token); err != nil {
log.Fatal(err)
}

a.SpotifyChannel <- spotify.New(a.auth.Client(r.Context(), token))
Expand All @@ -80,3 +81,17 @@ func (a *Client) completeAuth(w http.ResponseWriter, r *http.Request) {
}
}()
}

func (a *Client) setToken(token *oauth2.Token) error {
if err := a.cfg.Set(config.AccessTokenKey, token.AccessToken); err != nil {
return fmt.Errorf("fail to set access token: %v", err)
}
if err := a.cfg.Set(config.RefreshTokenKey, token.RefreshToken); err != nil {
return fmt.Errorf("fail to set refresh token: %v", err)
}
if err := a.cfg.Set(config.ExpirationKey, token.Expiry.Unix()); err != nil {
return fmt.Errorf("fail to set expiration: %v", err)
}

return nil
}
46 changes: 30 additions & 16 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ const (
ExpirationKey ConfKey = "expiration"
)

func (k ConfKey) isTokenKey() bool {
return k == AccessTokenKey || k == RefreshTokenKey || k == ExpirationKey
}

func (k ConfKey) isClientKey() bool {
return k == SpotifyIDKey || k == SpotifySecretKey || k == OpenAIAPIKey
}

func newConfig() *Config {
return &Config{
tokenViper: viper.New(),
Expand Down Expand Up @@ -108,10 +116,18 @@ func (c *Config) Load() error {
return nil
}

func (c *Config) SetToken(token *oauth2.Token) error {
c.tokenViper.Set(string(AccessTokenKey), token.AccessToken)
c.tokenViper.Set(string(RefreshTokenKey), token.RefreshToken)
c.tokenViper.Set(string(ExpirationKey), token.Expiry.Unix())
func (c *Config) Set(key ConfKey, value any) error {
if key.isTokenKey() {
return c.setToken(key, value)
} else if key.isClientKey() {
return c.setClient(key, value)
}

return fmt.Errorf("fail to set config. invalid key: %s", key)
}

func (c *Config) setToken(key ConfKey, value any) error {
c.tokenViper.Set(string(key), value)

if err := c.tokenViper.WriteConfig(); err != nil {
return fmt.Errorf("fail to write token config: %v", err)
Expand All @@ -120,6 +136,16 @@ func (c *Config) SetToken(token *oauth2.Token) error {
return nil
}

func (c *Config) setClient(key ConfKey, value any) error {
c.clientViper.Set(string(key), value)

if err := c.clientViper.WriteConfig(); err != nil {
return fmt.Errorf("fail to write token config: %v", err)
}

return nil
}

func (c *Config) GetToken() *oauth2.Token {
accessToken := c.tokenViper.GetString(string(AccessTokenKey))
refreshToken := c.tokenViper.GetString(string(RefreshTokenKey))
Expand All @@ -135,18 +161,6 @@ func (c *Config) GetToken() *oauth2.Token {
}
}

func (c *Config) SetClient(spotifyID, spotifySecret, openAIApiKey string) error {
c.clientViper.Set(string(spotifyID), spotifyID)
c.clientViper.Set(string(spotifySecret), spotifySecret)
c.clientViper.Set(string(openAIApiKey), openAIApiKey)

if err := c.clientViper.WriteConfig(); err != nil {
return fmt.Errorf("fail to write client config: %v", err)
}

return nil
}

func (c *Config) IsClientValid() bool {
spotifyID := c.clientViper.GetString(string(SpotifyIDKey))
spotifySecret := c.clientViper.GetString(string(SpotifySecretKey))
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
require (
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/harmonica v0.2.0 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,19 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/JunNishimura/spotify/v2 v2.0.0-20230803143011-7b365448b4da h1:1mDNsXDcVMDtk5la53hniKo3GKty5GGORSzWl6s+X6I=
github.com/JunNishimura/spotify/v2 v2.0.0-20230803143011-7b365448b4da/go.mod h1:38hSXhMhiWrNaS12Dm1Lp7yM875YxDEbhRamw4QD0jU=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/JunNishimura/spotify/v2 v2.0.0-20230803143011-7b365448b4da h1:1mDNsXDcVMDtk5la53hniKo3GKty5GGORSzWl6s+X6I=
github.com/JunNishimura/spotify/v2 v2.0.0-20230803143011-7b365448b4da/go.mod h1:38hSXhMhiWrNaS12Dm1Lp7yM875YxDEbhRamw4QD0jU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY=
github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc=
github.com/charmbracelet/bubbletea v0.24.1 h1:LpdYfnu+Qc6XtvMz6d/6rRY71yttHTP5HtrjMgWvixc=
github.com/charmbracelet/bubbletea v0.24.1/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
Expand Down
9 changes: 9 additions & 0 deletions ui/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"strings"

"github.com/JunNishimura/Chatify/config"
"github.com/JunNishimura/spotify/v2"
"github.com/charmbracelet/bubbles/textarea"
"github.com/charmbracelet/bubbles/viewport"
"github.com/charmbracelet/lipgloss"
Expand Down Expand Up @@ -40,12 +41,18 @@ var (

type Model struct {
index int
writeIndex int
cfg *config.Config
textarea textarea.Model
confKeyList []config.ConfKey
displayMessages []string
qaList []*QA
viewport viewport.Model
user *spotify.PrivateUser
senderStyle lipgloss.Style
qaDone bool
setConfigDone bool
greetingDone bool
err error
}

Expand All @@ -64,6 +71,8 @@ func NewModel() *Model {

return &Model{
index: 0,
writeIndex: 0,
confKeyList: []config.ConfKey{config.SpotifyIDKey, config.SpotifySecretKey, config.OpenAIAPIKey},
displayMessages: greetings,
qaList: qaListTemplate,
textarea: newTextArea(),
Expand Down
39 changes: 36 additions & 3 deletions ui/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"strings"
"time"

"github.com/JunNishimura/Chatify/auth"
"github.com/JunNishimura/Chatify/config"
Expand Down Expand Up @@ -32,14 +33,23 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
fmt.Println(m.textarea.Value())
return m, tea.Quit
case tea.KeyEnter:
if m.greetingDone {
return m, tea.Quit
} else if m.setConfigDone {
return m, m.Authorize
}

m.qaList[m.index].answer = m.textarea.Value()

m.index++
if m.index == len(m.qaList) {
m.qaDone = true
m.displayMessages = append(m.displayMessages, m.senderStyle.Render("Chatify: ")+"Thank you so much!")
m.viewport.SetContent(strings.Join(m.displayMessages, "\n"))

return m, m.Authorize
return m, tea.Batch(
m.setClientConfig(m.confKeyList[m.writeIndex], qaListTemplate[m.writeIndex].answer),
)
}

m.displayMessages = append(
Expand All @@ -53,12 +63,19 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.textarea.Reset()
m.textarea.Placeholder = m.qaList[m.index].placeholder
}
case writeClientConfigMsg:
m.writeIndex++
if m.writeIndex < len(m.confKeyList) {
return m, m.setClientConfig(m.confKeyList[m.writeIndex], m.qaList[m.writeIndex].answer)
}
m.setConfigDone = true
case loadConfigMsg:
m.cfg = msg.cfg
return m, textarea.Blink
case spotifyUserMsg:
fmt.Println("logged in as: ", msg.user.DisplayName)
return m, tea.Quit
m.user = msg.user
m.greetingDone = true
return m, tea.Batch(tiCmd, vpCmd)
case errMsg:
m.err = msg.err
return m, tea.Quit
Expand All @@ -80,6 +97,22 @@ func (m *Model) loadConfig() tea.Msg {
return loadConfigMsg{cfg: cfg}
}

type writeClientConfigMsg string

func (m *Model) setClientConfig(key config.ConfKey, value any) tea.Cmd {
start := time.Now()
if err := m.cfg.Set(key, value); err != nil {
return func() tea.Msg {
return errMsg{err: err}
}
}
elapsed := time.Since(start)

return tea.Tick(elapsed, func(t time.Time) tea.Msg {
return writeClientConfigMsg(key)
})
}

func (m *Model) Authorize() tea.Msg {
authClient := auth.New(m.cfg)

Expand Down
43 changes: 37 additions & 6 deletions ui/view.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,42 @@
package ui

import "fmt"
import (
"fmt"

"github.com/charmbracelet/lipgloss"
)

var (
checkMark = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).SetString("✓")
doneStyle = lipgloss.NewStyle().Margin(1, 2)
)

func (m *Model) View() string {
return fmt.Sprintf(
"%s\n\n%s\n\n",
m.viewport.View(),
m.textarea.View(),
)
view := m.viewport.View()
text := m.textarea.View()

var output string
if m.greetingDone {
output += doneStyle.Render(fmt.Sprintf(`Nice to see you, %s!!
If you want to talk to me, please type
$ chatify hey
See you then!! (press to "enter" to exit)`,
m.user.DisplayName,
))
} else if m.qaDone {
for i, key := range m.confKeyList[:m.writeIndex] {
output += fmt.Sprintf("%s set %s as %s\n", checkMark, key, m.qaList[i].answer)
}

if m.setConfigDone {
output += doneStyle.Render(`Press "enter" to authorize`)
}
} else {
output = fmt.Sprintf("%s\n\n%s\n\n", view, text)
}

return output
}

0 comments on commit 6f591ef

Please sign in to comment.