Skip to content

Commit

Permalink
fix: fix viewport (#280)
Browse files Browse the repository at this point in the history
Update viewport to show more of the sample SDK code at once
  • Loading branch information
dbolson authored May 14, 2024
1 parent 00eb55f commit d079561
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 36 deletions.
17 changes: 10 additions & 7 deletions cmd/quickstart.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,16 @@ func runQuickStart(
viper.GetString(cliflags.BaseURIFlag),
viper.GetBool(cliflags.AnalyticsOptOut),
)
_, err = tea.NewProgram(quickstart.NewContainerModel(
analyticsTracker,
environmentsClient,
flagsClient,
viper.GetString(cliflags.AccessTokenFlag),
viper.GetString(cliflags.BaseURIFlag),
)).Run()
_, err = tea.NewProgram(
quickstart.NewContainerModel(
analyticsTracker,
environmentsClient,
flagsClient,
viper.GetString(cliflags.AccessTokenFlag),
viper.GetString(cliflags.BaseURIFlag),
),
tea.WithAltScreen(),
).Run()
if err != nil {
log.Fatal(err)
}
Expand Down
11 changes: 9 additions & 2 deletions internal/quickstart/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type ContainerModel struct {
flagToggled bool
flagsClient flags.Client
gettingStarted bool
height int
quitting bool
sdk sdkDetail
startTime time.Time
Expand Down Expand Up @@ -94,7 +95,9 @@ func (m ContainerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var shouldSendTrackingEvent bool
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.height = msg.Height
m.width = msg.Width
m.currentModel, cmd = m.currentModel.Update(msg)
case tea.KeyMsg:
switch {
case key.Matches(msg, pressableKeys.Quit):
Expand All @@ -120,6 +123,8 @@ func (m ContainerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.flagsClient,
m.accessToken,
m.baseURI,
m.height,
m.width,
m.sdk.canonicalName,
m.sdk.displayName,
m.sdk.url,
Expand All @@ -146,6 +151,8 @@ func (m ContainerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.flagsClient,
m.accessToken,
m.baseURI,
m.height,
m.width,
msg.sdk.canonicalName,
msg.sdk.displayName,
msg.sdk.url,
Expand Down Expand Up @@ -231,14 +238,14 @@ func (m ContainerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}

func (m ContainerModel) View() string {
out := fmt.Sprintf("\nStep %d of %d\n"+m.currentModel.View(), m.currentStep, m.totalSteps)
out := fmt.Sprintf("Step %d of %d\n"+m.currentModel.View(), m.currentStep, m.totalSteps)

if m.quitting {
return ""
}

if m.gettingStarted {
out = "Within this guided setup flow, you'll be creating a new feature flag and,\nusing the SDK of your choice, building a small sample application to see a\nfeature flag toggle on and off in real time.\n\nLet's get started!\n" + out
out = "Within this guided setup flow, you'll be creating a new feature flag and,\nusing the SDK of your choice, building a small sample application to see a\nfeature flag toggle on and off in real time.\n\nLet's get started!\n\n" + out
}

return wordwrap.String(out, m.width)
Expand Down
2 changes: 1 addition & 1 deletion internal/quickstart/create_flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (m createFlagModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

func (m createFlagModel) View() string {
style := lipgloss.NewStyle().
MarginLeft(2)
MarginLeft(1)

if m.showSuccessView {
successMessage := fmt.Sprintf("Flag %q created successfully!", m.flag.name)
Expand Down
85 changes: 59 additions & 26 deletions internal/quickstart/show_sdk_instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ import (
"ldcli/internal/sdks"
)

const (
viewportWidth = 80
viewportHeight = 30
)
// stepCountHeight is the approximate height of the current step value shown from the container and
// is used to calculate height of viewport.
const stepCountHeight = 4

type environment struct {
sdkKey string
Expand Down Expand Up @@ -51,6 +50,8 @@ func NewShowSDKInstructionsModel(
flagsClient flags.Client,
accessToken string,
baseUri string,
height int,
width int,
canonicalName string,
displayName string,
url string,
Expand All @@ -61,17 +62,7 @@ func NewShowSDKInstructionsModel(
s := spinner.New()
s.Spinner = spinner.Points

vp := viewport.New(viewportWidth, viewportHeight)
vp.Style = lipgloss.NewStyle().
BorderStyle(lipgloss.ThickBorder()).
BorderForeground(lipgloss.Color("62")).
BorderTop(true).
BorderBottom(true).
PaddingRight(2)

h := help.New()

return showSDKInstructionsModel{
m := showSDKInstructionsModel{
accessToken: accessToken,
baseUri: baseUri,
canonicalName: canonicalName,
Expand All @@ -80,18 +71,26 @@ func NewShowSDKInstructionsModel(
environment: environment,
flagsClient: flagsClient,
flagKey: flagKey,
help: h,
help: help.New(),
helpKeys: keyMap{
Back: BindingBack,
CursorDown: BindingCursorDown,
CursorUp: BindingCursorUp,
Quit: BindingQuit,
},
sdkKind: sdkKind,
spinner: s,
url: url,
viewport: vp,
sdkKind: sdkKind,
spinner: s,
url: url,
}

vp := viewport.New(
width,
m.getViewportHeight(height),
)

m.viewport = vp

return m
}

// Init sends commands when the model is created that will:
Expand All @@ -115,6 +114,8 @@ func (m showSDKInstructionsModel) Init() tea.Cmd {
func (m showSDKInstructionsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.viewport.Height = m.getViewportHeight(msg.Height)
case tea.KeyMsg:
switch {
case key.Matches(msg, pressableKeys.Enter):
Expand All @@ -130,15 +131,15 @@ func (m showSDKInstructionsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if err != nil {
return m, sendErrMsg(err)
}
m.viewport.SetContent(md)
m.viewport.SetContent(m.headerView() + md)
}
case fetchedEnvMsg:
m.environment = &msg.environment
md, err := m.renderMarkdown()
if err != nil {
return m, sendErrMsg(err)
}
m.viewport.SetContent(md)
m.viewport.SetContent(m.headerView() + md)
case spinner.TickMsg:
m.spinner, cmd = m.spinner.Update(msg)
case errMsg:
Expand All @@ -159,7 +160,14 @@ func (m showSDKInstructionsModel) View() string {

m.help.ShowAll = true

instructions := fmt.Sprintf(`
return m.viewport.View() + m.footerView()
}

func (m showSDKInstructionsModel) headerView() string {
style := borderStyle().BorderBottom(true)

return style.Render(
fmt.Sprintf(`
Here are the steps to set up a test app to see feature flagging in action
using the %s SDK in your Default project & Test environment.
Expand All @@ -172,10 +180,21 @@ Open a new terminal window to get started.
If you want to skip ahead, the final code is available in our GitHub repository:
%s
`,
m.displayName,
m.url,
m.displayName,
m.url,
),
)
}

func (m showSDKInstructionsModel) footerView() string {
// set the width to tbe the same as the header so the borders are the same length
style := borderStyle().
BorderTop(true).
Width(lipgloss.Width(m.headerView()))

return style.Render(
"\n(press enter to continue)" + footerView(m.help.View(m.helpKeys), nil),
)
return instructions + m.viewport.View() + "\n(press enter to continue)" + footerView(m.help.View(m.helpKeys), nil)
}

func (m showSDKInstructionsModel) renderMarkdown() (string, error) {
Expand All @@ -187,8 +206,10 @@ func (m showSDKInstructionsModel) renderMarkdown() (string, error) {
m.environment.mobileKey,
)

// set the width to be as long as possible to have less line wrapping in the SDK code
renderer, err := glamour.NewTermRenderer(
glamour.WithAutoStyle(),
glamour.WithWordWrap(m.viewport.Width),
)
if err != nil {
return "", err
Expand All @@ -201,3 +222,15 @@ func (m showSDKInstructionsModel) renderMarkdown() (string, error) {

return out, nil
}

func (m showSDKInstructionsModel) getViewportHeight(h int) int {
return h - lipgloss.Height(m.footerView()) - stepCountHeight
}

// borderStyle sets a border for the bottom of the headerView and the top of the footerView to show a
// border around the SDK code.
func borderStyle() lipgloss.Style {
return lipgloss.NewStyle().
BorderForeground(lipgloss.Color("62")).
BorderStyle(lipgloss.ThickBorder())
}

0 comments on commit d079561

Please sign in to comment.