gobs-cli/group.go
onyx-and-iris 7147c3f1ca style tables and add out/err highlights
improve projector open error message if an invalid monitor index is passed.
it now prints the monitor name and suggests `gobs-cli prj ls-m`

improve error message for sceneitem commands if a scene item in a group is queried without the --group flag.
2025-06-21 06:41:12 +01:00

231 lines
7.2 KiB
Go

package main
import (
"fmt"
"github.com/andreykaipov/goobs/api/requests/sceneitems"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/table"
)
// GroupCmd provides commands to manage groups in OBS Studio.
type GroupCmd struct {
List GroupListCmd `cmd:"" help:"List all groups." aliases:"ls"`
Show GroupShowCmd `cmd:"" help:"Show group details." aliases:"sh"`
Hide GroupHideCmd `cmd:"" help:"Hide group." aliases:"h"`
Toggle GroupToggleCmd `cmd:"" help:"Toggle group." aliases:"tg"`
Status GroupStatusCmd `cmd:"" help:"Get group status." aliases:"ss"`
}
// GroupListCmd provides a command to list all groups in a scene.
type GroupListCmd struct {
SceneName string `arg:"" help:"Name of the scene to list groups from." default:""`
}
// Run executes the command to list all groups in a scene.
// nolint: misspell
func (cmd *GroupListCmd) Run(ctx *context) error {
if cmd.SceneName == "" {
currentScene, err := ctx.Client.Scenes.GetCurrentProgramScene()
if err != nil {
return fmt.Errorf("failed to get current program scene: %w", err)
}
cmd.SceneName = currentScene.SceneName
}
resp, err := ctx.Client.SceneItems.GetSceneItemList(sceneitems.NewGetSceneItemListParams().
WithSceneName(cmd.SceneName))
if err != nil {
return fmt.Errorf("failed to get scene item list: %w", err)
}
t := table.New().Border(lipgloss.RoundedBorder()).
BorderStyle(lipgloss.NewStyle().Foreground(ctx.Style.border)).
Headers("ID", "Group Name", "Enabled").
StyleFunc(func(row, col int) lipgloss.Style {
style := lipgloss.NewStyle().Padding(0, 3)
switch col {
case 0:
style = style.Align(lipgloss.Center)
case 1:
style = style.Align(lipgloss.Left)
case 2:
style = style.Align(lipgloss.Center)
}
switch {
case row == table.HeaderRow:
style = style.Bold(true).Align(lipgloss.Center)
case row%2 == 0:
style = style.Foreground(ctx.Style.evenRows)
default:
style = style.Foreground(ctx.Style.oddRows)
}
return style
})
var found bool
for _, item := range resp.SceneItems {
if item.IsGroup {
t.Row(fmt.Sprintf("%d", item.SceneItemID), item.SourceName, getEnabledMark(item.SceneItemEnabled))
found = true
}
}
if !found {
fmt.Fprintf(ctx.Out, "No groups found in scene %s.\n", ctx.Style.Highlight(cmd.SceneName))
return nil
}
fmt.Fprintln(ctx.Out, t.Render())
return nil
}
// GroupShowCmd provides a command to show a group in a scene.
type GroupShowCmd struct {
SceneName string `arg:"" help:"Name of the scene to show group from."`
GroupName string `arg:"" help:"Name of the group to show."`
}
// Run executes the command to show a group in a scene.
func (cmd *GroupShowCmd) Run(ctx *context) error {
resp, err := ctx.Client.SceneItems.GetSceneItemList(sceneitems.NewGetSceneItemListParams().
WithSceneName(cmd.SceneName))
if err != nil {
return fmt.Errorf("failed to get scene item list: %w", err)
}
var found bool
for _, item := range resp.SceneItems {
if item.IsGroup && item.SourceName == cmd.GroupName {
_, err := ctx.Client.SceneItems.SetSceneItemEnabled(sceneitems.NewSetSceneItemEnabledParams().
WithSceneName(cmd.SceneName).
WithSceneItemId(item.SceneItemID).
WithSceneItemEnabled(true))
if err != nil {
return fmt.Errorf("failed to set scene item enabled: %w", err)
}
fmt.Fprintf(ctx.Out, "Group %s is now shown.\n", ctx.Style.Highlight(cmd.GroupName))
found = true
break
}
}
if !found {
return fmt.Errorf(
"group %s not found in scene %s",
ctx.Style.Error(cmd.GroupName),
ctx.Style.Error(cmd.SceneName),
)
}
return nil
}
// GroupHideCmd provides a command to hide a group in a scene.
type GroupHideCmd struct {
SceneName string `arg:"" help:"Name of the scene to hide group from."`
GroupName string `arg:"" help:"Name of the group to hide."`
}
// Run executes the command to hide a group in a scene.
func (cmd *GroupHideCmd) Run(ctx *context) error {
resp, err := ctx.Client.SceneItems.GetSceneItemList(sceneitems.NewGetSceneItemListParams().
WithSceneName(cmd.SceneName))
if err != nil {
return fmt.Errorf("failed to get scene item list: %w", err)
}
var found bool
for _, item := range resp.SceneItems {
if item.IsGroup && item.SourceName == cmd.GroupName {
_, err := ctx.Client.SceneItems.SetSceneItemEnabled(sceneitems.NewSetSceneItemEnabledParams().
WithSceneName(cmd.SceneName).
WithSceneItemId(item.SceneItemID).
WithSceneItemEnabled(false))
if err != nil {
return fmt.Errorf("failed to set scene item enabled: %w", err)
}
fmt.Fprintf(ctx.Out, "Group %s is now hidden.\n", ctx.Style.Highlight(cmd.GroupName))
found = true
break
}
}
if !found {
return fmt.Errorf(
"group %s not found in scene %s",
ctx.Style.Error(cmd.GroupName),
ctx.Style.Error(cmd.SceneName),
)
}
return nil
}
// GroupToggleCmd provides a command to toggle a group in a scene.
type GroupToggleCmd struct {
SceneName string `arg:"" help:"Name of the scene to toggle group from."`
GroupName string `arg:"" help:"Name of the group to toggle."`
}
// Run executes the command to toggle a group in a scene.
func (cmd *GroupToggleCmd) Run(ctx *context) error {
resp, err := ctx.Client.SceneItems.GetSceneItemList(sceneitems.NewGetSceneItemListParams().
WithSceneName(cmd.SceneName))
if err != nil {
return fmt.Errorf("failed to get scene item list: %w", err)
}
var found bool
for _, item := range resp.SceneItems {
if item.IsGroup && item.SourceName == cmd.GroupName {
newState := !item.SceneItemEnabled
_, err := ctx.Client.SceneItems.SetSceneItemEnabled(sceneitems.NewSetSceneItemEnabledParams().
WithSceneName(cmd.SceneName).
WithSceneItemId(item.SceneItemID).
WithSceneItemEnabled(newState))
if err != nil {
return fmt.Errorf("failed to set scene item enabled: %w", err)
}
if newState {
fmt.Fprintf(ctx.Out, "Group %s is now shown.\n", ctx.Style.Highlight(cmd.GroupName))
} else {
fmt.Fprintf(ctx.Out, "Group %s is now hidden.\n", ctx.Style.Highlight(cmd.GroupName))
}
found = true
break
}
}
if !found {
return fmt.Errorf(
"group %s not found in scene %s",
ctx.Style.Error(cmd.GroupName),
ctx.Style.Error(cmd.SceneName),
)
}
return nil
}
// GroupStatusCmd provides a command to get the status of a group in a scene.
type GroupStatusCmd struct {
SceneName string `arg:"" help:"Name of the scene to get group status from."`
GroupName string `arg:"" help:"Name of the group to get status."`
}
// Run executes the command to get the status of a group in a scene.
func (cmd *GroupStatusCmd) Run(ctx *context) error {
resp, err := ctx.Client.SceneItems.GetSceneItemList(sceneitems.NewGetSceneItemListParams().
WithSceneName(cmd.SceneName))
if err != nil {
return fmt.Errorf("failed to get scene item list: %w", err)
}
for _, item := range resp.SceneItems {
if item.IsGroup && item.SourceName == cmd.GroupName {
if item.SceneItemEnabled {
fmt.Fprintf(ctx.Out, "Group %s is shown.\n", ctx.Style.Highlight(cmd.GroupName))
} else {
fmt.Fprintf(ctx.Out, "Group %s is hidden.\n", ctx.Style.Highlight(cmd.GroupName))
}
return nil
}
}
return fmt.Errorf("group %s not found in scene %s", ctx.Style.Error(cmd.GroupName), ctx.Style.Error(cmd.SceneName))
}