mirror of
https://github.com/IllusionMan1212/gorc.git
synced 2026-10-24 18:12:33 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ddd238552
|
@@ -0,0 +1,11 @@
|
|||||||
|
# progress
|
||||||
|
it works nicely when there isn't spamming going on.
|
||||||
|
|
||||||
|
if spamming:
|
||||||
|
when pressing g while a message is being received the calculation messes up and the first shown message is actually the 2nd or 3rd
|
||||||
|
when pressing G while a message is being received a message or two will be missing, im suspecting this happens because of the ToInsert gets written to the db but we already fetched from the db so ToInsert is empty even tho we haven't appened it yet. (same thing happens when going down with d)
|
||||||
|
-- potential fixes
|
||||||
|
- save stuff to db message by message (this is slow as shit, but maybe goroutines could do something here ???)
|
||||||
|
- same way of throttling the message receiving when a key is pressed such as g, G, d or etc..
|
||||||
|
- maybe there's a way to optimize the readfromdb cmd, maybe the pointer stuff is slowing it down. idk
|
||||||
|
- last resort is making this whole feature an option for people that know they have slow chats and want to keep the program open for days (idk)
|
||||||
+139
@@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
"github.com/illusionman1212/gorc/irc"
|
"github.com/illusionman1212/gorc/irc"
|
||||||
|
"github.com/illusionman1212/gorc/irc/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConnectMsg struct{}
|
type ConnectMsg struct{}
|
||||||
@@ -40,6 +41,15 @@ func Quit(client *irc.Client) tea.Cmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TickMsg struct{}
|
||||||
|
|
||||||
|
func Tick(client *irc.Client) tea.Cmd {
|
||||||
|
return tea.Tick(time.Second/60, func(time.Time) tea.Msg {
|
||||||
|
client.SendCommand(commands.PRIVMSG, "#hell", fmt.Sprintf("%d", client.Ticks))
|
||||||
|
return TickMsg{}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type SendPrivMsgMsg struct {
|
type SendPrivMsgMsg struct {
|
||||||
Msg string
|
Msg string
|
||||||
Timestamp string
|
Timestamp string
|
||||||
@@ -74,3 +84,132 @@ type UpdateTabBarMsg struct{}
|
|||||||
func UpdateTabBar() tea.Msg {
|
func UpdateTabBar() tea.Msg {
|
||||||
return UpdateTabBarMsg{}
|
return UpdateTabBarMsg{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReadHistoryFromDBMsg struct {
|
||||||
|
LinesRead uint64
|
||||||
|
Direction string
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadHistoryFromDB(client *irc.Client, linesToRead int, direction string) tea.Cmd {
|
||||||
|
hash := client.Channels[client.ActiveChannelIndex].Hash
|
||||||
|
scrollBackBufFirstLine := client.Channels[client.ActiveChannelIndex].ScrollBackBufFirstLine
|
||||||
|
|
||||||
|
messages := make([]string, 0)
|
||||||
|
|
||||||
|
switch direction {
|
||||||
|
case "top":
|
||||||
|
client.DB.
|
||||||
|
Table("histories").
|
||||||
|
Select("message").
|
||||||
|
Where("hash = ?", hash).
|
||||||
|
Limit(linesToRead).
|
||||||
|
Scan(&messages).
|
||||||
|
Order("line ASC")
|
||||||
|
|
||||||
|
// set the new messages
|
||||||
|
copy(client.Channels[client.ActiveChannelIndex].ScrollBackBuf, messages)
|
||||||
|
// adjust the scrollback buf first line
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBufFirstLine = 1
|
||||||
|
|
||||||
|
return func() tea.Msg {
|
||||||
|
return ReadHistoryFromDBMsg{
|
||||||
|
LinesRead: 0,
|
||||||
|
Direction: "top",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "up":
|
||||||
|
limit := linesToRead
|
||||||
|
linesToGet := 0
|
||||||
|
|
||||||
|
if linesToRead > int(scrollBackBufFirstLine) {
|
||||||
|
limit = int(scrollBackBufFirstLine) - 1
|
||||||
|
linesToGet = int(scrollBackBufFirstLine) - limit
|
||||||
|
} else {
|
||||||
|
linesToGet = int(scrollBackBufFirstLine) - linesToRead
|
||||||
|
}
|
||||||
|
|
||||||
|
client.DB.
|
||||||
|
Table("histories").
|
||||||
|
Select("message").
|
||||||
|
Where("hash = ? AND line >= ?", hash, linesToGet).
|
||||||
|
Limit(limit).
|
||||||
|
Scan(&messages).
|
||||||
|
Order("line ASC")
|
||||||
|
|
||||||
|
if len(messages) != 0 {
|
||||||
|
// prepend to the scroll back buf
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBuf = append(messages, client.Channels[client.ActiveChannelIndex].ScrollBackBuf...)
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBuf = client.Channels[client.ActiveChannelIndex].ScrollBackBuf[:irc.SCROLLBACK_MAX]
|
||||||
|
// adjust the scrollback buf first line
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBufFirstLine -= uint64(limit)
|
||||||
|
|
||||||
|
return func() tea.Msg {
|
||||||
|
return ReadHistoryFromDBMsg{
|
||||||
|
LinesRead: uint64(limit),
|
||||||
|
Direction: "up",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "down":
|
||||||
|
client.DB.
|
||||||
|
Table("histories").
|
||||||
|
Select("message").
|
||||||
|
Where("hash = ? AND line >= ?", hash, client.Channels[client.ActiveChannelIndex].ScrollBackBufFirstLine+irc.SCROLLBACK_MAX).
|
||||||
|
Limit(linesToRead).
|
||||||
|
Scan(&messages).
|
||||||
|
Order("line ASC")
|
||||||
|
linesGot := len(messages)
|
||||||
|
if len(messages) != 0 {
|
||||||
|
extraMessagesLen := 0
|
||||||
|
// append to the scroll back buf
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBuf = append(client.Channels[client.ActiveChannelIndex].ScrollBackBuf, messages...)
|
||||||
|
// if we reached the end of the messages in the db. try appending the messages in the ToInsert buffer
|
||||||
|
if linesGot < linesToRead {
|
||||||
|
for _, history := range client.Channels[client.ActiveChannelIndex].ToInsert {
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBuf = append(client.Channels[client.ActiveChannelIndex].ScrollBackBuf, history.Message)
|
||||||
|
}
|
||||||
|
extraMessagesLen = len(client.Channels[client.ActiveChannelIndex].ToInsert)
|
||||||
|
}
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBuf = client.Channels[client.ActiveChannelIndex].ScrollBackBuf[len(client.Channels[client.ActiveChannelIndex].ScrollBackBuf)-irc.SCROLLBACK_MAX:]
|
||||||
|
// adjust the scrollback buf first line
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBufFirstLine += uint64(linesGot) + uint64(extraMessagesLen)
|
||||||
|
|
||||||
|
return func() tea.Msg {
|
||||||
|
return ReadHistoryFromDBMsg{
|
||||||
|
LinesRead: uint64(linesGot) + uint64(extraMessagesLen),
|
||||||
|
Direction: "down",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "bottom":
|
||||||
|
client.DB.Raw("SELECT t.message FROM (SELECT line, message FROM histories WHERE hash = ? ORDER BY line DESC LIMIT ?) t ORDER BY t.line ASC;", hash, linesToRead).
|
||||||
|
Scan(&messages)
|
||||||
|
|
||||||
|
toInsert := make([]string, 0)
|
||||||
|
|
||||||
|
for _, history := range client.Channels[client.ActiveChannelIndex].ToInsert {
|
||||||
|
toInsert = append(toInsert, history.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the new messages
|
||||||
|
copy(client.Channels[client.ActiveChannelIndex].ScrollBackBuf, messages)
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBuf = append(client.Channels[client.ActiveChannelIndex].ScrollBackBuf, toInsert...)
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBuf = client.Channels[client.ActiveChannelIndex].ScrollBackBuf[len(toInsert):]
|
||||||
|
// adjust the scrollback buf first line
|
||||||
|
client.Channels[client.ActiveChannelIndex].ScrollBackBufFirstLine = client.Channels[client.ActiveChannelIndex].TotalLines - irc.SCROLLBACK_MAX + uint64(len(toInsert))
|
||||||
|
|
||||||
|
return func() tea.Msg {
|
||||||
|
return ReadHistoryFromDBMsg{
|
||||||
|
LinesRead: 0,
|
||||||
|
Direction: "bottom",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return func() tea.Msg {
|
||||||
|
return ReadHistoryFromDBMsg{
|
||||||
|
LinesRead: 0,
|
||||||
|
Direction: "unknown",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/driver/sqlite"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type History struct {
|
||||||
|
Hash string `gorm:"index"`
|
||||||
|
Line uint64 `gorm:"index" gorm:"unique"`
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConnectToDB() (*gorm.DB, error) {
|
||||||
|
db, err := gorm.Open(sqlite.Open("gorc.db"), &gorm.Config{
|
||||||
|
Logger: logger.Default.LogMode(logger.Silent),
|
||||||
|
AllowGlobalUpdate: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
db.AutoMigrate(&History{})
|
||||||
|
db.Delete(&History{})
|
||||||
|
|
||||||
|
return db, err
|
||||||
|
}
|
||||||
@@ -10,7 +10,10 @@ require (
|
|||||||
github.com/charmbracelet/lipgloss v0.4.0
|
github.com/charmbracelet/lipgloss v0.4.0
|
||||||
github.com/containerd/console v1.0.3 // indirect
|
github.com/containerd/console v1.0.3 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.13 // indirect
|
||||||
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
|
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
|
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||||
|
gorm.io/driver/sqlite v1.3.4
|
||||||
|
gorm.io/gorm v1.23.6 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ github.com/charmbracelet/lipgloss v0.4.0/go.mod h1:vmdkHvce7UzX6xkyf4cca8WlwdQ5R
|
|||||||
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
||||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
|
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
@@ -18,6 +25,10 @@ github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRC
|
|||||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
||||||
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 h1:kMlmsLSbjkikxQJ1IPwaM+7LJ9ltFu/fi8CRzvSnQmA=
|
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 h1:kMlmsLSbjkikxQJ1IPwaM+7LJ9ltFu/fi8CRzvSnQmA=
|
||||||
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
||||||
@@ -27,10 +38,13 @@ github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKt
|
|||||||
github.com/muesli/termenv v0.9.0 h1:wnbOaGz+LUR3jNT0zOzinPnyDaCZUQRZj9GxK8eRVl8=
|
github.com/muesli/termenv v0.9.0 h1:wnbOaGz+LUR3jNT0zOzinPnyDaCZUQRZj9GxK8eRVl8=
|
||||||
github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw=
|
github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -42,3 +56,11 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gorm.io/driver/sqlite v1.3.4 h1:NnFOPVfzi4CPsJPH4wXr6rMkPb4ElHEqKMvrsx9c9Fk=
|
||||||
|
gorm.io/driver/sqlite v1.3.4/go.mod h1:B+8GyC9K7VgzJAcrcXMRPdnMcck+8FgJynEehEPM16U=
|
||||||
|
gorm.io/gorm v1.23.4 h1:1BKWM67O6CflSLcwGQR7ccfmC4ebOxQrTfOQGRE9wjg=
|
||||||
|
gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||||
|
gorm.io/gorm v1.23.6 h1:KFLdNgri4ExFFGTRGGFWON2P1ZN28+9SJRN8voOoYe0=
|
||||||
|
gorm.io/gorm v1.23.6/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||||
|
|||||||
+62
-6
@@ -26,8 +26,10 @@ import (
|
|||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
"github.com/illusionman1212/gorc/db"
|
||||||
"github.com/illusionman1212/gorc/irc/commands"
|
"github.com/illusionman1212/gorc/irc/commands"
|
||||||
"github.com/illusionman1212/gorc/ui"
|
"github.com/illusionman1212/gorc/ui"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
@@ -42,8 +44,26 @@ type Channel struct {
|
|||||||
// Channel topic
|
// Channel topic
|
||||||
Topic string
|
Topic string
|
||||||
|
|
||||||
// Channel messages history
|
// Scrollback buffer for the channel message history
|
||||||
History string
|
ScrollBackBuf []string
|
||||||
|
|
||||||
|
// Whethere the viewport is at the bottom or not
|
||||||
|
AtBottom bool
|
||||||
|
|
||||||
|
// Total amount of lines that have been received from the tcp conn
|
||||||
|
// and written to the history db
|
||||||
|
TotalLines uint64
|
||||||
|
|
||||||
|
// Buffer of messages that need to be inserted into the db
|
||||||
|
ToInsert []db.History
|
||||||
|
|
||||||
|
// Position/Index of first line in the scrollback buffer as mapped
|
||||||
|
// to TotalLines.
|
||||||
|
// Last line is ScrollBackBufFirstLine + SCROLLBACK_MAX - 1
|
||||||
|
ScrollBackBufFirstLine uint64
|
||||||
|
|
||||||
|
// Unique sha1 hash for the channel made from server hostname and channel name
|
||||||
|
Hash string
|
||||||
|
|
||||||
// Users in this channel
|
// Users in this channel
|
||||||
// The map key is the user's nickname
|
// The map key is the user's nickname
|
||||||
@@ -77,6 +97,12 @@ type Client struct {
|
|||||||
// Reference to the bubbletea program
|
// Reference to the bubbletea program
|
||||||
Tea *tea.Program
|
Tea *tea.Program
|
||||||
|
|
||||||
|
// TODO: remove this
|
||||||
|
Ticks int
|
||||||
|
|
||||||
|
// DB reference
|
||||||
|
DB *gorm.DB
|
||||||
|
|
||||||
// Index of the first visible tab in the tab bar
|
// Index of the first visible tab in the tab bar
|
||||||
FirstTabIndexInTabBar int
|
FirstTabIndexInTabBar int
|
||||||
|
|
||||||
@@ -96,9 +122,12 @@ var serverMsgStyle = lipgloss.NewStyle().Foreground(ui.ServerMsgColor)
|
|||||||
var timestampStyle = serverMsgStyle.Copy()
|
var timestampStyle = serverMsgStyle.Copy()
|
||||||
var dateStyle = lipgloss.NewStyle().Foreground(ui.DateColor)
|
var dateStyle = lipgloss.NewStyle().Foreground(ui.DateColor)
|
||||||
|
|
||||||
const CRLF = "\r\n"
|
const (
|
||||||
|
CRLF = "\r\n"
|
||||||
|
SCROLLBACK_MAX = 400
|
||||||
|
)
|
||||||
|
|
||||||
func (c *Channel) AppendMsg(timestamp string, fullMsg string, opts MsgFmtOpts) {
|
func (c *Channel) AppendMsg(host string, database *gorm.DB, timestamp string, fullMsg string, opts MsgFmtOpts) {
|
||||||
prefixes := ""
|
prefixes := ""
|
||||||
style := ui.DefaultStyle
|
style := ui.DefaultStyle
|
||||||
|
|
||||||
@@ -119,7 +148,32 @@ func (c *Channel) AppendMsg(timestamp string, fullMsg string, opts MsgFmtOpts) {
|
|||||||
style = dateStyle
|
style = dateStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
c.History += prefixes + style.Render(fullMsg) + CRLF
|
finalMsg := prefixes + style.Render(fullMsg)
|
||||||
|
|
||||||
|
c.TotalLines++
|
||||||
|
|
||||||
|
history := db.History{Hash: c.Hash, Line: c.TotalLines, Message: finalMsg}
|
||||||
|
c.ToInsert = append(c.ToInsert, history)
|
||||||
|
|
||||||
|
if c.TotalLines%10 == 0 {
|
||||||
|
database.Create(c.ToInsert)
|
||||||
|
c.ToInsert = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.ScrollBackBuf) < SCROLLBACK_MAX {
|
||||||
|
c.ScrollBackBuf = append(c.ScrollBackBuf, prefixes+style.Render(fullMsg))
|
||||||
|
// We haven't reached the bottom yet so the first line is still 1
|
||||||
|
c.ScrollBackBufFirstLine = 1
|
||||||
|
} else if c.AtBottom && len(c.ScrollBackBuf) >= SCROLLBACK_MAX {
|
||||||
|
// TODO: when pressing 'g' in viewport, we need to set this to 1
|
||||||
|
// TODO: when pressing 'G' in viewport, we need to set this to TotalLines - 1000 + 1
|
||||||
|
// TODO: when going up in viewport, we need to decrement the amount of lines by how many lines we need to prepend to the scrollbackbuf
|
||||||
|
// TODO: when going down in viewport, we need to increment the amount of lines by how many lines we need to append to the scrollbackbuf
|
||||||
|
// If we're at bottom and we're appending a line, then we increment the first line
|
||||||
|
c.ScrollBackBufFirstLine++
|
||||||
|
c.ScrollBackBuf = append(c.ScrollBackBuf, prefixes+style.Render(fullMsg))
|
||||||
|
c.ScrollBackBuf = c.ScrollBackBuf[1:]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Client) Initialize(host string, port string, tlsEnabled bool) {
|
func (s *Client) Initialize(host string, port string, tlsEnabled bool) {
|
||||||
@@ -138,6 +192,7 @@ func (s *Client) Initialize(host string, port string, tlsEnabled bool) {
|
|||||||
s.Port = port
|
s.Port = port
|
||||||
s.ActiveChannel = host
|
s.ActiveChannel = host
|
||||||
s.Channels = make([]Channel, 0)
|
s.Channels = make([]Channel, 0)
|
||||||
|
s.Ticks = 1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +211,7 @@ func (s *Client) Initialize(host string, port string, tlsEnabled bool) {
|
|||||||
s.Port = port
|
s.Port = port
|
||||||
s.ActiveChannel = host
|
s.ActiveChannel = host
|
||||||
s.Channels = make([]Channel, 0)
|
s.Channels = make([]Channel, 0)
|
||||||
|
s.Ticks = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Register(nick string, password string, channel string) {
|
func (c *Client) Register(nick string, password string, channel string) {
|
||||||
@@ -188,7 +244,7 @@ func (c *Client) SetDay() {
|
|||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
msg := fmt.Sprintf("————— %s %d —————", now.Month().String(), now.Day())
|
msg := fmt.Sprintf("————— %s %d —————", now.Month().String(), now.Day())
|
||||||
c.Channels[0].AppendMsg("", msg, msgOpts)
|
c.Channels[0].AppendMsg(c.Host, c.DB, "", msg, msgOpts)
|
||||||
|
|
||||||
// TODO: append new day to each channel whenever the day changes
|
// TODO: append new day to each channel whenever the day changes
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-31
@@ -18,6 +18,7 @@ package handler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"crypto/sha1"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
@@ -69,7 +70,7 @@ func handlePrivMsg(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
|
|
||||||
for i, c := range client.Channels {
|
for i, c := range client.Channels {
|
||||||
if c.Name == channel {
|
if c.Name == channel {
|
||||||
client.Channels[i].AppendMsg(msg.Timestamp, privMsg, msgOpts)
|
client.Channels[i].AppendMsg(client.Host, client.DB, msg.Timestamp, privMsg, msgOpts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,13 +87,24 @@ func handleJoin(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if nick == client.Nickname {
|
if nick == client.Nickname {
|
||||||
|
for _, regChannel := range client.Channels {
|
||||||
|
if regChannel.Name == channel {
|
||||||
|
client.Tea.Send(cmds.SwitchChannels())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hash := sha1.New()
|
||||||
|
hash.Write([]byte(client.Host + " " + channel))
|
||||||
|
hashStr := fmt.Sprintf("%x", hash.Sum(nil))
|
||||||
|
|
||||||
client.Channels = append(client.Channels, irc.Channel{
|
client.Channels = append(client.Channels, irc.Channel{
|
||||||
Name: channel,
|
Name: channel,
|
||||||
Users: make(map[string]irc.User),
|
Users: make(map[string]irc.User),
|
||||||
|
Hash: hashStr,
|
||||||
})
|
})
|
||||||
client.ActiveChannelIndex = len(client.Channels) - 1
|
client.ActiveChannelIndex = len(client.Channels) - 1
|
||||||
client.ActiveChannel = channel
|
client.ActiveChannel = channel
|
||||||
client.Channels[client.ActiveChannelIndex].AppendMsg(msg.Timestamp, joinMsg, msgOpts)
|
client.Channels[client.ActiveChannelIndex].AppendMsg(client.Host, client.DB, msg.Timestamp, joinMsg, msgOpts)
|
||||||
if _, exists := client.Channels[client.ActiveChannelIndex].Users[nick]; !exists {
|
if _, exists := client.Channels[client.ActiveChannelIndex].Users[nick]; !exists {
|
||||||
client.Channels[client.ActiveChannelIndex].Users[nick] = irc.User{}
|
client.Channels[client.ActiveChannelIndex].Users[nick] = irc.User{}
|
||||||
}
|
}
|
||||||
@@ -100,7 +112,7 @@ func handleJoin(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
} else {
|
} else {
|
||||||
for i, c := range client.Channels {
|
for i, c := range client.Channels {
|
||||||
if c.Name == channel {
|
if c.Name == channel {
|
||||||
client.Channels[i].AppendMsg(msg.Timestamp, joinMsg, msgOpts)
|
client.Channels[i].AppendMsg(client.Host, client.DB, msg.Timestamp, joinMsg, msgOpts)
|
||||||
if _, exists := client.Channels[i].Users[nick]; !exists {
|
if _, exists := client.Channels[i].Users[nick]; !exists {
|
||||||
client.Channels[i].Users[nick] = irc.User{}
|
client.Channels[i].Users[nick] = irc.User{}
|
||||||
}
|
}
|
||||||
@@ -128,7 +140,7 @@ func handleQuit(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
if i == 0 {
|
if i == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
client.Channels[i].AppendMsg(msg.Timestamp, quitMsg, msgOpts)
|
client.Channels[i].AppendMsg(client.Host, client.DB, msg.Timestamp, quitMsg, msgOpts)
|
||||||
delete(client.Channels[i].Users, nick)
|
delete(client.Channels[i].Users, nick)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +172,7 @@ func handlePart(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
}
|
}
|
||||||
client.LastTabIndexInTabBar--
|
client.LastTabIndexInTabBar--
|
||||||
} else {
|
} else {
|
||||||
client.Channels[i].AppendMsg(msg.Timestamp, partMsg, msgOpts)
|
client.Channels[i].AppendMsg(client.Host, client.DB, msg.Timestamp, partMsg, msgOpts)
|
||||||
delete(client.Channels[i].Users, nick)
|
delete(client.Channels[i].Users, nick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,7 +192,7 @@ func handleWELCOME(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
|
|
||||||
// set server-registered nickname
|
// set server-registered nickname
|
||||||
client.Nickname = nick
|
client.Nickname = nick
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, welcomeMsg, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, welcomeMsg, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleYOURHOST(msg parser.IRCMessage, client *irc.Client) {
|
func handleYOURHOST(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -191,7 +203,7 @@ func handleYOURHOST(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, host, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, host, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleCREATED(msg parser.IRCMessage, client *irc.Client) {
|
func handleCREATED(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -202,7 +214,7 @@ func handleCREATED(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, created, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, created, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMYINFO(msg parser.IRCMessage, client *irc.Client) {
|
func handleMYINFO(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -213,7 +225,7 @@ func handleMYINFO(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, info, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, info, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLUSERCLIENT(msg parser.IRCMessage, client *irc.Client) {
|
func handleLUSERCLIENT(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -224,7 +236,7 @@ func handleLUSERCLIENT(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLUSEROP(msg parser.IRCMessage, client *irc.Client) {
|
func handleLUSEROP(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -235,7 +247,7 @@ func handleLUSEROP(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLUSERUNKNOWN(msg parser.IRCMessage, client *irc.Client) {
|
func handleLUSERUNKNOWN(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -246,7 +258,7 @@ func handleLUSERUNKNOWN(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLUSERCHANNELS(msg parser.IRCMessage, client *irc.Client) {
|
func handleLUSERCHANNELS(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -257,7 +269,7 @@ func handleLUSERCHANNELS(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLUSERME(msg parser.IRCMessage, client *irc.Client) {
|
func handleLUSERME(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -268,7 +280,7 @@ func handleLUSERME(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLOCALUSERS(msg parser.IRCMessage, client *irc.Client) {
|
func handleLOCALUSERS(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -279,7 +291,7 @@ func handleLOCALUSERS(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleGLOBALUSERS(msg parser.IRCMessage, client *irc.Client) {
|
func handleGLOBALUSERS(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -290,7 +302,7 @@ func handleGLOBALUSERS(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleWHOISUSER(msg parser.IRCMessage, client *irc.Client) {
|
func handleWHOISUSER(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -312,8 +324,8 @@ func handleWHOISUSER(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
realName,
|
realName,
|
||||||
)
|
)
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, "WHOIS Information", msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, "WHOIS Information", msgOpts)
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleWHOISSERVER(msg parser.IRCMessage, client *irc.Client) {
|
func handleWHOISSERVER(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -331,7 +343,7 @@ func handleWHOISSERVER(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
serverInfo,
|
serverInfo,
|
||||||
)
|
)
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleWHOISIDLE(msg parser.IRCMessage, client *irc.Client) {
|
func handleWHOISIDLE(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -355,7 +367,7 @@ func handleWHOISIDLE(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
idleSeconds,
|
idleSeconds,
|
||||||
since.Format(time.ANSIC),
|
since.Format(time.ANSIC),
|
||||||
)
|
)
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleENDOFWHOIS(msg parser.IRCMessage, client *irc.Client) {
|
func handleENDOFWHOIS(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -366,7 +378,7 @@ func handleENDOFWHOIS(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleWHOISCHANNELS(msg parser.IRCMessage, client *irc.Client) {
|
func handleWHOISCHANNELS(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -379,7 +391,7 @@ func handleWHOISCHANNELS(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
|
|
||||||
message := fmt.Sprintf("channels: %s", chans)
|
message := fmt.Sprintf("channels: %s", chans)
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleNAMREPLY(msg parser.IRCMessage, client *irc.Client) {
|
func handleNAMREPLY(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -420,7 +432,7 @@ func handleMOTDStart(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMOTD(msg parser.IRCMessage, client *irc.Client) {
|
func handleMOTD(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -431,7 +443,7 @@ func handleMOTD(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, messageLine, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, messageLine, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleWHOISHOST(msg parser.IRCMessage, client *irc.Client) {
|
func handleWHOISHOST(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -442,7 +454,7 @@ func handleWHOISHOST(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleWHOISMODES(msg parser.IRCMessage, client *irc.Client) {
|
func handleWHOISMODES(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -453,7 +465,7 @@ func handleWHOISMODES(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleNOSUCHSERVER(msg parser.IRCMessage, client *irc.Client) {
|
func handleNOSUCHSERVER(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -464,7 +476,7 @@ func handleNOSUCHSERVER(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleNONICKNAMEGIVEN(msg parser.IRCMessage, client *irc.Client) {
|
func handleNONICKNAMEGIVEN(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -475,7 +487,7 @@ func handleNONICKNAMEGIVEN(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleNEEDMOREPARAMS(msg parser.IRCMessage, client *irc.Client) {
|
func handleNEEDMOREPARAMS(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -486,7 +498,7 @@ func handleNEEDMOREPARAMS(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleALREADYREGISTERED(msg parser.IRCMessage, client *irc.Client) {
|
func handleALREADYREGISTERED(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -497,7 +509,7 @@ func handleALREADYREGISTERED(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
AsServerMsg: true,
|
AsServerMsg: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, message, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, message, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleCommand(msg parser.IRCMessage, client *irc.Client) {
|
func HandleCommand(msg parser.IRCMessage, client *irc.Client) {
|
||||||
@@ -589,7 +601,7 @@ func HandleCommand(msg parser.IRCMessage, client *irc.Client) {
|
|||||||
NotImpl: true,
|
NotImpl: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Channels[0].AppendMsg(msg.Timestamp, fullMsg, msgOpts)
|
client.Channels[0].AppendMsg(client.Host, client.DB, msg.Timestamp, fullMsg, msgOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// send a receivedIRCmsg tea message so the ui can update
|
// send a receivedIRCmsg tea message so the ui can update
|
||||||
|
|||||||
+6
-19
@@ -17,6 +17,7 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
@@ -25,24 +26,6 @@ import (
|
|||||||
"github.com/illusionman1212/gorc/irc/commands"
|
"github.com/illusionman1212/gorc/irc/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
func handleSlashJoin(params []string, client *irc.Client) tea.Cmd {
|
|
||||||
channel := ""
|
|
||||||
if len(params) > 0 {
|
|
||||||
channel = params[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, c := range client.Channels {
|
|
||||||
if c.Name == channel {
|
|
||||||
client.ActiveChannelIndex = i
|
|
||||||
client.ActiveChannel = channel
|
|
||||||
return cmds.SwitchChannels
|
|
||||||
}
|
|
||||||
}
|
|
||||||
client.SendCommand(commands.JOIN, params...)
|
|
||||||
|
|
||||||
return cmds.SwitchChannels
|
|
||||||
}
|
|
||||||
|
|
||||||
func HandleSlashCommand(msg string, client *irc.Client) tea.Cmd {
|
func HandleSlashCommand(msg string, client *irc.Client) tea.Cmd {
|
||||||
substrs := strings.Fields(msg[1:])
|
substrs := strings.Fields(msg[1:])
|
||||||
command := strings.ToUpper(substrs[0])
|
command := strings.ToUpper(substrs[0])
|
||||||
@@ -53,10 +36,14 @@ func HandleSlashCommand(msg string, client *irc.Client) tea.Cmd {
|
|||||||
|
|
||||||
switch command {
|
switch command {
|
||||||
case commands.JOIN:
|
case commands.JOIN:
|
||||||
return handleSlashJoin(params, client)
|
client.SendCommand(commands.JOIN, params...)
|
||||||
|
return cmds.SwitchChannels
|
||||||
case commands.QUIT:
|
case commands.QUIT:
|
||||||
client.SendCommand(command, params...)
|
client.SendCommand(command, params...)
|
||||||
return cmds.Quit(client)
|
return cmds.Quit(client)
|
||||||
|
case "TEST":
|
||||||
|
log.Println("running the spammer")
|
||||||
|
return cmds.Tick(client)
|
||||||
default:
|
default:
|
||||||
client.SendCommand(command, params...)
|
client.SendCommand(command, params...)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type Tags map[string]string
|
|||||||
func (m *IRCMessage) setTimestamp() {
|
func (m *IRCMessage) setTimestamp() {
|
||||||
// TODO: get timestamp from time tag
|
// TODO: get timestamp from time tag
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
m.Timestamp = fmt.Sprintf("[%02d:%02d]", now.Hour(), now.Minute())
|
m.Timestamp = fmt.Sprintf("[%02d:%02d:%02d.%03d]", now.Hour(), now.Minute(), now.Second(), now.Nanosecond()/1000000)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseTags(rawTags string) Tags {
|
func parseTags(rawTags string) Tags {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/illusionman1212/gorc/db"
|
||||||
"github.com/illusionman1212/gorc/ui/app"
|
"github.com/illusionman1212/gorc/ui/app"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,7 +33,13 @@ func main() {
|
|||||||
tea.WithMouseCellMotion(),
|
tea.WithMouseCellMotion(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
db, err := db.ConnectToDB()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
gorc.Client.Tea = p
|
gorc.Client.Tea = p
|
||||||
|
gorc.Client.DB = db
|
||||||
|
|
||||||
f, err := tea.LogToFile("gorc.log", "gorc")
|
f, err := tea.LogToFile("gorc.log", "gorc")
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ func NewMainScreen(client *irc.Client) State {
|
|||||||
newViewport := viewport.New(0, 0)
|
newViewport := viewport.New(0, 0)
|
||||||
newViewport.Wrap = viewport.Wrap
|
newViewport.Wrap = viewport.Wrap
|
||||||
newViewport.Style = MessagesStyle.Copy()
|
newViewport.Style = MessagesStyle.Copy()
|
||||||
|
newViewport.MouseWheelEnabled = false
|
||||||
|
|
||||||
return State{
|
return State{
|
||||||
Client: client,
|
Client: client,
|
||||||
@@ -77,9 +78,25 @@ func (s State) Update(msg tea.Msg) (State, tea.Cmd) {
|
|||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case cmds.ReceivedIRCMsgMsg:
|
case cmds.ReceivedIRCMsgMsg:
|
||||||
wasAtBottom := s.Viewport.AtBottom()
|
wasAtBottom := s.Viewport.AtBottom()
|
||||||
s.Viewport.SetContent(s.Client.Channels[s.Client.ActiveChannelIndex].History)
|
s.Viewport.SetContent(strings.Join(s.Client.Channels[s.Client.ActiveChannelIndex].ScrollBackBuf, "\n"))
|
||||||
|
|
||||||
if wasAtBottom {
|
if wasAtBottom {
|
||||||
|
s.Client.Channels[s.Client.ActiveChannelIndex].AtBottom = true
|
||||||
|
s.Viewport.GotoBottom()
|
||||||
|
} else {
|
||||||
|
s.Client.Channels[s.Client.ActiveChannelIndex].AtBottom = false
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
case cmds.ReadHistoryFromDBMsg:
|
||||||
|
s.Viewport.SetContent(strings.Join(s.Client.Channels[s.Client.ActiveChannelIndex].ScrollBackBuf, "\n"))
|
||||||
|
switch msg.Direction {
|
||||||
|
case "top":
|
||||||
|
s.Viewport.GotoTop()
|
||||||
|
case "up":
|
||||||
|
s.Viewport.SetYOffset(s.Viewport.YOffset + int(msg.LinesRead))
|
||||||
|
case "down":
|
||||||
|
s.Viewport.SetYOffset(s.Viewport.YOffset - int(msg.LinesRead))
|
||||||
|
case "bottom":
|
||||||
s.Viewport.GotoBottom()
|
s.Viewport.GotoBottom()
|
||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
@@ -94,17 +111,17 @@ func (s State) Update(msg tea.Msg) (State, tea.Cmd) {
|
|||||||
WithTimestamp: true,
|
WithTimestamp: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Client.Channels[s.Client.ActiveChannelIndex].AppendMsg(msg.Timestamp, fullMsg, msgOpts)
|
s.Client.Channels[s.Client.ActiveChannelIndex].AppendMsg(s.Client.Host, s.Client.DB, msg.Timestamp, fullMsg, msgOpts)
|
||||||
// TODO: make sure to only append the message to the history if server sends back no errors
|
// TODO: make sure to only append the message to the history if server sends back no errors
|
||||||
s.Client.SendCommand(commands.PRIVMSG, s.Client.ActiveChannel, msg.Msg)
|
s.Client.SendCommand(commands.PRIVMSG, s.Client.ActiveChannel, msg.Msg)
|
||||||
s.Viewport.SetContent(s.Client.Channels[s.Client.ActiveChannelIndex].History)
|
s.Viewport.SetContent(strings.Join(s.Client.Channels[s.Client.ActiveChannelIndex].ScrollBackBuf, "\n"))
|
||||||
s.Viewport.GotoBottom()
|
s.Viewport.GotoBottom()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
case cmds.SwitchChannelsMsg:
|
case cmds.SwitchChannelsMsg:
|
||||||
s.Viewport.SetContent(s.Client.Channels[s.Client.ActiveChannelIndex].History)
|
s.Viewport.SetContent(strings.Join(s.Client.Channels[s.Client.ActiveChannelIndex].ScrollBackBuf, "\n"))
|
||||||
s.Viewport.GotoBottom()
|
s.Viewport.GotoBottom()
|
||||||
|
|
||||||
*s.SidePanel, cmd = s.SidePanel.Update(msg)
|
*s.SidePanel, cmd = s.SidePanel.Update(msg)
|
||||||
@@ -113,6 +130,9 @@ func (s State) Update(msg tea.Msg) (State, tea.Cmd) {
|
|||||||
s.Client.LastTabIndexInTabBar = len(s.Client.Channels) - 1
|
s.Client.LastTabIndexInTabBar = len(s.Client.Channels) - 1
|
||||||
s.TabRenderingDirection = Left
|
s.TabRenderingDirection = Left
|
||||||
return s, nil
|
return s, nil
|
||||||
|
case cmds.TickMsg:
|
||||||
|
s.Client.Ticks++
|
||||||
|
return s, cmds.Tick(s.Client)
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
key := msg.String()
|
key := msg.String()
|
||||||
switch key {
|
switch key {
|
||||||
@@ -180,11 +200,37 @@ func (s State) Update(msg tea.Msg) (State, tea.Cmd) {
|
|||||||
return s, cmds.SwitchChannels
|
return s, cmds.SwitchChannels
|
||||||
case "g":
|
case "g":
|
||||||
if s.FocusIndex == Viewport {
|
if s.FocusIndex == Viewport {
|
||||||
s.Viewport.GotoTop()
|
s.Client.Channels[s.Client.ActiveChannelIndex].AtBottom = false
|
||||||
|
if !s.Viewport.AtTop() {
|
||||||
|
cmdsToProcess = append(cmdsToProcess, cmds.ReadHistoryFromDB(s.Client, irc.SCROLLBACK_MAX, "top"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case "G":
|
case "G":
|
||||||
if s.FocusIndex == Viewport {
|
if s.FocusIndex == Viewport {
|
||||||
s.Viewport.GotoBottom()
|
if !s.Viewport.AtBottom() {
|
||||||
|
cmdsToProcess = append(cmdsToProcess, cmds.ReadHistoryFromDB(s.Client, irc.SCROLLBACK_MAX, "bottom"))
|
||||||
|
}
|
||||||
|
s.Client.Channels[s.Client.ActiveChannelIndex].AtBottom = true
|
||||||
|
}
|
||||||
|
case "j", "k", "d", "u", "f", "b", "up", "down":
|
||||||
|
// TODO: what???
|
||||||
|
// if s.Viewport.AtBottom() {
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
|
||||||
|
if key == "j" || key == "d" || key == "f" || key == "down" {
|
||||||
|
if s.Viewport.ScrollPercent() > 0.5 {
|
||||||
|
excess := s.Viewport.ScrollPercent() - 0.5 + 0.1
|
||||||
|
linesToRead := int(math.Floor(excess * float64(irc.SCROLLBACK_MAX)))
|
||||||
|
cmdsToProcess = append(cmdsToProcess, cmds.ReadHistoryFromDB(s.Client, linesToRead, "down"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.Client.Channels[s.Client.ActiveChannelIndex].AtBottom = false
|
||||||
|
if s.Viewport.ScrollPercent() < 0.5 && s.Viewport.ScrollPercent() > 0.0 {
|
||||||
|
excess := 0.5 - s.Viewport.ScrollPercent() + 0.1
|
||||||
|
linesToRead := int(math.Floor(excess * float64(irc.SCROLLBACK_MAX)))
|
||||||
|
cmdsToProcess = append(cmdsToProcess, cmds.ReadHistoryFromDB(s.Client, linesToRead, "up"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,7 +290,7 @@ func (s *State) SetSize(width, height int) {
|
|||||||
// we need this to render an empty viewport
|
// we need this to render an empty viewport
|
||||||
history := ""
|
history := ""
|
||||||
if len(s.Client.Channels) != 0 {
|
if len(s.Client.Channels) != 0 {
|
||||||
history = s.Client.Channels[s.Client.ActiveChannelIndex].History
|
history = strings.Join(s.Client.Channels[s.Client.ActiveChannelIndex].ScrollBackBuf, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to re-set the content because words wrap differently on different sizes
|
// we need to re-set the content because words wrap differently on different sizes
|
||||||
|
|||||||
Reference in New Issue
Block a user