1package common
2
3import (
4 "fmt"
5 "image"
6 "os"
7
8 tea "charm.land/bubbletea/v2"
9 "github.com/atotto/clipboard"
10 "github.com/charmbracelet/crush/internal/app"
11 "github.com/charmbracelet/crush/internal/config"
12 "github.com/charmbracelet/crush/internal/ui/styles"
13 "github.com/charmbracelet/crush/internal/uiutil"
14 uv "github.com/charmbracelet/ultraviolet"
15)
16
17// MaxAttachmentSize defines the maximum allowed size for file attachments (5 MB).
18const MaxAttachmentSize = int64(5 * 1024 * 1024)
19
20// AllowedImageTypes defines the permitted image file types.
21var AllowedImageTypes = []string{".jpg", ".jpeg", ".png"}
22
23// Common defines common UI options and configurations.
24type Common struct {
25 App *app.App
26 Styles *styles.Styles
27}
28
29// Config returns the configuration associated with this [Common] instance.
30func (c *Common) Config() *config.Config {
31 return c.App.Config()
32}
33
34// DefaultCommon returns the default common UI configurations.
35func DefaultCommon(app *app.App) *Common {
36 s := styles.DefaultStyles()
37 return &Common{
38 App: app,
39 Styles: &s,
40 }
41}
42
43// CenterRect returns a new [Rectangle] centered within the given area with the
44// specified width and height.
45func CenterRect(area uv.Rectangle, width, height int) uv.Rectangle {
46 centerX := area.Min.X + area.Dx()/2
47 centerY := area.Min.Y + area.Dy()/2
48 minX := centerX - width/2
49 minY := centerY - height/2
50 maxX := minX + width
51 maxY := minY + height
52 return image.Rect(minX, minY, maxX, maxY)
53}
54
55// IsFileTooBig checks if the file at the given path exceeds the specified size
56// limit.
57func IsFileTooBig(filePath string, sizeLimit int64) (bool, error) {
58 fileInfo, err := os.Stat(filePath)
59 if err != nil {
60 return false, fmt.Errorf("error getting file info: %w", err)
61 }
62
63 if fileInfo.Size() > sizeLimit {
64 return true, nil
65 }
66
67 return false, nil
68}
69
70// CopyToClipboard copies the given text to the clipboard using both OSC 52
71// (terminal escape sequence) and native clipboard for maximum compatibility.
72// Returns a command that reports success to the user with the given message.
73func CopyToClipboard(text, successMessage string) tea.Cmd {
74 return CopyToClipboardWithCallback(text, successMessage, nil)
75}
76
77// CopyToClipboardWithCallback copies text to clipboard and executes a callback
78// before showing the success message.
79// This is useful when you need to perform additional actions like clearing UI state.
80func CopyToClipboardWithCallback(text, successMessage string, callback tea.Cmd) tea.Cmd {
81 return tea.Sequence(
82 tea.SetClipboard(text),
83 func() tea.Msg {
84 _ = clipboard.WriteAll(text)
85 return nil
86 },
87 callback,
88 uiutil.ReportInfo(successMessage),
89 )
90}