Split command system from main view
This commit is contained in:
		
							
								
								
									
										128
									
								
								ui/command-processor.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								ui/command-processor.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
			
		||||
// gomuks - A terminal Matrix client written in Go.
 | 
			
		||||
// Copyright (C) 2018 Tulir Asokan
 | 
			
		||||
//
 | 
			
		||||
// 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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
package ui
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"maunium.net/go/gomuks/interface"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"maunium.net/go/gomuks/config"
 | 
			
		||||
	"maunium.net/go/gomuks/debug"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type gomuksPointerContainer struct {
 | 
			
		||||
	MainView *MainView
 | 
			
		||||
	UI       *GomuksUI
 | 
			
		||||
	Matrix   ifc.MatrixContainer
 | 
			
		||||
	Config   *config.Config
 | 
			
		||||
	Gomuks   ifc.Gomuks
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Command struct {
 | 
			
		||||
	gomuksPointerContainer
 | 
			
		||||
	Handler *CommandProcessor
 | 
			
		||||
 | 
			
		||||
	Room     *RoomView
 | 
			
		||||
	Command  string
 | 
			
		||||
	Args     []string
 | 
			
		||||
	OrigText string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cmd *Command) Reply(message string, args ...interface{}) {
 | 
			
		||||
	cmd.Room.AddServiceMessage(fmt.Sprintf(message, args...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Alias struct {
 | 
			
		||||
	NewCommand string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (alias *Alias) Process(cmd *Command) *Command {
 | 
			
		||||
	cmd.Command = alias.NewCommand
 | 
			
		||||
	return cmd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CommandHandler func(cmd *Command)
 | 
			
		||||
 | 
			
		||||
type CommandProcessor struct {
 | 
			
		||||
	gomuksPointerContainer
 | 
			
		||||
 | 
			
		||||
	aliases  map[string]*Alias
 | 
			
		||||
	commands map[string]CommandHandler
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewCommandProcessor(parent *MainView) *CommandProcessor {
 | 
			
		||||
	return &CommandProcessor{
 | 
			
		||||
		gomuksPointerContainer: gomuksPointerContainer{
 | 
			
		||||
			MainView: parent,
 | 
			
		||||
			UI:       parent.parent,
 | 
			
		||||
			Matrix:   parent.matrix,
 | 
			
		||||
			Config:   parent.config,
 | 
			
		||||
			Gomuks:   parent.gmx,
 | 
			
		||||
		},
 | 
			
		||||
		aliases: map[string]*Alias{
 | 
			
		||||
			"part": {"leave"},
 | 
			
		||||
		},
 | 
			
		||||
		commands: map[string]CommandHandler{
 | 
			
		||||
			"unknown-command": cmdUnknownCommand,
 | 
			
		||||
			"help":            cmdHelp,
 | 
			
		||||
			"me":              cmdMe,
 | 
			
		||||
			"quit":            cmdQuit,
 | 
			
		||||
			"clearcache":      cmdClearCache,
 | 
			
		||||
			"leave":           cmdLeave,
 | 
			
		||||
			"join":            cmdJoin,
 | 
			
		||||
			"uitoggle":        cmdUIToggle,
 | 
			
		||||
			"logout":          cmdLogout,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ch *CommandProcessor) ParseCommand(roomView *RoomView, text string) *Command {
 | 
			
		||||
	if text[0] != '/' || len(text) < 2 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	text = text[1:]
 | 
			
		||||
	args := strings.SplitN(text, " ", 2)
 | 
			
		||||
	command := strings.ToLower(args[0])
 | 
			
		||||
	args = args[1:]
 | 
			
		||||
	return &Command{
 | 
			
		||||
		gomuksPointerContainer: ch.gomuksPointerContainer,
 | 
			
		||||
		Handler:                ch,
 | 
			
		||||
 | 
			
		||||
		Room:     roomView,
 | 
			
		||||
		Command:  command,
 | 
			
		||||
		Args:     args,
 | 
			
		||||
		OrigText: text,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ch *CommandProcessor) HandleCommand(cmd *Command) {
 | 
			
		||||
	defer debug.Recover()
 | 
			
		||||
	if cmd == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if alias, ok := ch.aliases[cmd.Command]; ok {
 | 
			
		||||
		cmd = alias.Process(cmd)
 | 
			
		||||
	}
 | 
			
		||||
	if cmd == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if handler, ok := ch.commands[cmd.Command]; ok {
 | 
			
		||||
		handler(cmd)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	cmdUnknownCommand(cmd)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										99
									
								
								ui/commands.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								ui/commands.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
// gomuks - A terminal Matrix client written in Go.
 | 
			
		||||
// Copyright (C) 2018 Tulir Asokan
 | 
			
		||||
//
 | 
			
		||||
// 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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
package ui
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"maunium.net/go/gomuks/debug"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func cmdMe(cmd *Command) {
 | 
			
		||||
	text := strings.Join(cmd.Args, " ")
 | 
			
		||||
	tempMessage := cmd.Room.NewTempMessage("m.emote", text)
 | 
			
		||||
	go cmd.MainView.sendTempMessage(cmd.Room, tempMessage, text)
 | 
			
		||||
	cmd.UI.Render()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdQuit(cmd *Command) {
 | 
			
		||||
	cmd.Gomuks.Stop()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdClearCache(cmd *Command) {
 | 
			
		||||
	cmd.Config.Clear()
 | 
			
		||||
	cmd.Gomuks.Stop()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdUnknownCommand(cmd *Command) {
 | 
			
		||||
	cmd.Reply("Unknown command \"%s\". Try \"/help\" for help.", cmd.Command)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdHelp(cmd *Command) {
 | 
			
		||||
	cmd.Reply("Known command. Don't try \"/help\" for help.")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdLeave(cmd *Command) {
 | 
			
		||||
	err := cmd.Matrix.LeaveRoom(cmd.Room.MxRoom().ID)
 | 
			
		||||
	debug.Print("Leave room error:", err)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		cmd.MainView.RemoveRoom(cmd.Room.MxRoom())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdJoin(cmd *Command) {
 | 
			
		||||
	if len(cmd.Args) == 0 {
 | 
			
		||||
		cmd.Reply("Usage: /join <room>")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	identifer := cmd.Args[0]
 | 
			
		||||
	server := ""
 | 
			
		||||
	if len(cmd.Args) > 1 {
 | 
			
		||||
		server = cmd.Args[1]
 | 
			
		||||
	}
 | 
			
		||||
	room, err := cmd.Matrix.JoinRoom(identifer, server)
 | 
			
		||||
	debug.Print("Join room error:", err)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		cmd.MainView.AddRoom(room)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdUIToggle(cmd *Command) {
 | 
			
		||||
	if len(cmd.Args) == 0 {
 | 
			
		||||
		cmd.Reply("Usage: /uitoggle <rooms/users/baremessages>")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	switch cmd.Args[0] {
 | 
			
		||||
	case "rooms":
 | 
			
		||||
		cmd.MainView.hideRoomList = !cmd.MainView.hideRoomList
 | 
			
		||||
		cmd.Config.Preferences.HideRoomList = cmd.MainView.hideRoomList
 | 
			
		||||
	case "users":
 | 
			
		||||
		cmd.MainView.hideUserList = !cmd.MainView.hideUserList
 | 
			
		||||
		cmd.Config.Preferences.HideUserList = cmd.MainView.hideUserList
 | 
			
		||||
	case "baremessages":
 | 
			
		||||
		cmd.MainView.bareMessages = !cmd.MainView.bareMessages
 | 
			
		||||
		cmd.Config.Preferences.BareMessageView = cmd.MainView.bareMessages
 | 
			
		||||
	default:
 | 
			
		||||
		cmd.Reply("Usage: /uitoggle <rooms/users/baremessages>")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	cmd.UI.Render()
 | 
			
		||||
	cmd.UI.Render()
 | 
			
		||||
	go cmd.Matrix.SendPreferencesToMatrix()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdLogout(cmd *Command) {
 | 
			
		||||
	cmd.Matrix.Logout()
 | 
			
		||||
}
 | 
			
		||||
@@ -18,7 +18,6 @@ package ui
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unicode"
 | 
			
		||||
 | 
			
		||||
@@ -43,6 +42,7 @@ type MainView struct {
 | 
			
		||||
	roomList     *RoomList
 | 
			
		||||
	roomView     *tview.Pages
 | 
			
		||||
	rooms        map[string]*RoomView
 | 
			
		||||
	cmdProcessor *CommandProcessor
 | 
			
		||||
 | 
			
		||||
	lastFocusTime time.Time
 | 
			
		||||
 | 
			
		||||
@@ -73,6 +73,7 @@ func (ui *GomuksUI) NewMainView() tview.Primitive {
 | 
			
		||||
		hideRoomList: prefs.HideRoomList,
 | 
			
		||||
		bareMessages: prefs.BareMessageView,
 | 
			
		||||
	}
 | 
			
		||||
	mainView.cmdProcessor = NewCommandProcessor(mainView)
 | 
			
		||||
 | 
			
		||||
	mainView.
 | 
			
		||||
		SetDirection(tview.FlexColumn).
 | 
			
		||||
@@ -133,10 +134,8 @@ func (view *MainView) InputSubmit(roomView *RoomView, text string) {
 | 
			
		||||
	if len(text) == 0 {
 | 
			
		||||
		return
 | 
			
		||||
	} else if text[0] == '/' {
 | 
			
		||||
		args := strings.SplitN(text, " ", 2)
 | 
			
		||||
		command := strings.ToLower(args[0])
 | 
			
		||||
		args = args[1:]
 | 
			
		||||
		go view.HandleCommand(roomView, command, args)
 | 
			
		||||
		cmd := view.cmdProcessor.ParseCommand(roomView, text)
 | 
			
		||||
		go view.cmdProcessor.HandleCommand(cmd)
 | 
			
		||||
	} else {
 | 
			
		||||
		view.SendMessage(roomView, text)
 | 
			
		||||
	}
 | 
			
		||||
@@ -168,72 +167,6 @@ func (view *MainView) sendTempMessage(roomView *RoomView, tempMessage ifc.Messag
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *MainView) HandleCommand(roomView *RoomView, command string, args []string) {
 | 
			
		||||
	defer debug.Recover()
 | 
			
		||||
	debug.Print("Handling command", command, args)
 | 
			
		||||
	switch command {
 | 
			
		||||
	case "/me":
 | 
			
		||||
		text := strings.Join(args, " ")
 | 
			
		||||
		tempMessage := roomView.NewTempMessage("m.emote", text)
 | 
			
		||||
		go view.sendTempMessage(roomView, tempMessage, text)
 | 
			
		||||
		view.parent.Render()
 | 
			
		||||
	case "/quit":
 | 
			
		||||
		view.gmx.Stop()
 | 
			
		||||
	case "/clearcache":
 | 
			
		||||
		view.config.Clear()
 | 
			
		||||
		view.gmx.Stop()
 | 
			
		||||
	case "/panic":
 | 
			
		||||
		panic("This is a test panic.")
 | 
			
		||||
	case "/part", "/leave":
 | 
			
		||||
		err := view.matrix.LeaveRoom(roomView.Room.ID)
 | 
			
		||||
		debug.Print("Leave room error:", err)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			view.RemoveRoom(roomView.Room)
 | 
			
		||||
		}
 | 
			
		||||
	case "/uitoggle":
 | 
			
		||||
		if len(args) == 0 {
 | 
			
		||||
			roomView.AddServiceMessage("Usage: /uitoggle <rooms/users/baremessages>")
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		switch args[0] {
 | 
			
		||||
		case "rooms":
 | 
			
		||||
			view.hideRoomList = !view.hideRoomList
 | 
			
		||||
			view.config.Preferences.HideRoomList = view.hideRoomList
 | 
			
		||||
		case "users":
 | 
			
		||||
			view.hideUserList = !view.hideUserList
 | 
			
		||||
			view.config.Preferences.HideUserList = view.hideUserList
 | 
			
		||||
		case "baremessages":
 | 
			
		||||
			view.bareMessages = !view.bareMessages
 | 
			
		||||
			view.config.Preferences.BareMessageView = view.bareMessages
 | 
			
		||||
		default:
 | 
			
		||||
			roomView.AddServiceMessage("Usage: /uitoggle <rooms/users/baremessages>")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		view.parent.Render()
 | 
			
		||||
		view.parent.Render()
 | 
			
		||||
		go view.matrix.SendPreferencesToMatrix()
 | 
			
		||||
	case "/join":
 | 
			
		||||
		if len(args) == 0 {
 | 
			
		||||
			roomView.AddServiceMessage("Usage: /join <room>")
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		identifer := args[0]
 | 
			
		||||
		server := ""
 | 
			
		||||
		if len(args) > 1 {
 | 
			
		||||
			server = args[1]
 | 
			
		||||
		}
 | 
			
		||||
		room, err := view.matrix.JoinRoom(identifer, server)
 | 
			
		||||
		debug.Print("Join room error:", err)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			view.AddRoom(room)
 | 
			
		||||
		}
 | 
			
		||||
	case "/logout":
 | 
			
		||||
		view.matrix.Logout()
 | 
			
		||||
	default:
 | 
			
		||||
		roomView.AddServiceMessage("Unknown command.")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *MainView) ShowBare(roomView *RoomView) {
 | 
			
		||||
	_, height := view.parent.app.GetScreen().Size()
 | 
			
		||||
	view.parent.app.Suspend(func() {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user