First implementation fo the message box as a command input
MODIFY
internal/app.go
internal/app.go
@@ -5,6 +5,7 @@ import (
"log"
"os"
+ "github.com/Bios-Marcel/cordless/internal/commands"
"github.com/Bios-Marcel/cordless/internal/config"
"github.com/Bios-Marcel/cordless/internal/ui"
"github.com/bwmarrin/discordgo"
@@ -52,6 +53,8 @@ func Run() {
log.Fatalf("Error constructing window (%s).\n", createError.Error())
}
+ window.RegisterCommand("fixedlayout", commands.FixedLayout)
+
runError := window.Run()
if runError != nil {
log.Fatalf("Error launching View (%s).\n", runError.Error())

ADD
internal/commands/fixedlayout.go
+package commands
+
+import (
+ "errors"
+ "strconv"
+
+ "github.com/Bios-Marcel/cordless/internal/config"
+ "github.com/Bios-Marcel/cordless/internal/ui"
+)
+
+func FixedLayout(window *ui.Window, parameters []string) error {
+ if len(parameters) == 1 {
+ choice, parseError := strconv.ParseBool(parameters[0])
+ if parseError != nil {
+ return errors.New("the given input was incorrect, there has to be only one parameter, which can only be of the value 'true' or 'false'")
+ }
+
+ config.GetConfig().UseFixedLayout = choice
+ window.RefreshLayout()
+
+ persistError := config.PersistConfig()
+ if persistError != nil {
+ return persistError
+ }
+
+ return nil
+ }
+
+ if len(parameters) == 2 {
+ size, parseError := strconv.ParseInt(parameters[1], 10, 64)
+ if parseError != nil {
+ return errors.New("the given input was invalid, it has to be an integral number greater than -1")
+ }
+
+ if size < 0 {
+ return errors.New("the given input was out of bounds, it has to be bigger than -1")
+ }
+
+ //TODO Check for upper limit?
+
+ subCommand := parameters[0]
+ if subCommand == "left" {
+ config.GetConfig().FixedSizeLeft = int(size)
+ } else if subCommand == "right" {
+ config.GetConfig().FixedSizeRight = int(size)
+ } else {
+ return errors.New("the subcommand" + subCommand + " does not exist")
+ }
+
+ window.RefreshLayout()
+
+ persistError := config.PersistConfig()
+ if persistError != nil {
+ return persistError
+ }
+ }
+
+ //TODO Print help
+
+ return nil
+}

MODIFY
internal/config/config.go
internal/config/config.go
@@ -15,8 +15,11 @@ const (
//It us used for filepaths and such.
AppNameLowercase = "cordless"
+ //HourMinuteAndSeconds is the time format HH:MM:SS.
HourMinuteAndSeconds = 0
+ //HourAndMinute is the time format HH:MM.
HourAndMinute = 1
+ //NoTime means that not time at all will be displayed.
NoTime = 2
)
@@ -25,16 +28,40 @@ var (
Times: HourMinuteAndSeconds,
ShowUserContainer: true,
ShowFrame: true,
+ UseFixedLayout: false,
+ FixedSizeLeft: 12,
+ FixedSizeRight: 12,
+ CommandPrefix: "!c",
}
)
//Config contains all possible configuration for the application.
type Config struct {
+ //Token is the authorization token for accessing the discord API.
Token string
+ //Times decides on the time format (none, short and long).
Times int
+
+ //ShowUserContainer decides wether the user container is part of the
+ //layout or not.
ShowUserContainer bool
+
+ //ShowFrame decides wether the application will have a border and a title.
ShowFrame bool
+
+ //UseFixedLayout defines whether the FixedSizeLeft and FixedSizeRight
+ //values will be applied or not.
+ UseFixedLayout bool
+ //FixedSizeLeft determines the size of the guilds/channels/friends
+ //container on the left side of the layout.
+ FixedSizeLeft int
+ //FixedSizeRight defines the size of the users container on the right.
+ FixedSizeRight int
+
+ //CommandPrefix determines which prefix a text needs in order to be
+ //recognized as an application internal command.
+ CommandPrefix string
}
var cachedConfigDir string

MODIFY
internal/ui/window.go
internal/ui/window.go
@@ -52,6 +52,8 @@ type Window struct {
selectedChannelNode *tview.TreeNode
selectedChannel *discordgo.Channel
+
+ commands map[string]func(*Window, []string) error
}
func NewWindow(discord *discordgo.Session) (*Window, error) {
@@ -60,6 +62,7 @@ func NewWindow(discord *discordgo.Session) (*Window, error) {
window := Window{
session: discord,
app: app,
+ commands: make(map[string]func(*Window, []string) error, 1),
}
guilds, discordError := discord.UserGuilds(100, "", "")
@@ -314,7 +317,11 @@ func NewWindow(discord *discordgo.Session) (*Window, error) {
window.messageInput.SetBorder(true)
window.messageInput.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
- if event.Key() == tcell.KeyUp && window.messageInput.GetText() == "" {
+ messageToSend := window.messageInput.GetText()
+ if messageToSend == "" {
+
+ }
+ if event.Key() == tcell.KeyUp {
for i := len(window.shownMessages) - 1; i > 0; i-- {
message := window.shownMessages[i]
if message.Author.ID == window.session.State.User.ID {
@@ -334,8 +341,20 @@ func NewWindow(discord *discordgo.Session) (*Window, error) {
}
if event.Key() == tcell.KeyEnter {
+ conf := config.GetConfig()
+ if conf.CommandPrefix != "" && strings.HasPrefix(messageToSend, conf.CommandPrefix) {
+ command := strings.TrimPrefix(messageToSend, conf.CommandPrefix)
+ commandError := window.ExecuteCommand(strings.TrimSpace(command))
+ if commandError != nil {
+ window.ShowErrorDialog(commandError.Error())
+ }
+
+ window.messageInput.SetText("")
+
+ return nil
+ }
+
if window.selectedChannel != nil {
- messageToSend := window.messageInput.GetText()
window.messageInput.SetText("")
if len(messageToSend) != 0 {
@@ -538,6 +557,16 @@ func NewWindow(discord *discordgo.Session) (*Window, error) {
return &window, nil
}
+func (window *Window) ExecuteCommand(command string) error {
+ parts := strings.Split(command, " ")
+ commandLogic, exists := window.commands[parts[0]]
+ if exists {
+ return commandLogic(window, parts[1:])
+ }
+
+ return nil
+}
+
func (window *Window) exitMessageEditMode() {
window.editingMessageID = nil
window.messageInput.SetBackgroundColor(tcell.ColorDefault)
@@ -606,15 +635,25 @@ func (window *Window) RefreshLayout() {
window.rootContainer.RemoveItem(window.chatArea)
window.rootContainer.RemoveItem(window.userContainer)
+ conf := config.GetConfig()
+
+ if conf.UseFixedLayout {
+ window.rootContainer.AddItem(window.leftArea, conf.FixedSizeLeft, 7, true)
+ window.rootContainer.AddItem(window.chatArea, 0, 1, false)
+
+ if conf.ShowUserContainer && window.overrideShowUsers {
+ window.rootContainer.AddItem(window.userContainer, conf.FixedSizeRight, 6, false)
+ }
+ } else {
window.rootContainer.AddItem(window.leftArea, 0, 7, true)
- conf := config.GetConfig()
if conf.ShowUserContainer && window.overrideShowUsers {
window.rootContainer.AddItem(window.chatArea, 0, 20, false)
window.rootContainer.AddItem(window.userContainer, 0, 6, false)
} else {
window.rootContainer.AddItem(window.chatArea, 0, 26, false)
}
+ }
if conf.ShowFrame {
window.rootContainer.SetTitle("Cordless")
@@ -769,6 +808,13 @@ func (window *Window) UpdateUsersForGuild(guild *discordgo.UserGuild) {
})
}
+//RegisterCommand register a command. That makes the command available for
+//being called from the message input field, in case the user-defined prefix
+//is in front of the input.
+func (window *Window) RegisterCommand(name string, logic func(window *Window, parameters []string) error) {
+ window.commands[name] = logic
+}
+
//Run Shows the window optionally returning an error.
func (window *Window) Run() error {
return window.app.Run()

First implementation fo the message box as a command input