summaryrefslogtreecommitdiffhomepage
path: root/internal/tui/components/qr
diff options
context:
space:
mode:
Diffstat (limited to 'internal/tui/components/qr')
-rw-r--r--internal/tui/components/qr/qr.go58
1 files changed, 58 insertions, 0 deletions
diff --git a/internal/tui/components/qr/qr.go b/internal/tui/components/qr/qr.go
new file mode 100644
index 000000000..42a60bb5e
--- /dev/null
+++ b/internal/tui/components/qr/qr.go
@@ -0,0 +1,58 @@
+package qr
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/lipgloss"
+ "github.com/sst/opencode/internal/tui/theme"
+ "rsc.io/qr"
+)
+
+var tops_bottoms = []rune{' ', '▀', '▄', '█'}
+
+// Generate a text string to a QR code, which you can write to a terminal or file.
+func Generate(text string) (string, int, error) {
+ code, err := qr.Encode(text, qr.Level(0))
+ if err != nil {
+ return "", 0, err
+ }
+
+ t := theme.CurrentTheme()
+ if t == nil {
+ return "", 0, err
+ }
+
+ // Create lipgloss style for QR code with theme colors
+ qrStyle := lipgloss.NewStyle().
+ Foreground(t.Text()).
+ Background(t.Background())
+
+ var result strings.Builder
+
+ // content
+ for y := 0; y < code.Size-1; y += 2 {
+ var line strings.Builder
+ for x := 0; x < code.Size; x += 1 {
+ var num int8
+ if code.Black(x, y) {
+ num += 1
+ }
+ if code.Black(x, y+1) {
+ num += 2
+ }
+ line.WriteRune(tops_bottoms[num])
+ }
+ result.WriteString(qrStyle.Render(line.String()) + "\n")
+ }
+
+ // add lower border when required (only required when QR size is odd)
+ if code.Size%2 == 1 {
+ var borderLine strings.Builder
+ for range code.Size {
+ borderLine.WriteRune('▀')
+ }
+ result.WriteString(qrStyle.Render(borderLine.String()) + "\n")
+ }
+
+ return result.String(), code.Size, nil
+}