Max Fixes and scrolling update
This commit is contained in:
parent
8046177af0
commit
1eebca289f
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
vendor/
|
||||
/gomod2nix-template
|
||||
result
|
||||
|
||||
configs/servers/default/users/*
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
go run cmd/main.go
|
||||
```
|
||||
|
||||
- Run on nix
|
||||
- Run on nix (don't work for now)
|
||||
|
||||
```shell
|
||||
nix run git+https://git.foglar.tech/foglar/WhspBrd.git
|
||||
|
||||
@ -1,30 +1,12 @@
|
||||
schema = 3
|
||||
|
||||
[mod]
|
||||
[mod."github.com/getlantern/context"]
|
||||
version = "v0.0.0-20190109183933-c447772a6520"
|
||||
hash = "sha256-T4v8t2Hg7lT5d69hD7189WN+dPeMxWXY3vfyiW+oQSM="
|
||||
[mod."github.com/getlantern/errors"]
|
||||
version = "v0.0.0-20190325191628-abdb3e3e36f7"
|
||||
hash = "sha256-AvZvWYUJtOMo7Lk7sZ0BzIougsGltlZ3fAZ6yNjkZs8="
|
||||
[mod."github.com/getlantern/golog"]
|
||||
version = "v0.0.0-20190830074920-4ef2e798c2d7"
|
||||
hash = "sha256-X3o4fSfl+Hb2ZIViUpIg9jpfWjMObrJ53m5E4WFwiLg="
|
||||
[mod."github.com/getlantern/hex"]
|
||||
version = "v0.0.0-20190417191902-c6586a6fe0b7"
|
||||
hash = "sha256-WGOCIMQrXovgp1TGheQv9GOZa/4T5xI2h2gh5Eeqayc="
|
||||
[mod."github.com/getlantern/hidden"]
|
||||
version = "v0.0.0-20190325191715-f02dbb02be55"
|
||||
hash = "sha256-zTYo91NllpZhrWKerxtOdqNkLm7hxpd91POHSAajKT4="
|
||||
[mod."github.com/getlantern/ops"]
|
||||
version = "v0.0.0-20190325191751-d70cb0d6f85f"
|
||||
hash = "sha256-2+oDnDZ1YjJc68ERVV902VAbjmGbFi6rvWtWisFjrlQ="
|
||||
[mod."github.com/getlantern/systray"]
|
||||
version = "v1.2.2"
|
||||
hash = "sha256-GEflgBfashORmopz8kxD7R3GRMKyF7bGE2DXr0w5nX0="
|
||||
[mod."github.com/go-stack/stack"]
|
||||
version = "v1.8.0"
|
||||
hash = "sha256-26RlTEcAkbewMUtmirKrDGQ1WJlNousp69v7HMopYnI="
|
||||
[mod."github.com/Endg4meZer0/go-mpris"]
|
||||
version = "v1.0.5"
|
||||
hash = "sha256-BT5lIuVGPfYCikmVdK8JdTHQorMgALB7a5nScv78GVc="
|
||||
[mod."github.com/godbus/dbus/v5"]
|
||||
version = "v5.1.0"
|
||||
hash = "sha256-xOCMJpQK3KTmHTPn/CdqI4j0eENCtMmJDgAIoYqYOEY="
|
||||
[mod."github.com/jroimartin/gocui"]
|
||||
version = "v0.5.0"
|
||||
hash = "sha256-yNVYFx11d9ITkJKPNoFoGM1gIXnuJBjA4VZJXPh/zZM="
|
||||
@ -34,9 +16,6 @@ schema = 3
|
||||
[mod."github.com/nsf/termbox-go"]
|
||||
version = "v1.1.1"
|
||||
hash = "sha256-Fxk9s3vKmXO3uWmpneN1iZQ+nCbUEZLWShDyeJcwhvM="
|
||||
[mod."github.com/oxtoacart/bpool"]
|
||||
version = "v0.0.0-20190530202638-03653db5a59c"
|
||||
hash = "sha256-Jaw3QTrj05MwADtv7lSjwMACp8s2Z/ratmxPw0t9LbM="
|
||||
[mod."golang.org/x/sys"]
|
||||
version = "v0.30.0"
|
||||
hash = "sha256-BuhWtwDkciVioc03rxty6G2vcZVnPX85lI7tgQOFVP8="
|
||||
|
||||
@ -1,16 +1,22 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"whspbrd/pkg/cell_size"
|
||||
//"whspbrd/pkg/clean_image"
|
||||
"whspbrd/pkg/render_image"
|
||||
"whspbrd/pkg/clean_image"
|
||||
|
||||
"github.com/jroimartin/gocui"
|
||||
)
|
||||
|
||||
var chatData ChatData
|
||||
var selectedUserIdx int = 0
|
||||
|
||||
func layoutChat(g *gocui.Gui, maxX, maxY int) error {
|
||||
if v, err := g.SetView("chat", 21, 0, maxX-1, maxY-5); err != nil {
|
||||
if err != gocui.ErrUnknownView {
|
||||
@ -29,7 +35,7 @@ func layoutInput(g *gocui.Gui, maxX, maxY int) error {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
v.Title = "Type your message"
|
||||
v.Title = " Type your message: "
|
||||
v.Editable = true
|
||||
v.Wrap = true
|
||||
if _, err := g.SetCurrentView("input"); err != nil {
|
||||
@ -42,12 +48,23 @@ func layoutInput(g *gocui.Gui, maxX, maxY int) error {
|
||||
func updateChatView(v *gocui.View) {
|
||||
v.Clear()
|
||||
|
||||
clear := cleanimage.NewKittyImageCleaner()
|
||||
//clear := cleanimage.NewKittyImageCleaner()
|
||||
// TODO: In future optimize this to only clear certain part of screen
|
||||
fmt.Print(clear.DeleteAllVisiblePlacements(true))
|
||||
//fmt.Print(clear.DeleteAllVisiblePlacements(true))
|
||||
|
||||
for i, msg := range chatData.Messages {
|
||||
decoded, err := base64.StdEncoding.DecodeString(msg.Content)
|
||||
if err != nil {
|
||||
log.Printf("Error decoding message: %v", err)
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(string(decoded), "\n") {
|
||||
decoded = []byte(strings.TrimSuffix(string(decoded), "\n"))
|
||||
}
|
||||
|
||||
t, _ := time.Parse(time.RFC3339, msg.Timestamp)
|
||||
formattedTime := t.Format("2006-01-02 15:04")
|
||||
|
||||
for i, msg := range messages {
|
||||
fmt.Fprintf(v, "%s\n\n", msg)
|
||||
w, h, err := cell_size.GetTerminalCellSizePixels()
|
||||
if err != nil {
|
||||
log.Println("Error getting terminal cell size:", err)
|
||||
@ -60,7 +77,16 @@ func updateChatView(v *gocui.View) {
|
||||
w = w*3 - (w / 10)
|
||||
h = 0
|
||||
}
|
||||
render_image.RenderImage("./configs/icon.png", i*3+2, 23, w, h, 0)
|
||||
if !strings.EqualFold(msg.Sender, users[selectedUserIdx]) {
|
||||
|
||||
fmt.Fprintf(v, "%s", "\t\t\t\t\t"+Colors.Text(Colors.Base02)+"You ("+formattedTime+"):"+Colors.Reset+"\n\t\t\t\t\t"+string(decoded)+"\n\n")
|
||||
render_image.RenderImage("./configs/icon.png", i*3+2, 23, w, h, false)
|
||||
|
||||
} else {
|
||||
fmt.Fprintf(v, "%s", "\t\t\t\t\t"+Colors.Text(Colors.Base05)+msg.Sender+" ("+formattedTime+"):"+Colors.Reset+"\n\t\t\t\t\t"+string(decoded)+"\n\n")
|
||||
icon_path := fmt.Sprintf("./configs/servers/default/users/%s/icon.png", strings.ToLower(msg.Sender))
|
||||
render_image.RenderImage(icon_path, i*3+2, 23, w, h, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,8 +98,6 @@ func sendMessage(g *gocui.Gui, v *gocui.View) error {
|
||||
v.SetOrigin(0, 0)
|
||||
|
||||
WriteMessage(users[selectedUserIdx], "You", users[selectedUserIdx], input)
|
||||
|
||||
messages = []string{}
|
||||
LoadMessages(users[selectedUserIdx])
|
||||
|
||||
updateChatView(g.Views()[1])
|
||||
|
||||
@ -15,7 +15,7 @@ func layout(g *gocui.Gui) error {
|
||||
}
|
||||
|
||||
if err := layoutSidebar(g, maxY); err != nil {
|
||||
updateUsersView(g)
|
||||
updateContactsView(g)
|
||||
return err
|
||||
}
|
||||
if err := layoutChat(g, maxX, maxY); err != nil {
|
||||
@ -27,5 +27,3 @@ func layout(g *gocui.Gui) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -103,31 +103,8 @@ func LoadMessages(username string) {
|
||||
return
|
||||
}
|
||||
|
||||
var chatData ChatData
|
||||
if err := json.Unmarshal(data, &chatData); err != nil {
|
||||
log.Printf("Error parsing JSON: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, msg := range chatData.Messages {
|
||||
decoded, err := base64.StdEncoding.DecodeString(msg.Content)
|
||||
if err != nil {
|
||||
log.Printf("Error decoding message: %v", err)
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(string(decoded), "\n") {
|
||||
decoded = []byte(strings.TrimSuffix(string(decoded), "\n"))
|
||||
}
|
||||
|
||||
t, _ := time.Parse(time.RFC3339, msg.Timestamp)
|
||||
formattedTime := t.Format("2006-01-02 15:04")
|
||||
|
||||
// TODO: Move this part to the rendering chat file (./chat.go) and here i should only load all messages and related data to that
|
||||
// TODO: And in the chat file i should get all data in nice structure and then just select what i need from that
|
||||
if !strings.EqualFold(msg.Sender, username) {
|
||||
messages = append(messages, "\t\t\t\t\t"+Colors.Text(Colors.Base02)+"You ("+formattedTime+"):"+Colors.Reset+"\n\t\t\t\t\t"+string(decoded))
|
||||
} else {
|
||||
messages = append(messages, "\t\t\t\t\t"+Colors.Text(Colors.Base05)+msg.Sender+" ("+formattedTime+"):\n"+Colors.Reset+"\t\t\t\t\t"+string(decoded))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
32
internal/tui/profile-sidebar.go
Normal file
32
internal/tui/profile-sidebar.go
Normal file
@ -0,0 +1,32 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"github.com/jroimartin/gocui"
|
||||
)
|
||||
|
||||
func layoutProfile(g *gocui.Gui, maxX, maxY int) error {
|
||||
var VIEW_WIDTH int
|
||||
if maxX-maxX/6 < 21 {
|
||||
VIEW_WIDTH = 30
|
||||
} else {
|
||||
VIEW_WIDTH = maxX - maxX/6
|
||||
}
|
||||
if v, err := g.SetView("profile", VIEW_WIDTH, 0, maxX-1, maxY-5); err != nil {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
v.Title = " Profile "
|
||||
v.Wrap = true
|
||||
//updateProfileView(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func toggleProfileView(g *gocui.Gui, v *gocui.View) error {
|
||||
if _, err := g.View("profile"); err != nil {
|
||||
layoutProfile(g, prevWidth, prevHeight)
|
||||
} else {
|
||||
g.DeleteView("profile")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -1,12 +1,18 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/jroimartin/gocui"
|
||||
)
|
||||
//"math"
|
||||
//"strings"
|
||||
//"whspbrd/pkg/cell_size"
|
||||
"whspbrd/pkg/render_image"
|
||||
//"whspbrd/pkg/resize_image"
|
||||
|
||||
var selectedUserIdx int = 0
|
||||
"github.com/jroimartin/gocui"
|
||||
//"os"
|
||||
)
|
||||
|
||||
// LAYOUT
|
||||
func layoutSidebar(g *gocui.Gui, maxY int) error {
|
||||
@ -16,12 +22,12 @@ func layoutSidebar(g *gocui.Gui, maxY int) error {
|
||||
}
|
||||
v.Title = " Users "
|
||||
v.Clear()
|
||||
updateUsersView(g)
|
||||
updateContactsView(g)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateUsersView(g *gocui.Gui) error {
|
||||
func updateContactsView(g *gocui.Gui) error {
|
||||
v, err := g.View("users")
|
||||
if err != nil {
|
||||
return err
|
||||
@ -29,27 +35,34 @@ func updateUsersView(g *gocui.Gui) error {
|
||||
|
||||
v.Clear()
|
||||
|
||||
messages = nil
|
||||
|
||||
// TODO: If no contacts then error, create some add contacts window or hello to WhspBrd
|
||||
LoadMessages(users[selectedUserIdx])
|
||||
|
||||
// TODO: Render profile image of users and change colors of each user maybe?
|
||||
for i, u := range users {
|
||||
if len(users) == 0 {
|
||||
fmt.Fprintln(v, "No Contacts")
|
||||
return errors.New("no contacts in the list, find some friends")
|
||||
}
|
||||
|
||||
_, maxY := g.Size()
|
||||
h := min(len(users), (maxY / 2) - 1)
|
||||
startI := max(0, min(selectedUserIdx - (h / 2), len(users) - h))
|
||||
|
||||
fmt.Fprint(v, "\n\n")
|
||||
for i := startI; i < startI + h; i++ {
|
||||
u := users[i]
|
||||
|
||||
fmt.Fprint(v, "\t\t\t\t")
|
||||
|
||||
icon_path := fmt.Sprintf("./configs/servers/default/users/%s/icon.png", u)
|
||||
render_image.RenderImage(icon_path, 3 + 2 * (i - startI), 2, 30, 30, false)
|
||||
|
||||
// Change Selected User In The TUI Window
|
||||
if i == selectedUserIdx {
|
||||
fmt.Fprintf(v, "%s%s%s\n", Colors.Background(Colors.Base06), u, Colors.Reset)
|
||||
_, y := v.Size()
|
||||
if i == 0 {
|
||||
v.SetOrigin(0, 0)
|
||||
fmt.Fprintln(v, "\x1b[7m"+u+"\x1b[0m\n")
|
||||
} else {
|
||||
v.SetOrigin(0, i-y+1)
|
||||
fmt.Fprintln(v, u+"\n")
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.Fprintln(v, u)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -59,8 +72,13 @@ func nextContact(g *gocui.Gui, v *gocui.View) error {
|
||||
if len(users) == 0 {
|
||||
return nil
|
||||
}
|
||||
selectedUserIdx = (selectedUserIdx + 1) % len(users)
|
||||
err := updateUsersView(g)
|
||||
selectedUserIdx++
|
||||
if selectedUserIdx == len(users) {
|
||||
selectedUserIdx = 0
|
||||
}
|
||||
|
||||
err := updateContactsView(g)
|
||||
|
||||
updateChatView(g.Views()[1])
|
||||
return err
|
||||
}
|
||||
@ -69,8 +87,13 @@ func prevContact(g *gocui.Gui, v *gocui.View) error {
|
||||
if len(users) == 0 {
|
||||
return nil
|
||||
}
|
||||
selectedUserIdx = (selectedUserIdx - 1 + len(users)) % len(users)
|
||||
err := updateUsersView(g)
|
||||
selectedUserIdx--
|
||||
if selectedUserIdx == -1 {
|
||||
selectedUserIdx = len(users) - 1
|
||||
}
|
||||
|
||||
err := updateContactsView(g)
|
||||
|
||||
updateChatView(g.Views()[1])
|
||||
return err
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import (
|
||||
"github.com/jroimartin/gocui"
|
||||
)
|
||||
|
||||
var messages []string
|
||||
var users []string
|
||||
var prevWidth, prevHeight int
|
||||
|
||||
|
||||
@ -22,30 +22,30 @@ func LoadImage(filePath string) (image.Image, error) {
|
||||
return img, err
|
||||
}
|
||||
|
||||
func convertToRGBA(img image.Image) *image.RGBA {
|
||||
func ConvertToRGBA(img image.Image) *image.RGBA {
|
||||
rgba := image.NewRGBA(img.Bounds())
|
||||
draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)
|
||||
return rgba
|
||||
}
|
||||
|
||||
func encodeImageToBase64RGBA(rgba *image.RGBA) string {
|
||||
func EncodeImageToBase64RGBA(rgba *image.RGBA) string {
|
||||
return base64.StdEncoding.EncodeToString(rgba.Pix)
|
||||
}
|
||||
|
||||
func RenderImage(filepath string, row int, col int, width_ int, height_ int, units int) {
|
||||
func RenderImage(filepath string, row int, col int, width_ int, height_ int, units bool) {
|
||||
img, err := LoadImage(filepath)
|
||||
if err != nil {
|
||||
fmt.Printf("Error loading image: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
rgba := convertToRGBA(img)
|
||||
if units == 1 {
|
||||
rgba := ConvertToRGBA(img)
|
||||
if units {
|
||||
rgba, _ = resize_image.ResizeInTerminal(*rgba, width_, height_)
|
||||
} else {
|
||||
rgba, _ = resize_image.Resize(*rgba, width_, height_)
|
||||
}
|
||||
encoded := encodeImageToBase64RGBA(rgba)
|
||||
encoded := EncodeImageToBase64RGBA(rgba)
|
||||
|
||||
width := rgba.Rect.Dx()
|
||||
height := rgba.Rect.Dy()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user