2021-11-14 06:31:51 +02:00
// gorc project
2022-01-24 04:23:02 +02:00
// Copyright (C) 2022 IllusionMan1212
2021-11-14 06:31:51 +02:00
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see https://www.gnu.org/licenses.
2022-01-24 04:23:02 +02:00
package cmds
2021-11-14 06:19:46 +02:00
import (
2022-02-19 16:24:39 +02:00
"fmt"
"time"
2021-11-14 06:19:46 +02:00
tea "github.com/charmbracelet/bubbletea"
2022-01-24 04:23:02 +02:00
"github.com/illusionman1212/gorc/irc"
2023-02-19 00:58:42 +02:00
"github.com/illusionman1212/gorc/irc/commands"
2021-11-14 06:19:46 +02:00
)
2022-01-24 04:23:02 +02:00
type ConnectMsg struct {}
func Connect () tea . Msg {
return ConnectMsg {}
}
func Quit ( client * irc . Client ) tea . Cmd {
return func () tea . Msg {
if client . TcpConn != nil {
client . SendCommand ( "QUIT" )
}
return tea . Quit ()
}
}
2023-02-19 00:58:42 +02:00
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 {}
})
}
2022-01-24 04:23:02 +02:00
type SendPrivMsgMsg struct {
2022-02-19 16:24:39 +02:00
Msg string
Timestamp string
2022-01-05 00:54:54 +02:00
}
2022-01-24 04:23:02 +02:00
func SendPrivMsg ( msg string ) tea . Cmd {
2022-01-05 00:54:54 +02:00
return func () tea . Msg {
2022-02-19 16:24:39 +02:00
now := time . Now ()
timestamp := fmt . Sprintf ( "[%02d:%02d]" , now . Hour (), now . Minute ())
return SendPrivMsgMsg {
Msg : msg ,
Timestamp : timestamp ,
}
2022-01-05 00:54:54 +02:00
}
}
2022-01-15 21:56:06 +02:00
type ReceivedIRCMsgMsg struct {}
func ReceivedIRCMsg () tea . Msg {
return ReceivedIRCMsgMsg {}
}
type SwitchChannelsMsg struct {}
func SwitchChannels () tea . Msg {
return SwitchChannelsMsg {}
}
2022-01-24 04:23:02 +02:00
type UpdateTabBarMsg struct {}
func UpdateTabBar () tea . Msg {
return UpdateTabBarMsg {}
}
2023-02-19 00:58:42 +02:00
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" ,
}
}
}