Skip to content

Commit

Permalink
feat: Create choose SDK view (#89)
Browse files Browse the repository at this point in the history
* add choose sdk step

* no errors when choosing an sdk

* filtering not actually working
  • Loading branch information
k3llymariee authored Mar 28, 2024
1 parent 3c6e6f4 commit 7518423
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 3 deletions.
134 changes: 134 additions & 0 deletions internal/quickstart/choose_sdk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package quickstart

import (
"fmt"
"io"
"strings"

"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)

var (
sdkStyle = lipgloss.NewStyle().PaddingLeft(4)
selectedSdkItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170"))
)

type chooseSDKModel struct {
list list.Model
selectedSdk sdkDetail
}

func NewChooseSDKModel() tea.Model {
l := list.New(sdksToItems(), sdkDelegate{}, 30, 14)
l.Title = "Select your SDK:\n"
// reset title styles
l.Styles.Title = lipgloss.NewStyle()
l.Styles.TitleBar = lipgloss.NewStyle()
l.SetShowPagination(true)
l.SetShowStatusBar(false)
l.SetFilteringEnabled(false) // TODO: try to get filtering working
l.Paginator.PerPage = 5

return chooseSDKModel{
list: l,
}
}

func (m chooseSDKModel) Init() tea.Cmd { return nil }

func (m chooseSDKModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.Enter):
i, ok := m.list.SelectedItem().(sdkDetail)
if ok {
m.selectedSdk = i
}
case key.Matches(msg, keys.Quit):
return m, tea.Quit
default:
m.list, cmd = m.list.Update(msg)
}
}

return m, cmd
}

func (m chooseSDKModel) View() string {
return m.list.View()
}

type sdkDetail struct {
DisplayName string `json:"displayName"`
SDKType string `json:"sdkType"`
}

func (s sdkDetail) FilterValue() string { return "" }

const clientSideSDK = "client"
const serverSideSDK = "server"

var SDKs = []sdkDetail{
{DisplayName: "React", SDKType: clientSideSDK},
{DisplayName: "Node.js (server-side)", SDKType: serverSideSDK},
{DisplayName: "Python", SDKType: serverSideSDK},
{DisplayName: "Java", SDKType: serverSideSDK},
{DisplayName: ".NET (server-side)", SDKType: serverSideSDK},
{DisplayName: "JavaScript", SDKType: clientSideSDK},
{DisplayName: "Vue", SDKType: clientSideSDK},
{DisplayName: "iOS", SDKType: clientSideSDK},
{DisplayName: "Go", SDKType: serverSideSDK},
{DisplayName: "Android", SDKType: clientSideSDK},
{DisplayName: "React Native", SDKType: clientSideSDK},
{DisplayName: "Ruby", SDKType: serverSideSDK},
{DisplayName: "Flutter", SDKType: clientSideSDK},
{DisplayName: ".NET (client-side)", SDKType: clientSideSDK},
{DisplayName: "Erlang", SDKType: serverSideSDK},
{DisplayName: "Rust", SDKType: serverSideSDK},
{DisplayName: "Electron", SDKType: clientSideSDK},
{DisplayName: "C/C++ (client-side)", SDKType: clientSideSDK},
{DisplayName: "Roku", SDKType: clientSideSDK},
{DisplayName: "Node.js (client-side)", SDKType: clientSideSDK},
{DisplayName: "C/C++ (server-side)", SDKType: serverSideSDK},
{DisplayName: "Lua", SDKType: serverSideSDK},
{DisplayName: "Haskell", SDKType: serverSideSDK},
{DisplayName: "Apex", SDKType: serverSideSDK},
{DisplayName: "PHP", SDKType: serverSideSDK},
}

func sdksToItems() []list.Item {
items := make([]list.Item, len(SDKs))
for i, sdk := range SDKs {
items[i] = list.Item(sdk)
}

return items
}

type sdkDelegate struct{}

func (d sdkDelegate) Height() int { return 1 }
func (d sdkDelegate) Spacing() int { return 0 }
func (d sdkDelegate) Update(_ tea.Msg, _ *list.Model) tea.Cmd { return nil }
func (d sdkDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
i, ok := listItem.(sdkDetail)
if !ok {
return
}

str := fmt.Sprintf("%d. %s", index+1, i.DisplayName)

fn := sdkStyle.Render
if index == m.Index() {
fn = func(s ...string) string {
return selectedSdkItemStyle.Render("> " + strings.Join(s, " "))
}
}

fmt.Fprint(w, fn(str))
}
15 changes: 12 additions & 3 deletions internal/quickstart/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type step int

const (
createFlagStep step = iota
chooseSDKStep
)

// ContainerModel is a high level container model that controls the nested models wher each
Expand All @@ -25,6 +26,7 @@ type ContainerModel struct {
flagKey string
flagsClient flags.Client
quitting bool
sdk sdkDetail
steps []tea.Model
}

Expand All @@ -34,6 +36,7 @@ func NewContainerModel(flagsClient flags.Client) tea.Model {
flagsClient: flagsClient,
steps: []tea.Model{
NewCreateFlagModel(flagsClient),
NewChooseSDKModel(),
},
}
}
Expand All @@ -53,12 +56,18 @@ func (m ContainerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if model, ok := updated.(createFlagModel); ok {
if model.err != nil {
m.err = model.err

return m, nil
}
m.flagKey = model.flagKey
m.currentStep += 1
}
case chooseSDKStep:
updated, _ := m.steps[chooseSDKStep].Update(msg)
if model, ok := updated.(chooseSDKModel); ok {
// no error state for this step
m.sdk = model.selectedSdk
m.currentStep += 1
}
default:
}
case key.Matches(msg, keys.Quit):
Expand Down Expand Up @@ -90,8 +99,8 @@ func (m ContainerModel) View() string {
}

// TODO: remove after creating more steps
if m.currentStep > createFlagStep {
return fmt.Sprintf("created flag %s", m.flagKey)
if m.currentStep > chooseSDKStep {
return fmt.Sprintf("created flag %s\nselected the %s SDK", m.flagKey, m.sdk.DisplayName)
}

return fmt.Sprintf("\nStep %d of %d\n"+m.steps[m.currentStep].View(), m.currentStep+1, len(m.steps))
Expand Down

0 comments on commit 7518423

Please sign in to comment.