Example #1
0
func main() {
	scr, _ := gc.Init()
	defer gc.End()

	rows, cols := scr.Maxyx()

	gc.InitPair(ChatAreaColor, gc.C_WHITE, gc.C_BLACK)
	gc.InitPair(InputAreaColor, gc.C_BLACK, gc.C_WHITE)

	chatArea := scr.Derived(rows-1, cols, 0, 0)
	chatArea.SetBackground(gc.Character(' ' | gc.ColorPair(ChatAreaColor)))

	inputArea := scr.Derived(1, cols, rows-1, 0)
	chatArea.SetBackground(gc.Character(' ' | gc.ColorPair(InputAreaColor)))

	chat := make(chan string)
	go func() {
		for msg := range chat {
			msg = fmt.Sprintf("%v| %v", time.Now().Format("15:04:05"), msg)
			chatArea.Scroll(1)
			chatArea.MovePrint(rows-2, 0, msg)
			chatArea.Refresh()
		}
	}()
	defer close(chat)

	userInputChan := make(chan string)
	go func() {
		for msg := range userInputChan {
			if len(msg) > 0 && msg[0] == '/' {
				chat <- fmt.Sprintf("Command: %s", msg[1:])
			} else {
				chat <- msg
			}
		}
	}()
	defer close(userInputChan)

	gc.Echo(false)
	gc.CBreak(true)
	gc.Raw(true)
	chatArea.ScrollOk(true)
	scr.Keypad(true)

	chat <- "Welcome to snails shitty chat thing."
	chat <- "Press esc to quit, it may or may not break stuff. "
	chat <- "If it does, do a 'reset' to fix it."
	buffer := ""
	for {
		chatArea.Refresh()
		key := inputArea.GetChar()
		switch key {
		case gc.Key(27):
			return
		case gc.KEY_RETURN:
			userInputChan <- buffer
			buffer = ""
			chatArea.Refresh()
		case gc.Key(127): //backspace
			l := len(buffer)
			if l > 0 {
				buffer = buffer[:l-1]
			}
		default:
			buffer = fmt.Sprintf("%s%c", buffer, key)
		}
		inputArea.Clear()
		inputArea.MovePrint(0, 0, buffer)
	}

}
Example #2
0
func cli() {
	var e error
	scr, e = goncurses.Init()

	if e != nil {
		log.Fatal(e)
	}

	defer goncurses.End()

	exit := false

	pageNum := 0

	p := NewPageCache()

	for !exit {
		scr.Refresh()
		h, _ := scr.MaxYX()

		scr.Clear()

		height := h - BOTTOM_MARGIN

		start := height * pageNum
		end := start + height

		for end > len(p.Articles) {
			p.GetNext()
		}

		for i, ar := range p.Articles[start:end] {
			scr.Printf("%d. (%d): %s\n", start+i+1, ar.Karma, ar.Title)
		}

		scr.Print("\n(n: next, p: previous, <num>c: view comments, <num>o: open in browser, q: quit)  ")
		scr.Refresh()

		doneWithInput := false
		input := ""
		for !doneWithInput {
			c := scr.GetChar()

			if c == 127 {
				c = goncurses.Key(goncurses.KEY_BACKSPACE)
			}

			ch := goncurses.KeyString(c)
			switch ch {
			case "c":
				if num, err := strconv.Atoi(input); err == nil {
					if num < 1 {
						doneWithInput = true
						break
					}

					for num-1 > len(p.Articles) {
						p.GetNext()
					}

					text := p.Articles[num-1].PrintComments()
					line := 0

					cont := true
					for cont {
						scr.Clear()
						scr.Print(pagify(text, line))
						scr.Print("\n\n(d/u scroll 30 lines; j/k: scroll 1 line; n/p scroll 1 page; q: quit)")
						scr.Refresh()

						a := scr.GetChar()

						switch goncurses.KeyString(a) {
						case "d":
							line += 30
							break
						case "u":
							line -= 30
							break
						case "j":
							line += 1
							break
						case "k":
							line -= 1
							break
						case "n":
							line += h
							break
						case "p":
							line -= h
							break
						case "q":
							cont = false
							break
						default:
							scr.DelChar()
							scr.DelChar()
							break
						}

						// Verify lines are not negative. Bad mojo
						if line < 0 {
							line = 0
						}
					}

					doneWithInput = true
				} else {
					scr.Clear()
					scr.Print("\n\nPlease enter a number to select a comment\n\n")
					scr.Refresh()
					scr.GetChar()
					doneWithInput = true
				}
			case "o":
				if num, err := strconv.Atoi(input); err == nil {
					for num-1 > len(p.Articles) {
						p.GetNext()
					}

					viewInBrowser := exec.Command("xdg-open", p.Articles[num-1].Url)
					viewInBrowser.Start()
					doneWithInput = true
				} else {
					scr.Clear()
					scr.Print("\n\nPlease enter a number to view an article\n\n")
					scr.Refresh()
					doneWithInput = true
				}
			case "q":
				doneWithInput = true
				exit = true
			case "n":
				pageNum += 1
				doneWithInput = true
			case "p":
				if pageNum > 0 {
					pageNum -= 1
				}
				doneWithInput = true
			case "enter":
				continue
			case "backspace":
				//Not the prettiest but whatever
				cy, cx := scr.CursorYX()
				if len(input) > 0 {
					input = input[:len(input)-1]
					scr.MoveDelChar(cy, cx-3)
					scr.DelChar()
					scr.DelChar()
				} else {
					scr.MoveDelChar(cy, cx-2)
					scr.DelChar()
					scr.DelChar()
				}
			default:
				input += ch
				break
			}
		}
	}
}