diff options
Diffstat (limited to 'go-src')
| -rw-r--r-- | go-src/utils/utils.go | 15 | ||||
| -rw-r--r-- | go-src/windows.go | 138 | ||||
| -rw-r--r-- | go-src/windowsHelpers.go | 91 |
3 files changed, 130 insertions, 114 deletions
diff --git a/go-src/utils/utils.go b/go-src/utils/utils.go index 5676744..d241da6 100644 --- a/go-src/utils/utils.go +++ b/go-src/utils/utils.go @@ -33,3 +33,18 @@ func AppendToFile(path string, value string) { allChatsFile.WriteString(value) allChatsFile.Close() } + +func StrShortenRight(s *string, amount int) { + *s = (*s)[:len(*s)-amount] +} + +// Special thanks to icza, over on https://stackoverflow.com/a/59375088 for the If constuction + +type If bool + +func (c If) Int(a, b int) int { + if c { + return a + } + return b +} diff --git a/go-src/windows.go b/go-src/windows.go index 744e672..e7e414b 100644 --- a/go-src/windows.go +++ b/go-src/windows.go @@ -6,8 +6,11 @@ import ( "gitlab.com/Syndamia/ctfc/go-src/csi" "gitlab.com/Syndamia/ctfc/go-src/ui" + "gitlab.com/Syndamia/ctfc/go-src/utils" ) +const showHelp = "ShowHelp" + type window func(...string) func StartupWindow(...string) { @@ -20,10 +23,11 @@ func StartupWindow(...string) { inputAction{"L", loginWindow, nil}, inputAction{"R", registerWindow, nil}, ) - if handled != nil { - defer handled() - } else { + + if handled == nil { defer showError(invalidCommand, StartupWindow) + } else { + defer handled() } } @@ -73,30 +77,25 @@ func registerWindow(values ...string) { func chatsWindow(values ...string) { csi.ClearScreen() - if len(values) == 0 { - values = append(append(values, ""), ".") - } + initPaginatedValues(0, values) ui.NormalBox(true, "Direct Messages", "Account", "Logout") allChats := getAllChats() + ui.EmptyLines(pageSize + 3) // empty line + message lines + page number line + empty line - customLinesBelow := 2 - if values[0] == "ShowHelp" { - customLinesBelow++ - } - ui.EmptyLines(pageSize + 1 + customLinesBelow) + customLinesBelow := utils.If(values[1] == showHelp).Int(3, 2) lastLine := -1 go routinePaginatedSubwindow(&allChats, func(s *[]string) { *s = getAllChats() }, &lastLine, - len(values[1]), + len(values[0]), customLinesBelow, true, ) - if values[0] == "ShowHelp" { + if values[1] == showHelp { ui.TextField("Chats page options: [(D)irect messages/(A)ccount/(L)ogout/(<) for previous page/(>) for next page/(C) for create chat/(name) for go to chat room by name/(number) for go to chat room by number/(H)elp]") } @@ -104,18 +103,18 @@ func chatsWindow(values ...string) { handled := handleInputActions(input, true, inputAction{"C", createChatWindow, nil}, - inputAction{"H", chatsWindow, []string{"ShowHelp", values[1]}}, + inputAction{"H", chatsWindow, []string{values[0], "ShowHelp"}}, ) - if handled != nil { - defer handled() - } else { + if handled == nil { // If user input is number, navigate to chat of given number, else show error if chatI, err := strconv.Atoi(input); chatI >= 0 && chatI <= len(allChats) && err == nil { defer chatWindow(strings.Split(allChats[chatI-1], " : ")[0]) } else { defer showError(invalidCommand, chatsWindow) } + } else { + defer handled() } lastLine = -2 } @@ -145,9 +144,7 @@ func chatWindow(values ...string) { // We determine page number by length of a string // This method should be faster than having to cast to int all the time - if len(values) == 1 { - values = append(append(values, "."), "") - } + initPaginatedValues(1, values) currChat := getChat(values[0]) @@ -157,14 +154,9 @@ func chatWindow(values ...string) { "Brought to you by "+currChat.Owner.Name+" ("+currChat.Owner.Username+")", ) - customLinesBelow := 2 - // One empty line to separate the "Brought to you by" line - // with the chat messages, and then empty line for each chat message - ui.EmptyLines(pageSize + 1 + customLinesBelow) + ui.EmptyLines(pageSize + 3) // empty line + messages lines + page number line + empty line - if values[2] == "ShowHelp" { - customLinesBelow++ - } + customLinesBelow := utils.If(values[2] == "ShowHelp").Int(3, 2) lastLine := -1 go routinePaginatedSubwindow(&currChat.Messages, @@ -183,12 +175,10 @@ func chatWindow(values ...string) { input := ui.InputField("Message or [C/D/A/L/</>/H]") handled := handleInputActions(input, true, - inputAction{"H", chatWindow, []string{values[0], values[1], "ShowHelp"}}, + inputAction{"H", chatWindow, []string{values[0], values[1], showHelp}}, ) - if handled != nil { - defer handled() - } else { + if handled == nil { switch input { case ">": // If possible, increment to the next page (adds a dot to the end of the string) @@ -198,7 +188,7 @@ func chatWindow(values ...string) { case "<": // If possible, decrement to the previous page (removes a dot from the string) if len(values[1]) > 1 { - values[1] = values[1][:len(values[1])-1] + utils.StrShortenRight(&values[1], 1) } default: // Send a message values[1] = "." // Make sure to be at the first page, when sending a message @@ -207,6 +197,8 @@ func chatWindow(values ...string) { } defer chatWindow(values...) + } else { + defer handled() } lastLine = -2 // Practically stops execution of the paginated subwindow routine } @@ -226,85 +218,3 @@ func logoutWindow(...string) { defer chatsWindow() } } - -func showError(message string, callback window, callbackData ...string) { - csi.ClearScreen() - - ui.ErrorBox(message) - csi.BlockClearScreenNextTime() - - defer callback(callbackData...) -} - -/* Form */ - -type formInput struct { - name string - specification string - validationFunc func(string) bool -} - -func formWindow(boxTitle string, backWindow window, formInputs []formInput, currentValues ...string) (userInputs []string) { - userInputs = currentValues - // Go through all inputs - for i, v := range formInputs[len(currentValues):] { - csi.ClearScreen() - - ui.NormalBox(true, boxTitle) - - // Show filled input fields - for j, va := range userInputs { - ui.InputFieldFilled(formInputs[j].name, va) - } - - // Wait for input on current input field - input := ui.InputField(v.name + v.specification) - - // Go to the "backWindow", if we're on the first input, we are given a back window, and the letter B is given - if i == 0 && backWindow != nil && strings.ToLower(input) == "b" { - defer backWindow() - return - } - - // If we're validating input data, try to validate - if v.validationFunc != nil { - // If input data isn't valid, show an error and the same screen - if !v.validationFunc(input) { - formCallback := func(...string) { - defer formWindow(boxTitle, backWindow, formInputs, userInputs...) - } - defer showError(invalidValueFor(v.name), formCallback) - return - } - } - - // Add current input as a filled input - userInputs = append(userInputs, input) - } - return -} - -/* Input actions */ - -type inputAction struct { - value string - execute window - args []string -} - -func handleInputActions(input string, handleNav bool, ia ...inputAction) func() { - if handleNav { - ia = append(ia, - inputAction{"C", chatsWindow, nil}, - inputAction{"D", chatsWindow, nil}, - inputAction{"A", chatsWindow, nil}, - inputAction{"L", logoutWindow, nil}, - ) - } - for _, v := range ia { - if strings.ToLower(input) == strings.ToLower(v.value) { - return func() { v.execute(v.args...) } - } - } - return nil -} diff --git a/go-src/windowsHelpers.go b/go-src/windowsHelpers.go index fb530c1..d4ff90c 100644 --- a/go-src/windowsHelpers.go +++ b/go-src/windowsHelpers.go @@ -1,6 +1,7 @@ package ctfc import ( + "strings" "time" "gitlab.com/Syndamia/ctfc/go-src/csi" @@ -56,3 +57,93 @@ func routinePaginatedSubwindow(messages *[]string, updateMessages func(*[]string time.Sleep(500 * time.Millisecond) } } + +func initPaginatedValues(defaultLength int, values []string) { + if len(values) == defaultLength { + values = append(append(values, "."), "") + } +} + +/* Input actions */ + +type inputAction struct { + value string + execute window + args []string +} + +func handleInputActions(input string, handleNav bool, ia ...inputAction) func() { + if handleNav { + ia = append(ia, + inputAction{"C", chatsWindow, nil}, + inputAction{"D", chatsWindow, nil}, + inputAction{"A", chatsWindow, nil}, + inputAction{"L", logoutWindow, nil}, + ) + } + for _, v := range ia { + if strings.ToLower(input) == strings.ToLower(v.value) { + return func() { v.execute(v.args...) } + } + } + return nil +} + +/* Form */ + +type formInput struct { + name string + specification string + validationFunc func(string) bool +} + +func formWindow(boxTitle string, backWindow window, formInputs []formInput, currentValues ...string) (userInputs []string) { + userInputs = currentValues + // Go through all inputs + for i, v := range formInputs[len(currentValues):] { + csi.ClearScreen() + + ui.NormalBox(true, boxTitle) + + // Show filled input fields + for j, va := range userInputs { + ui.InputFieldFilled(formInputs[j].name, va) + } + + // Wait for input on current input field + input := ui.InputField(v.name + v.specification) + + // Go to the "backWindow", if we're on the first input, we are given a back window, and the letter B is given + if i == 0 && backWindow != nil && strings.ToLower(input) == "b" { + defer backWindow() + return + } + + // If we're validating input data, try to validate + if v.validationFunc != nil { + // If input data isn't valid, show an error and the same screen + if !v.validationFunc(input) { + formCallback := func(...string) { + defer formWindow(boxTitle, backWindow, formInputs, userInputs...) + } + defer showError(invalidValueFor(v.name), formCallback) + return + } + } + + // Add current input as a filled input + userInputs = append(userInputs, input) + } + return +} + +/* Error */ + +func showError(message string, callback window, callbackData ...string) { + csi.ClearScreen() + + ui.ErrorBox(message) + csi.BlockClearScreenNextTime() + + defer callback(callbackData...) +} |
