Skip to content

Commit 5e65461

Browse files
committed
Created initial MVC
1 parent 8fac13a commit 5e65461

File tree

10 files changed

+364
-127
lines changed

10 files changed

+364
-127
lines changed

go.mod

+17
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,32 @@ module github.com/kanerix/chitty-chat
33
go 1.23.1
44

55
require (
6+
github.com/charmbracelet/bubbles v0.20.0
7+
github.com/charmbracelet/bubbletea v1.1.2
8+
github.com/charmbracelet/lipgloss v0.13.0
69
github.com/spf13/cobra v1.8.1
710
google.golang.org/grpc v1.67.1
811
google.golang.org/protobuf v1.35.1
912
)
1013

1114
require (
15+
github.com/atotto/clipboard v0.1.4 // indirect
16+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
17+
github.com/charmbracelet/x/ansi v0.4.0 // indirect
18+
github.com/charmbracelet/x/term v0.2.0 // indirect
19+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
1220
github.com/inconshreveable/mousetrap v1.1.0 // indirect
21+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
22+
github.com/mattn/go-isatty v0.0.20 // indirect
23+
github.com/mattn/go-localereader v0.0.1 // indirect
24+
github.com/mattn/go-runewidth v0.0.16 // indirect
25+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
26+
github.com/muesli/cancelreader v0.2.2 // indirect
27+
github.com/muesli/termenv v0.15.2 // indirect
28+
github.com/rivo/uniseg v0.4.7 // indirect
1329
github.com/spf13/pflag v1.0.5 // indirect
1430
golang.org/x/net v0.30.0 // indirect
31+
golang.org/x/sync v0.8.0 // indirect
1532
golang.org/x/sys v0.26.0 // indirect
1633
golang.org/x/text v0.19.0 // indirect
1734
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect

go.sum

+40-27
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,58 @@
1-
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
1+
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
2+
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
3+
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
4+
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
5+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
6+
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
7+
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
8+
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
9+
github.com/charmbracelet/bubbletea v1.1.2 h1:naQXF2laRxyLyil/i7fxdpiz1/k06IKquhm4vBfHsIc=
10+
github.com/charmbracelet/bubbletea v1.1.2/go.mod h1:9HIU/hBV24qKjlehyj8z1r/tR9TYTQEag+cWZnuXo8E=
11+
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
12+
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
13+
github.com/charmbracelet/x/ansi v0.4.0 h1:NqwHA4B23VwsDn4H3VcNX1W1tOmgnvY1NDx5tOXdnOU=
14+
github.com/charmbracelet/x/ansi v0.4.0/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
15+
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
16+
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
217
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
3-
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
4-
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
5-
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
6-
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
7-
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
18+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
19+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
20+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
21+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
822
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
923
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
10-
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
11-
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
12-
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
13-
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
14-
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
15-
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
16-
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
17-
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
18-
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
24+
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
25+
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
26+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
27+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
28+
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
29+
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
30+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
31+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
32+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
33+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
34+
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
35+
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
36+
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
37+
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
38+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
39+
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
40+
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
1941
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
2042
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
2143
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
2244
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
2345
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
24-
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
25-
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
26-
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
27-
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
2846
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
2947
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
30-
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
48+
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
49+
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
50+
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
3151
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
32-
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
33-
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
34-
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
3552
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
3653
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
37-
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
38-
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
3954
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
4055
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
41-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
42-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
4356
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc=
4457
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
4558
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=

internal/client/chat.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package client
2+
3+
import (
4+
"context"
5+
6+
pb "github.com/kanerix/chitty-chat/proto"
7+
"google.golang.org/grpc"
8+
)
9+
10+
type ChatClient struct {
11+
pb.ChatClient
12+
}
13+
14+
type BroadcastStream struct {
15+
pb.Chat_BroadcastClient
16+
}
17+
18+
func NewChatClient(conn *grpc.ClientConn) *ChatClient {
19+
return &ChatClient{
20+
pb.NewChatClient(conn),
21+
}
22+
}
23+
24+
func (cc *ChatClient) Stream(ctx context.Context) (*BroadcastStream, error) {
25+
stream, err := cc.Broadcast(ctx)
26+
if err != nil {
27+
return nil, err
28+
}
29+
30+
return &BroadcastStream{
31+
stream,
32+
}, nil
33+
}
34+
35+
func (bs *BroadcastStream) JoinChat(username string) error {
36+
if err := bs.Send(&pb.ChatEvent{
37+
Event: &pb.ChatEvent_Join{
38+
Join: &pb.ChatEvent_UserJoin{
39+
Username: username,
40+
},
41+
},
42+
}); err != nil {
43+
return err
44+
}
45+
46+
return nil
47+
}
48+
49+
func (bs *BroadcastStream) LeaveChat(username string) error {
50+
if err := bs.Send(&pb.ChatEvent{
51+
Event: &pb.ChatEvent_Leave{
52+
Leave: &pb.ChatEvent_UserLeave{
53+
Username: username,
54+
},
55+
},
56+
}); err != nil {
57+
return err
58+
}
59+
60+
return nil
61+
}
62+
63+
func (bs *BroadcastStream) SendMessage(username string, message string) error {
64+
if err := bs.Send(&pb.ChatEvent{
65+
Event: &pb.ChatEvent_Message{
66+
Message: &pb.ChatEvent_ChatMessage{
67+
Username: username,
68+
},
69+
},
70+
}); err != nil {
71+
return err
72+
}
73+
74+
return nil
75+
}

internal/cmd/chat.go

+5-98
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
package cmd
22

33
import (
4-
"bufio"
5-
"context"
6-
"fmt"
7-
"os"
8-
"os/signal"
9-
"syscall"
10-
11-
pb "github.com/kanerix/chitty-chat/proto"
4+
tea "github.com/charmbracelet/bubbletea"
5+
"github.com/kanerix/chitty-chat/internal/mvc"
126
"github.com/spf13/cobra"
137
"google.golang.org/grpc"
148
"google.golang.org/grpc/credentials/insecure"
@@ -25,99 +19,12 @@ var chatCmd = &cobra.Command{
2519
if err != nil {
2620
return err
2721
}
28-
defer conn.Close()
29-
30-
client := pb.NewChatClient(conn)
3122

32-
stream, err := client.Broadcast(context.Background())
33-
if err != nil {
23+
p := tea.NewProgram(mvc.NewChatModel(conn, username), tea.WithAltScreen())
24+
if _, err := p.Run(); err != nil {
3425
return err
3526
}
3627

37-
shutdown := make(chan os.Signal, 1)
38-
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)
39-
40-
ch := make(chan error)
41-
42-
go joinChat(stream, ch)
43-
go leaveChat(stream, shutdown)
44-
45-
go messageListener(stream, ch)
46-
go inputListener(stream, ch)
47-
48-
for {
49-
select {
50-
case err := <-ch:
51-
cmd.PrintErrln(err)
52-
case <-stream.Context().Done():
53-
return nil
54-
}
55-
}
28+
return nil
5629
},
5730
}
58-
59-
func init() {
60-
chatCmd.Flags().StringVarP(
61-
&username,
62-
"username",
63-
"u",
64-
"",
65-
"The username to use",
66-
)
67-
chatCmd.MarkFlagRequired("username")
68-
}
69-
70-
func joinChat(stream pb.Chat_BroadcastClient, errorCh chan error) {
71-
if err := stream.Send(&pb.ChatEvent{
72-
Event: &pb.ChatEvent_Join{
73-
Join: &pb.ChatEvent_UserJoin{
74-
Username: username,
75-
},
76-
},
77-
}); err != nil {
78-
errorCh <- err
79-
}
80-
}
81-
82-
func leaveChat(stream pb.Chat_BroadcastClient, shutdown chan os.Signal) {
83-
<-shutdown
84-
85-
stream.Send(&pb.ChatEvent{
86-
Event: &pb.ChatEvent_Leave{
87-
Leave: &pb.ChatEvent_UserLeave{
88-
Username: username,
89-
},
90-
},
91-
})
92-
93-
os.Exit(0)
94-
}
95-
96-
func messageListener(stream pb.Chat_BroadcastClient, errorCh chan error) {
97-
for {
98-
req, err := stream.Recv()
99-
if err != nil {
100-
errorCh <- err
101-
}
102-
103-
fmt.Printf("%d @ %s - %s\n", req.Timestamp, req.Username, req.Message)
104-
}
105-
}
106-
107-
func inputListener(stream pb.Chat_BroadcastClient, errorCh chan error) error {
108-
for {
109-
input := bufio.NewScanner(os.Stdin)
110-
input.Scan()
111-
112-
if err := stream.Send(&pb.ChatEvent{
113-
Event: &pb.ChatEvent_Message{
114-
Message: &pb.ChatEvent_ChatMessage{
115-
Username: username,
116-
Message: input.Text(),
117-
},
118-
},
119-
}); err != nil {
120-
errorCh <- err
121-
}
122-
}
123-
}

internal/cmd/root.go

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import (
44
"github.com/spf13/cobra"
55
)
66

7-
type TokenKey struct{}
8-
97
var Hostname string
108

119
var RootCmd = &cobra.Command{

internal/mvc/chat.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package mvc
2+
3+
import "github.com/charmbracelet/bubbles/viewport"
4+
5+
type ChatView struct {
6+
viewport.Model
7+
messages []string
8+
}
9+
10+
func NewChatView() ChatView {
11+
view := ChatView{
12+
Model: viewport.New(Width, 5),
13+
messages: make([]string, 10),
14+
}
15+
16+
view.SetContent("Welcome to Chitty Chat!")
17+
18+
return view
19+
}

internal/mvc/constants.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package mvc
2+
3+
import "errors"
4+
5+
const (
6+
Width = 30
7+
)
8+
9+
var (
10+
ErrInvalidMessage = errors.New("invalid message")
11+
ErrStreamClosed = errors.New("stream closed")
12+
)

internal/mvc/input.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package mvc
2+
3+
import (
4+
"github.com/charmbracelet/bubbles/textarea"
5+
tea "github.com/charmbracelet/bubbletea"
6+
"github.com/charmbracelet/lipgloss"
7+
)
8+
9+
type InputArea struct {
10+
textarea.Model
11+
}
12+
13+
func NewInputArea() InputArea {
14+
area := InputArea{textarea.New()}
15+
area.Placeholder = "Send a message..."
16+
area.Focus()
17+
18+
area.Prompt = ">>> "
19+
area.CharLimit = 128
20+
21+
area.SetWidth(Width)
22+
area.SetHeight(1)
23+
24+
area.FocusedStyle.CursorLine = lipgloss.NewStyle()
25+
area.ShowLineNumbers = false
26+
area.KeyMap.InsertNewline.SetEnabled(false)
27+
28+
return area
29+
}
30+
31+
func (nv InputArea) Update(msg tea.Msg) (InputArea, tea.Cmd) {
32+
area, cmd := nv.Model.Update(msg)
33+
nv = InputArea{Model: area}
34+
return nv, cmd
35+
}

0 commit comments

Comments
 (0)