ArinDash/widgets/qrcode.go

101 lines
2.0 KiB
Go

package widgets
import (
"ArinDash/util"
"context"
"strings"
"github.com/mum4k/termdash/terminal/terminalapi"
"github.com/mum4k/termdash/widgetapi"
"github.com/mum4k/termdash/widgets/text"
"github.com/skip2/go-qrcode"
)
type QRCodeOptions struct {
data string
}
func QRCode(data string) QRCodeOptions {
widgetOptions["QRCodeOptions"] = createQRCode
return QRCodeOptions{
data: data,
}
}
func QrCodeASCII(data string) string {
bitmap := util.PanicOnErrorWithResult(qrcode.New(data, qrcode.Low)).Bitmap()
var stringBuilder strings.Builder
length := (len(bitmap)) / 2
firstLineReached := false
lastLineReached := false
firstColumnReached := false
firstColumn := 0
lastColumn := 0
for i := range length {
if !firstLineReached {
for x := range bitmap[i] {
u := bitmap[i*2][x]
firstLineReached = firstLineReached || u
if firstLineReached && !firstColumnReached {
firstColumn = x
firstColumnReached = true
}
if firstLineReached && u {
lastColumn = x
}
}
}
if firstLineReached {
linesHaveBits := false
for x := range bitmap[i] {
u := bitmap[i*2][x]
d := bitmap[i*2+1][x]
linesHaveBits = linesHaveBits || u || !d
}
lastLineReached = !linesHaveBits
if lastLineReached {
break
}
if stringBuilder.Len() > 0 {
stringBuilder.WriteByte('\n')
}
for x := range bitmap[i] {
if x < firstColumn {
continue
}
if x > lastColumn {
break
}
u := bitmap[i*2][x]
d := bitmap[i*2+1][x]
if u && d {
stringBuilder.WriteString("█")
} else if u {
stringBuilder.WriteString("▀")
} else if d {
stringBuilder.WriteString("▄")
} else {
stringBuilder.WriteString(" ")
}
}
}
}
return stringBuilder.String()
}
func createQRCode(_ context.Context, _ terminalapi.Terminal, opt interface{}) widgetapi.Widget {
options, ok := opt.(QRCodeOptions)
if !ok {
panic("invalid options type")
}
widget := util.PanicOnErrorWithResult(text.New())
util.PanicOnError(widget.Write(QrCodeASCII(options.data)))
return widget
}