1package common23import (4 "context"5 "fmt"67 "charm.land/log/v2"8 "github.com/alecthomas/chroma/v2/lexers"9 "github.com/charmbracelet/soft-serve/git"10 "github.com/charmbracelet/soft-serve/pkg/backend"11 "github.com/charmbracelet/soft-serve/pkg/config"12 "github.com/charmbracelet/soft-serve/pkg/ui/keymap"13 "github.com/charmbracelet/soft-serve/pkg/ui/styles"14 "github.com/charmbracelet/ssh"15 zone "github.com/lrstanley/bubblezone/v2"16)1718type contextKey struct {19 name string20}2122// Keys to use for context.Context.23var (24 ConfigKey = &contextKey{"config"}25 RepoKey = &contextKey{"repo"}26)2728// Common is a struct all components should embed.29type Common struct {30 ctx context.Context31 Width, Height int32 Styles *styles.Styles33 KeyMap *keymap.KeyMap34 Zone *zone.Manager35 Logger *log.Logger36 HideCloneCmd bool37}3839// NewCommon returns a new Common struct.40func NewCommon(ctx context.Context, width, height int) Common {41 if ctx == nil {42 ctx = context.TODO()43 }44 return Common{45 ctx: ctx,46 Width: width,47 Height: height,48 Styles: styles.DefaultStyles(),49 KeyMap: keymap.DefaultKeyMap(),50 Zone: zone.New(),51 Logger: log.FromContext(ctx).WithPrefix("ui"),52 }53}5455// SetValue sets a value in the context.56func (c *Common) SetValue(key, value interface{}) {57 c.ctx = context.WithValue(c.ctx, key, value)58}5960// SetSize sets the width and height of the common struct.61func (c *Common) SetSize(width, height int) {62 c.Width = width63 c.Height = height64}6566// Context returns the context.67func (c *Common) Context() context.Context {68 return c.ctx69}7071// Config returns the server config.72func (c *Common) Config() *config.Config {73 return config.FromContext(c.ctx)74}7576// Backend returns the Soft Serve backend.77func (c *Common) Backend() *backend.Backend {78 return backend.FromContext(c.ctx)79}8081// Repo returns the repository.82func (c *Common) Repo() *git.Repository {83 v := c.ctx.Value(RepoKey)84 if r, ok := v.(*git.Repository); ok {85 return r86 }87 return nil88}8990// PublicKey returns the public key.91func (c *Common) PublicKey() ssh.PublicKey {92 v := c.ctx.Value(ssh.ContextKeyPublicKey)93 if p, ok := v.(ssh.PublicKey); ok {94 return p95 }96 return nil97}9899// CloneCmd returns the clone command string.100func (c *Common) CloneCmd(publicURL, name string) string {101 if c.HideCloneCmd {102 return ""103 }104 return fmt.Sprintf("git clone %s", RepoURL(publicURL, name))105}106107// IsFileMarkdown returns true if the file is markdown.108// It uses chroma lexers to analyze and determine the language.109func IsFileMarkdown(content, ext string) bool {110 var lang string111 lexer := lexers.Match(ext)112 if lexer == nil {113 lexer = lexers.Analyse(content)114 }115 if lexer != nil && lexer.Config() != nil {116 lang = lexer.Config().Name117 }118 return lang == "markdown"119}120121// ScrollPercent returns a string representing the scroll percentage of the122// viewport.123func ScrollPercent(position int) string {124 return fmt.Sprintf("≡ %d%%", position)125}