diff --git a/textinput/text.go b/textinput/text.go new file mode 100644 index 0000000..6340dd9 --- /dev/null +++ b/textinput/text.go @@ -0,0 +1,123 @@ +package textinput + +import ( + "fmt" + "git.shadowhosting.xyz/Eggactyl/tui/validators" + + "golang.org/x/term" +) + +type InputData struct { + Notice string + Question string + Validator validators.TextInputValidator + ValidationFunc func(input string) bool +} + +func New(data InputData) (*string, error) { + + if data.Notice != "" { + fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m!\033[38;5;247m]\033[22m \033[3m%s\033[0m\n", data.Notice) + } else if data.Validator != nil && data.Validator.Notice() != "" { + fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m!\033[38;5;247m]\033[22m \033[3m%s\033[0m\n", data.Validator.Notice()) + } + + if data.Question != "" { + fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m?\033[38;5;247m]\033[0m %s \033[38;5;247m>>\033[3m\033[38;5;214m\n", data.Question) + } + + var input string + + for { + + if _, err := fmt.Scanln(&input); err != nil { + return nil, err + } + + width, _, err := term.GetSize(0) + if err != nil { + return nil, err + } + + if data.ValidationFunc != nil { + if !data.ValidationFunc(input) { + var lineNum int + + if width == 0 { + if data.Notice != "" { + lineNum++ + } + lineNum += 2 + } else { + if data.Notice == "" { + lineNum = ((len(data.Question) + 5 + width - 1) / width) + 1 + } else { + lineNum = ((len(data.Notice) + 5 + width) / width) + ((len(data.Question) + 5 + width - 1) / width) + 1 + } + } + + for i := 0; i < lineNum; i++ { + fmt.Printf("\033[A\033[K\033[0G") + } + fmt.Println("\033[0m\033[1m\033[38;5;247m[\033[38;5;167m!\033[38;5;247m]\033[0m Invalid input, please try again!\n ") + + if data.Notice != "" { + fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m!\033[38;5;247m]\033[22m \033[3m%s\033[0m\n", data.Notice) + } else if data.Validator != nil { + fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m!\033[38;5;247m]\033[22m \033[3m%s\033[0m\n", data.Validator.Notice()) + } + + if data.Question != "" { + fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m?\033[38;5;247m]\033[0m %s \033[38;5;247m>>\033[3m\033[38;5;214m\n", data.Question) + } + continue + } + } else if data.Validator != nil { + if !data.Validator.ValidationFunc(input) { + var lineNum int + + if width == 0 { + if data.Notice != "" || data.Validator.Notice() != "" { + lineNum++ + } + lineNum += 2 + } else { + if data.Notice == "" && data.Validator.Notice() == "" { + lineNum = ((len(data.Question) + 5 + width - 1) / width) + 1 + } else { + if data.Notice != "" { + lineNum = ((len(data.Notice) + 5 + width) / width) + ((len(data.Question) + 5 + width - 1) / width) + 1 + } else if data.Validator.Notice() != "" { + lineNum = ((len(data.Validator.Notice()) + 5 + width - 1) / width) + ((len(data.Question) + 5 + width - 1) / width) + 1 + } + } + } + + for i := 0; i < lineNum; i++ { + fmt.Printf("\033[A\033[K\033[0G") + } + + fmt.Println("\033[0m\033[1m\033[38;5;247m[\033[38;5;167m!\033[38;5;247m]\033[0m Invalid input, please try again!\n ") + + if data.Notice != "" { + fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m!\033[38;5;247m]\033[22m \033[3m%s\033[0m\n", data.Notice) + } else if data.Validator.Notice() != "" { + fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m!\033[38;5;247m]\033[22m \033[3m%s\033[0m\n", data.Validator.Notice()) + } + + if data.Question != "" { + fmt.Printf("\033[1m\033[38;5;247m[\033[38;5;214m?\033[38;5;247m]\033[0m %s \033[38;5;247m>>\033[3m\033[38;5;214m\n", data.Question) + } + continue + } + } + + break + + } + + fmt.Println("\033[0m") + + return &input, nil + +}