Skip to content

Commit

Permalink
fix theme switcher
Browse files Browse the repository at this point in the history
  • Loading branch information
mirzakhany committed Oct 13, 2024
1 parent b087fb4 commit 09f702f
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 78 deletions.
62 changes: 31 additions & 31 deletions ui/app/header.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"gioui.org/app"
"gioui.org/layout"
"gioui.org/unit"
"gioui.org/widget"
Expand All @@ -13,9 +14,11 @@ import (
)

type Header struct {
materialTheme *material.Theme
selectedEnv string
envDropDown *widgets.DropDown
w *app.Window

theme *chapartheme.Theme
selectedEnv string
envDropDown *widgets.DropDown

// modal is used to show error and messages to the user
modal *widgets.MessageModal
Expand All @@ -25,36 +28,34 @@ type Header struct {

envState *state.Environments
workspacesState *state.Workspaces
switchState *widget.Bool
themeSwitcher material.SwitchStyle

themeSwitcherClickable widget.Clickable

isDarkMode bool
iconDarkMode material.LabelStyle
iconLightMode material.LabelStyle

OnSelectedEnvChanged func(env *domain.Environment) error
OnSelectedWorkspaceChanged func(env *domain.Workspace) error
OnThemeSwitched func(isLight bool) error
OnThemeSwitched func(isDark bool) error
}

const (
none = "none"
noEnvironment = "No Environment"
)

func NewHeader(envState *state.Environments, workspacesState *state.Workspaces, theme *chapartheme.Theme) *Header {
func NewHeader(w *app.Window, envState *state.Environments, workspacesState *state.Workspaces, theme *chapartheme.Theme) *Header {
h := &Header{
materialTheme: theme.Material(),
w: w,
theme: theme,
selectedEnv: noEnvironment,
envState: envState,
workspacesState: workspacesState,
switchState: new(widget.Bool),
}
h.iconDarkMode = widgets.MaterialIcons("dark_mode", theme)
h.iconLightMode = widgets.MaterialIcons("light_mode", theme)

h.themeSwitcher = material.Switch(theme.Material(), h.switchState, "")
h.themeSwitcher.Color.Enabled = theme.SwitchBgColor
h.themeSwitcher.Color.Disabled = theme.Palette.Fg
h.envDropDown = widgets.NewDropDown(theme)
h.workspaceDropDown = widgets.NewDropDownWithoutBorder(
theme,
Expand Down Expand Up @@ -121,7 +122,16 @@ func (h *Header) SetSelectedEnvironment(env *domain.Environment) {
}

func (h *Header) SetTheme(isDark bool) {
h.switchState.Value = !isDark
h.isDarkMode = isDark
}

func (h *Header) themeSwitchIcon() material.LabelStyle {
if h.isDarkMode {
h.iconDarkMode = widgets.MaterialIcons("dark_mode", h.theme)
return h.iconDarkMode
}
h.iconLightMode = widgets.MaterialIcons("light_mode", h.theme)
return h.iconLightMode
}

func (h *Header) Layout(gtx layout.Context, theme *chapartheme.Theme) layout.Dimensions {
Expand All @@ -148,13 +158,13 @@ func (h *Header) Layout(gtx layout.Context, theme *chapartheme.Theme) layout.Dim
}
}

if h.switchState.Update(gtx) {
if h.themeSwitcherClickable.Clicked(gtx) {
h.isDarkMode = !h.isDarkMode
if h.OnThemeSwitched != nil {
go func() {
if err := h.OnThemeSwitched(!h.switchState.Value); err != nil {
h.showError(err)
}
}()
if err := h.OnThemeSwitched(h.isDarkMode); err != nil {
h.showError(err)
}
h.w.Invalidate()
}
}

Expand All @@ -178,7 +188,7 @@ func (h *Header) Layout(gtx layout.Context, theme *chapartheme.Theme) layout.Dim
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.Inset{Left: unit.Dp(10)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return material.H6(h.materialTheme, "Chapar").Layout(gtx)
return material.H6(h.theme.Material(), "Chapar").Layout(gtx)
})
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
Expand All @@ -191,17 +201,7 @@ func (h *Header) Layout(gtx layout.Context, theme *chapartheme.Theme) layout.Dim
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
h.iconDarkMode.Color = theme.TextColor
return h.iconDarkMode.Layout(gtx)
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.Inset{Right: unit.Dp(10), Left: unit.Dp(10)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return h.themeSwitcher.Layout(gtx)
})
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
h.iconLightMode.Color = theme.TextColor
return h.iconLightMode.Layout(gtx)
return widgets.Clickable(gtx, &h.themeSwitcherClickable, unit.Dp(4), h.themeSwitchIcon().Layout)
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.Inset{Left: unit.Dp(20), Right: unit.Dp(10)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
Expand Down
90 changes: 49 additions & 41 deletions ui/app/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ func New(w *app.Window, serviceVersion string) (*UI, error) {

u.repo = repo

preferences, err := u.repo.ReadPreferencesData()
if err != nil {
return nil, fmt.Errorf("failed to read preferences, %w", err)
}

u.workspacesView = workspaces.NewView()
u.workspacesState = state.NewWorkspaces(repo)
u.workspacesController = workspaces.NewController(u.workspacesView, u.workspacesState, repo)
Expand All @@ -102,12 +107,11 @@ func New(w *app.Window, serviceVersion string) (*UI, error) {

theme := material.NewTheme()
theme.Shaper = text.NewShaper(text.WithCollection(fontCollection))
// lest assume is dark theme, we will switch it later
u.Theme = chapartheme.New(theme, true)
u.Theme = chapartheme.New(theme, preferences.Spec.DarkMode)
// console need to be initialized before other pages as its listening for logs
u.consolePage = console.New()

u.header = NewHeader(u.environmentsState, u.workspacesState, u.Theme)
u.header = NewHeader(w, u.environmentsState, u.workspacesState, u.Theme)
u.sideBar = NewSidebar(u.Theme, serviceVersion)

u.header.LoadWorkspaces(u.workspacesState.GetWorkspaces())
Expand All @@ -119,32 +123,7 @@ func New(w *app.Window, serviceVersion string) (*UI, error) {
u.header.LoadEnvs(u.environmentsState.GetEnvironments())
})

u.header.OnSelectedEnvChanged = func(env *domain.Environment) error {
preferences, err := u.repo.ReadPreferencesData()
if err != nil {
return fmt.Errorf("failed to read preferences, %w", err)
}

if env != nil {
preferences.Spec.SelectedEnvironment.ID = env.MetaData.ID
preferences.Spec.SelectedEnvironment.Name = env.MetaData.Name
} else {
preferences.Spec.SelectedEnvironment.ID = ""
preferences.Spec.SelectedEnvironment.Name = ""
}

if err := repo.UpdatePreferences(preferences); err != nil {
return fmt.Errorf("failed to update preferences, %w", err)
}

if env != nil {
u.environmentsState.SetActiveEnvironment(env)
} else {
u.environmentsState.ClearActiveEnvironment()
}

return nil
}
u.header.OnSelectedEnvChanged = u.onSelectedEnvChanged

u.requestsView = requests.NewView(w, u.Theme, explorerController)
u.requestsController = requests.NewController(u.requestsView, repo, u.requestsState, u.environmentsState, explorerController, egressService, grpcService)
Expand All @@ -165,22 +144,51 @@ func New(w *app.Window, serviceVersion string) (*UI, error) {
u.header.LoadWorkspaces(u.workspacesState.GetWorkspaces())
})

u.header.OnThemeSwitched = func(isDark bool) error {
u.Theme.Switch(isDark)
u.header.OnThemeSwitched = u.onThemeChange

preferences, err := u.repo.ReadPreferencesData()
if err != nil {
return fmt.Errorf("failed to read preferences, %w", err)
}
return u, u.load()
}

preferences.Spec.DarkMode = isDark
if err := repo.UpdatePreferences(preferences); err != nil {
return fmt.Errorf("failed to update preferences, %w", err)
}
return nil
func (u *UI) onSelectedEnvChanged(env *domain.Environment) error {
preferences, err := u.repo.ReadPreferencesData()
if err != nil {
return fmt.Errorf("failed to read preferences, %w", err)
}

return u, u.load()
if env != nil {
preferences.Spec.SelectedEnvironment.ID = env.MetaData.ID
preferences.Spec.SelectedEnvironment.Name = env.MetaData.Name
} else {
preferences.Spec.SelectedEnvironment.ID = ""
preferences.Spec.SelectedEnvironment.Name = ""
}

if err := u.repo.UpdatePreferences(preferences); err != nil {
return fmt.Errorf("failed to update preferences, %w", err)
}

if env != nil {
u.environmentsState.SetActiveEnvironment(env)
} else {
u.environmentsState.ClearActiveEnvironment()
}

return nil
}

func (u *UI) onThemeChange(isDark bool) error {
u.Theme.Switch(isDark)

preferences, err := u.repo.ReadPreferencesData()
if err != nil {
return fmt.Errorf("failed to read preferences, %w", err)
}

preferences.Spec.DarkMode = isDark
if err := u.repo.UpdatePreferences(preferences); err != nil {
return fmt.Errorf("failed to update preferences, %w", err)
}
return nil
}

func (u *UI) load() error {
Expand Down
2 changes: 1 addition & 1 deletion ui/widgets/btn.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (b ButtonStyle) Layout(gtx layout.Context, theme *chapartheme.Theme) layout
})

items := []layout.FlexChild{iconDims, labelDims}
if b.IconPosition == IconPositionEnd {
if b.Icon != nil && b.IconPosition == IconPositionEnd {
items = []layout.FlexChild{labelDims, iconDims}

b.Inset.Right = unit.Dp(5)
Expand Down
7 changes: 5 additions & 2 deletions ui/widgets/clickable.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package widgets

import (
"image"
"image/color"

"gioui.org/io/semantic"
"gioui.org/layout"
"gioui.org/op/clip"
"gioui.org/op/paint"
"gioui.org/unit"
"gioui.org/widget"
)

// Clickable lays out a rectangular clickable widget without further
// decoration.
func Clickable(gtx layout.Context, button *widget.Clickable, w layout.Widget) layout.Dimensions {
func Clickable(gtx layout.Context, button *widget.Clickable, cornerRadius unit.Dp, w layout.Widget) layout.Dimensions {
return button.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
semantic.Button.Add(gtx.Ops)
return layout.Background{}.Layout(gtx,
func(gtx layout.Context) layout.Dimensions {
defer clip.Rect{Max: gtx.Constraints.Min}.Push(gtx.Ops).Pop()
rr := gtx.Dp(cornerRadius)
defer clip.UniformRRect(image.Rectangle{Max: gtx.Constraints.Min}, rr).Push(gtx.Ops).Pop()
if button.Hovered() {
paint.Fill(gtx.Ops, Hovered(color.NRGBA{}))
}
Expand Down
2 changes: 1 addition & 1 deletion ui/widgets/save_btn.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func SaveButtonLayout(gtx layout.Context, theme *chapartheme.Theme, clickable *w

return layout.Inset{Left: unit.Dp(15)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return border.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return Clickable(gtx, clickable, func(gtx layout.Context) layout.Dimensions {
return Clickable(gtx, clickable, unit.Dp(4), func(gtx layout.Context) layout.Dimensions {
return layout.Inset{Left: unit.Dp(4), Right: unit.Dp(4)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return layout.Flex{Axis: layout.Vertical, Alignment: layout.Middle}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
Expand Down
4 changes: 2 additions & 2 deletions ui/widgets/tab.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func (tabs *Tabs) Layout(gtx layout.Context, theme *chapartheme.Theme) layout.Di
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
var dims layout.Dimensions
if t.Closable {
dims = Clickable(gtx, &t.btn, func(gtx layout.Context) layout.Dimensions {
dims = Clickable(gtx, &t.btn, 0, func(gtx layout.Context) layout.Dimensions {
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.UniformInset(unit.Dp(12)).Layout(gtx,
Expand Down Expand Up @@ -223,7 +223,7 @@ func (tabs *Tabs) Layout(gtx layout.Context, theme *chapartheme.Theme) layout.Di
)
})
} else {
dims = Clickable(gtx, &t.btn, func(gtx layout.Context) layout.Dimensions {
dims = Clickable(gtx, &t.btn, 0, func(gtx layout.Context) layout.Dimensions {
return layout.UniformInset(unit.Dp(12)).Layout(gtx,
material.Label(theme.Material(), unit.Sp(13), t.Title).Layout,
)
Expand Down

0 comments on commit 09f702f

Please sign in to comment.