aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSyndamia <kamen.d.mladenov@protonmail.com>2021-07-22 14:02:11 +0300
committerSyndamia <kamen.d.mladenov@protonmail.com>2021-07-22 14:02:11 +0300
commit3d3324e36311aadd02e25e8e11e5d98272c0aa0e (patch)
tree8e30ae5927148506d4644a8de1bbdc128fb53437
parentffc2c1273183b488de9cc4fc282379c2a042bd6d (diff)
downloadctfc-3d3324e36311aadd02e25e8e11e5d98272c0aa0e.tar
ctfc-3d3324e36311aadd02e25e8e11e5d98272c0aa0e.tar.gz
ctfc-3d3324e36311aadd02e25e8e11e5d98272c0aa0e.zip
Moved some stuff from windows.go to windowsHelpers.go, implemented some consistency and code organization improvements
-rw-r--r--go-src/utils/utils.go15
-rw-r--r--go-src/windows.go138
-rw-r--r--go-src/windowsHelpers.go91
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...)
+}