package ctfc import ( "strconv" "strings" "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) { csi.ClearScreen() ui.NormalBox(true, loginNavTitle, registerNavTitle) input := ui.InputField(startupWindowSpec) handled := handleInputActions(input, false, inputAction{"L", loginWindow, nil}, inputAction{"R", registerWindow, nil}, ) if handled == nil { defer showError(invalidCommand, StartupWindow) } else { defer handled() } } func loginWindow(values ...string) { // Takes form user input inputs := formWindow(loginNavTitle, StartupWindow, []formInput{ {usernameInName, inputBackSpec, nil}, {passwordInName, "", nil}, }, values..., ) if len(inputs) == 0 { return } if !usernameExists(inputs[0]) { defer showError(valueDoesNotExist(usernameInName), loginWindow) } // If login is successful, go to chats window, else show error if logInUser(inputs[0], inputs[1]) { defer chatsWindow() } else { defer showError(invalidCredentials, loginWindow, inputs[0]) } } func registerWindow(values ...string) { inputs := formWindow(registerNavTitle, StartupWindow, []formInput{ {usernameInName, usernameSpec, stringValidUsername}, {passwordInName, passwordSpec, stringValidPassword}, {nameInName, nameSpec, stringValidName}, }, values..., ) if len(inputs) == 0 { return } if usernameExists(inputs[0]) { defer showError(valueAlreadyTaken(usernameInName), registerWindow, values...) return } createUser(inputs) logInUser(inputs[0], inputs[1]) defer chatsWindow() } func chatsWindow(values ...string) { csi.ClearScreen() initPaginatedValues(0, &values) ui.NormalBox(true, directMessagesNavTitle, accountNavTitle, logoutNavTitle) allChats := getAllChats() ui.EmptyLines(pageSize + 3) // empty line + message lines + page number line + empty line customLinesBelow := utils.If(values[1] == showHelp).Int(3, 2) lastLine := -1 go routinePaginatedSubwindow(&allChats, func(s *[]string) { *s = getAllChats() }, &lastLine, len(values[0]), customLinesBelow, true, ) if values[1] == showHelp { ui.TextField(chatsWindowHelpMsg) } input := ui.InputField(chatsSpec) handled := handleInputActions(input, true, inputAction{"C", createChatWindow, nil}, inputAction{"H", chatsWindow, []string{values[0], showHelp}}, ) 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[utils.MaxInt(len(allChats)-pageSize*len(values[0]), 0)+chatI-1], " : ")[0]) } else if input == ">" { // If possible, increment to the next page (adds a dot to the end of the string) if len(values[0]) < totalPages(len(allChats)) { values[0] += "." } defer chatsWindow(values...) } else if input == "<" { // If possible, decrement to the previous page (removes a dot from the string) if len(values[0]) > 1 { utils.StrShortenRight(&values[0], 1) } defer chatsWindow(values...) } else if chatNameExists(input) { defer chatWindow(input) } else { defer showError(invalidCommand, chatsWindow) } } else { defer handled() } lastLine = -2 } func createChatWindow(values ...string) { inputs := formWindow(createChatNavTitle, chatsWindow, []formInput{ {chatNameInName, chatNameSpec, stringValidChatName}, {chatDescInName, chatDescSpec, stringValidChatDesc}, }, values..., ) if len(inputs) == 0 { return } if chatNameExists(inputs[0]) { defer showError(valueAlreadyTaken(chatNameInName), createChatWindow, values...) return } createChat(inputs[0], inputs[1], loggedInUser.Username) defer chatWindow(inputs[0]) } func chatWindow(values ...string) { csi.ClearScreen() // We determine page number by length of a string // This method should be faster than having to cast to int all the time initPaginatedValues(1, &values) currChat := getChat(values[0]) ui.NormalBox(true, chatNavTitle, directMessagesNavTitle, accountNavTitle, logoutNavTitle) ui.TextFields( currChat.Name+" : "+currChat.Description, "Brought to you by "+currChat.Owner.Name+" ("+currChat.Owner.Username+")", ) ui.EmptyLines(pageSize + 3) // empty line + messages lines + page number line + empty line customLinesBelow := utils.If(values[2] == showHelp).Int(3, 2) lastLine := -1 go routinePaginatedSubwindow(&currChat.Messages, func(s *[]string) { *s = getChat(values[0]).Messages }, &lastLine, len(values[1]), customLinesBelow, false, ) if values[2] == showHelp { ui.TextField(chatWindowHelpMsg) values[2] = "" } input := ui.InputField(chatWindowSpec) handled := handleInputActions(input, true, inputAction{"H", chatWindow, []string{values[0], values[1], showHelp}}, ) if handled == nil { switch input { case ">": // If possible, increment to the next page (adds a dot to the end of the string) if len(values[1]) < totalPages(len(currChat.Messages)) { values[1] += "." } case "<": // If possible, decrement to the previous page (removes a dot from the string) if 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 // Since "C" is a command, to just enter the letter C you'll need to input "\C" currChat.addMessage(strings.TrimPrefix(input, "\\"), loggedInUser.Username) } defer chatWindow(values...) } else { defer handled() } lastLine = -2 // Practically stops execution of the paginated subwindow routine } func logoutWindow(...string) { csi.ClearScreen() ui.NormalBox(true, "Are you sure you want to Log out of "+loggedInUser.Username+"?") ui.EmptyLine() input := ui.InputField(logoutWindowSpec) if strings.ToLower(input) == "y" { logoutUser() defer StartupWindow() } else { defer chatsWindow() } }