mirror of
https://github.com/Rudi9719/kbtui.git
synced 2026-03-22 11:07:22 +00:00
Merge kbtui/dev into kbtui/awesome-gocui for support
This commit is contained in:
22
README.md
22
README.md
@ -16,27 +16,31 @@ For support or suggestions check out the [kbtui team](https://keybase.io/team/kb
|
||||
* Reactions to messages
|
||||
* Auto #general teams when not given a channel
|
||||
* Pretty format headers in List view from window size
|
||||
|
||||
## Todo
|
||||
* Message editing
|
||||
* Twitter-style feed reading public messages
|
||||
|
||||
## Todo
|
||||
* Track multiple conversations at once
|
||||
* Message replies
|
||||
|
||||
|
||||
### Building and Running
|
||||
Easiest Way:
|
||||
```
|
||||
go get -u github.com/rudi9719/kbtui
|
||||
```
|
||||
|
||||
Or you can do the following:
|
||||
```
|
||||
go get ./
|
||||
go build
|
||||
go run build.go
|
||||
go run build.go {build, buildBeta... etc}
|
||||
./kbtui
|
||||
```
|
||||
Or
|
||||
```
|
||||
go get ./
|
||||
go run *.go
|
||||
```
|
||||
|
||||
You may see an error with `go get ./` about PATHs, that may be safely ignored.
|
||||
|
||||
If you see an error about a missing dependancy during a build, you'll want to resolve that.
|
||||
|
||||
|
||||
Occasionally when @dxb updates his API it will be necessary to run
|
||||
`go get -u ./`
|
||||
|
||||
24
cmdEdit.go
24
cmdEdit.go
@ -6,8 +6,6 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -37,24 +35,10 @@ func cmdEdit(cmd []string) {
|
||||
return
|
||||
}
|
||||
editString := origMessage.Result.Messages[0].Msg.Content.Text.Body
|
||||
g.Update(func(g *gocui.Gui) error {
|
||||
inputView, err := g.View("Input")
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
editString = fmt.Sprintf("/edit %d %s", messageId, editString)
|
||||
fmt.Fprintf(inputView, editString)
|
||||
viewX, viewY := inputView.Size()
|
||||
if len(editString) < viewX {
|
||||
viewX = len(editString)
|
||||
viewY = 0
|
||||
} else {
|
||||
viewX = viewX / len(editString)
|
||||
}
|
||||
inputView.MoveCursor(viewX, viewY, true)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
clearView("Edit")
|
||||
popupView("Edit")
|
||||
printToView("Edit", fmt.Sprintf("/e %d %s", messageId, editString))
|
||||
viewTitle("Edit", fmt.Sprintf(" Editing message %d ", messageId))
|
||||
return
|
||||
}
|
||||
if len(cmd) < 3 {
|
||||
|
||||
@ -27,6 +27,7 @@ func cmdJoin(cmd []string) {
|
||||
channel.TopicName = cmd[2]
|
||||
printToView("Feed", fmt.Sprintf("You are joining: @%s#%s", channel.Name, channel.TopicName))
|
||||
clearView("Chat")
|
||||
viewTitle("Input", fmt.Sprintf(" @%s#%s ", channel.Name, channel.TopicName))
|
||||
go populateChat()
|
||||
} else if len(cmd) == 2 {
|
||||
channel.MembersType = keybase.USER
|
||||
@ -34,6 +35,7 @@ func cmdJoin(cmd []string) {
|
||||
channel.TopicName = ""
|
||||
printToView("Feed", fmt.Sprintf("You are joining: @%s", channel.Name))
|
||||
clearView("Chat")
|
||||
viewTitle("Input", fmt.Sprintf(" @%s ", channel.Name))
|
||||
go populateChat()
|
||||
} else {
|
||||
printToView("Feed", fmt.Sprintf("To join a team use %sjoin <team> <channel>", cmdPrefix))
|
||||
|
||||
@ -17,5 +17,6 @@ func cmdStream(cmd []string) {
|
||||
stream = true
|
||||
channel.Name = ""
|
||||
printToView("Feed", "You are now viewing the formatted stream")
|
||||
viewTitle("Input", " Not in a chat /j to join ")
|
||||
clearView("Chat")
|
||||
}
|
||||
|
||||
1
mage.go
1
mage.go
@ -35,6 +35,7 @@ func BuildAllCommands() {
|
||||
func BuildAllCommandsT() {
|
||||
sh.Run("go", "build", "-tags", "type_commands,allcommands")
|
||||
}
|
||||
|
||||
// Build kbtui with beta functionality
|
||||
func BuildBeta() {
|
||||
sh.Run("go", "build", "-tags", "allcommands,showreactionscmd")
|
||||
|
||||
78
main.go
78
main.go
@ -24,27 +24,19 @@ var lastMessage keybase.ChatAPI
|
||||
var g *gocui.Gui
|
||||
|
||||
func main() {
|
||||
fmt.Println("Checking login")
|
||||
if !k.LoggedIn {
|
||||
fmt.Println("You are not logged in.")
|
||||
return
|
||||
}
|
||||
fmt.Println("Creating err")
|
||||
var err error
|
||||
fmt.Println("creating kbtui")
|
||||
g, err = gocui.NewGui(gocui.OutputNormal, false)
|
||||
if err != nil {
|
||||
fmt.Println("Err wasn't nil")
|
||||
fmt.Printf("%+v", err)
|
||||
}
|
||||
fmt.Println("defer g.Close()")
|
||||
defer g.Close()
|
||||
fmt.Println("SetManagerFunc")
|
||||
g.SetManagerFunc(layout)
|
||||
fmt.Println("Population")
|
||||
go populateList()
|
||||
go updateChatWindow()
|
||||
fmt.Println("Args")
|
||||
if len(os.Args) > 1 {
|
||||
os.Args[0] = "join"
|
||||
RunCommand(os.Args...)
|
||||
@ -54,11 +46,44 @@ func main() {
|
||||
if err := initKeybindings(); err != nil {
|
||||
fmt.Printf("%+v", err)
|
||||
}
|
||||
fmt.Println("Mainloop start")
|
||||
if err := g.MainLoop(); err != nil && !gocui.IsQuit(err) {
|
||||
fmt.Printf("%+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func viewTitle(viewName string, title string) {
|
||||
g.Update(func(g *gocui.Gui) error {
|
||||
updatingView, err := g.View(viewName)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
updatingView.Title = title
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
func popupView(viewName string) {
|
||||
_, err := g.SetCurrentView(viewName)
|
||||
if err != nil {
|
||||
printToView("Feed", fmt.Sprintf("%+v", err))
|
||||
}
|
||||
_, err = g.SetViewOnTop(viewName)
|
||||
if err != nil {
|
||||
printToView("Feed", fmt.Sprintf("%+v", err))
|
||||
}
|
||||
g.Update(func(g *gocui.Gui) error {
|
||||
updatingView, err := g.View(viewName)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
viewX, viewY := updatingView.Size()
|
||||
updatingView.MoveCursor(viewX, viewY, true)
|
||||
}
|
||||
return nil
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func populateChat() {
|
||||
lastMessage.ID = 0
|
||||
chat := k.NewChat(channel)
|
||||
@ -206,12 +231,21 @@ func printToView(viewName string, message string) {
|
||||
|
||||
func layout(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
if editView, err := g.SetView("Edit", maxX/2-maxX/3+1, maxY/2, maxX-2, maxY/2+10, 0); err != nil {
|
||||
if !gocui.IsUnknownView(err) {
|
||||
return err
|
||||
}
|
||||
editView.Editable = true
|
||||
editView.Wrap = true
|
||||
fmt.Fprintln(editView, "Edit window. Should disappear")
|
||||
}
|
||||
if feedView, err := g.SetView("Feed", maxX/2-maxX/3, 0, maxX-1, maxY/5, 0); err != nil {
|
||||
if !gocui.IsUnknownView(err) {
|
||||
return err
|
||||
}
|
||||
feedView.Autoscroll = true
|
||||
feedView.Wrap = true
|
||||
feedView.Title = "Feed Window"
|
||||
fmt.Fprintln(feedView, "Feed Window - If you are mentioned or receive a PM it will show here")
|
||||
}
|
||||
if chatView, err2 := g.SetView("Chat", maxX/2-maxX/3, maxY/5+1, maxX-1, maxY-5, 0); err2 != nil {
|
||||
@ -232,12 +266,14 @@ func layout(g *gocui.Gui) error {
|
||||
}
|
||||
inputView.Editable = true
|
||||
inputView.Wrap = true
|
||||
inputView.Title = " Not in a chat /j to join"
|
||||
g.Cursor = true
|
||||
}
|
||||
if listView, err4 := g.SetView("List", 0, 0, maxX/2-maxX/3-1, maxY-1, 0); err4 != nil {
|
||||
if !gocui.IsUnknownView(err4) {
|
||||
return err4
|
||||
}
|
||||
listView.Title = "Channels"
|
||||
fmt.Fprintf(listView, "Lists\nWindow\nTo view\n activity")
|
||||
}
|
||||
return nil
|
||||
@ -264,15 +300,15 @@ func layout2(g *gocui.Gui) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getInputString() (string, error) {
|
||||
inputView, _ := g.View("Input")
|
||||
func getInputString(viewName string) (string, error) {
|
||||
inputView, _ := g.View(viewName)
|
||||
return inputView.Line(0)
|
||||
}
|
||||
|
||||
func initKeybindings() error {
|
||||
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
input, err := getInputString()
|
||||
input, err := getInputString("Input")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -287,7 +323,16 @@ func initKeybindings() error {
|
||||
}
|
||||
if err := g.SetKeybinding("Input", gocui.KeyEnter, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return handleInput()
|
||||
return handleInput("Input")
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("Edit", gocui.KeyEnter, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
popupView("Chat")
|
||||
popupView("Input")
|
||||
return handleInput("Edit")
|
||||
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -345,6 +390,7 @@ func handleMessage(api keybase.ChatAPI) {
|
||||
}
|
||||
|
||||
}
|
||||
fmt.Print("\a")
|
||||
}
|
||||
if api.Msg.Channel.MembersType == channel.MembersType && cleanChannelName(api.Msg.Channel.Name) == channel.Name {
|
||||
if channel.MembersType == keybase.TEAM && channel.TopicName != api.Msg.Channel.TopicName {
|
||||
@ -374,9 +420,9 @@ func handleMessage(api keybase.ChatAPI) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleInput() error {
|
||||
clearView("Input")
|
||||
inputString, _ := getInputString()
|
||||
func handleInput(viewName string) error {
|
||||
clearView(viewName)
|
||||
inputString, _ := getInputString(viewName)
|
||||
if inputString == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
// +ignore
|
||||
// +build type_commands autoreactcmd
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"samhofi.us/x/keybase"
|
||||
)
|
||||
|
||||
func init() {
|
||||
command := TypeCommand{
|
||||
Cmd: []string{"text"},
|
||||
Name: "AutoReact",
|
||||
Description: "Automatically reacts to every incoming message with an emoji",
|
||||
Exec: tcmdAutoReact,
|
||||
}
|
||||
|
||||
RegisterTypeCommand(command)
|
||||
}
|
||||
|
||||
func tcmdAutoReact(m keybase.ChatAPI) {
|
||||
msgID := m.Msg.ID
|
||||
channel := m.Msg.Channel
|
||||
chat := k.NewChat(channel)
|
||||
chat.React(msgID, ":+1:")
|
||||
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
// +ignore
|
||||
// +build type_commands showreactionscmd
|
||||
// +build !rm_basic_commands type_commands showreactionscmd
|
||||
|
||||
package main
|
||||
|
||||
|
||||
Reference in New Issue
Block a user