Skip to content

Instantly share code, notes, and snippets.

@progapandist
Created November 11, 2020 13:17
Show Gist options
  • Save progapandist/97f7ccc8169b792e2d0b4a6aab6faf9b to your computer and use it in GitHub Desktop.
Save progapandist/97f7ccc8169b792e2d0b4a6aab6faf9b to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
var (
app *tview.Application // The tview application.
pages *tview.Pages
textView *tview.TextView
menu *tview.List
)
const about = `[::bu]Hi, I'm Andy[::-] 👋
Coming from the international news broadcasting background, I performed a drastic career change at the age of 30 to become a full-stack web developer, thanks to Le Wagon bootcamp in Paris and Vrije Universiteit Amsterdam (CS department).
Now based in Berlin and employed full-time by Le Wagon, I help shape the education process in the bootcamp and work as a back-end and DevOps engineer on our learning platforms. I use (and teach) Ruby on Rails, Docker, and Kubernetes every day.
I have never severed my ties to journalism, so I also hold the position of Lead Writer at Evil Martians, the extraterrestrial product development consultancy.
[::bu]Le Wagon Berlin[::-] https://www.lewagon.com/berlin
[::bu]Evil Martians[::-] https://www.evilmartians.com
[::bu]Martian Chronicles[::-] https://www.evilmartians.com/blog
[::bu]Twitter[::-] https://twitter.com/progapandist
[::bu]Github[::-] https://github.com/progapandist
This is my personal website with a "frontend" built entirely in Go.
`
const cv = `[::bu]My career in a gist[::-] 👨‍💼
* I got my first proper [::b]job in tech[::-] in the year 2000, at the very early age of 15, as a technical editor at [::b]Yandex[::-].
* In 2003, I switched to [::b]broadcast journalism[::-], and worked as an editor, reporter, foreign correspondent, and chief of European bureau for [::b]13 years[::-], covering events from car expos to local conflicts. While working, I graduated from the [::b]Moscow State University[::-], Department of Journalism (5-year degree).
* In 2015, I started [::b]teaching myself programming[::-], covering Python, C, Objective-C, and Swift. I went through Full-Stack Development Bootcamp at Le Wagon in Paris where I fell in love with [::b]Ruby on Rails[::-]. After my graduation, I moved to Amsterdam where I attended first two years of a Bachelor Degree in Computer Science at VU, spending time with C++ and Java.
* Since then, I've been working on various Rails applications for companies and private clients.
* I currently live and work in [::b]Berlin[::-], shaping the educational process at [::b]Le Wagon[::-] and writing Ruby, JavaScript, and Go code that allows our students to learn better. I am also managing [::b]Kubernetes[::-] deploys and set up local environments with [::b]Docker[::-].
`
const how = `[::bu]How it's built[::-] 👷‍♀️
* A Svelte front-end app uses Xterm.js to emulate terminal
* A Golang server establishes a Websocket connection to front-end
* An Alpine container starts in the backend
* A Golang binary in the container renders TUI
* Stdin and stdout of a container are piped back and forth through Websocket
The app is open-source, feel free to use it for your own inspiration: https://github.com/progapandist/progapanda.org
`
const why = `[::bu]But... Why?[::-] 🤔
I am obsessed with terminals and TUI programming, that's why!
To be serious though, this is a part of my research project for creating a highly scalable interactive learning environment for programming students.
This application is deployed on a single Digital Ocean VPS that is turned into a Kuberenetes cluster with k3s.
`
func main() {
app = tview.NewApplication()
textView = tview.NewTextView().
SetDynamicColors(true)
textView.SetBorder(true)
textView.SetBorderPadding(1, 1, 2, 1)
textView.SetWrap(true).SetWordWrap(true)
textView.SetBackgroundColor(tcell.Color19)
textView.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyESC {
app.SetFocus(menu)
}
return event
})
menu = tview.NewList().ShowSecondaryText(false)
menu.SetBorder(true).SetTitle("Menu")
menu.SetWrapAround(true).SetHighlightFullLine(true)
menu.SetBorderPadding(1, 1, 2, 1)
menu.SetSelectedBackgroundColor(tcell.ColorWhite)
menu.SetBackgroundColor(tcell.Color19)
menu.
AddItem(" [::b]Hello", "", 0, func() {
app.SetFocus(textView)
}).
AddItem(" [::b]CV", "", 0, func() {
app.SetFocus(textView)
}).
AddItem(" [::b]How", "", 0, func() {
app.SetFocus(textView)
}).
AddItem(" [::b]Why", "", 0, func() {
app.SetFocus(textView)
}).
AddItem(" [::b]Quit", "", 0, func() {
app.Stop()
})
menu.SetChangedFunc(func(i int, mt, st string, sc rune) {
switch i {
case 0:
printAbout()
case 1:
printCv()
case 2:
printHow()
case 3:
printWhy()
}
})
printAbout()
flex := tview.NewFlex().
AddItem(menu, 0, 1, true).
AddItem(textView, 0, 5, false)
flexFrame := tview.NewFrame(flex).
AddText(
" [::b](c) 2020, Andy B.[::-] [::b]Up/Down[::-]: Navigate, [::b]Enter[::-]: Open item, [::b]Esc[::-]: Back to Menu",
false,
tview.AlignLeft,
tcell.ColorWhite).
SetBorders(0, 1, 0, 0, 0, 0)
pages = tview.NewPages().
AddPage("layout", flexFrame, true, true)
app.SetRoot(pages, true).SetFocus(menu).EnableMouse(true).Run()
}
func printAbout() {
textView.Clear()
fmt.Fprintf(textView, "%s ", about)
textView.ScrollToBeginning()
textView.SetTitle("Hello")
}
func printCv() {
textView.Clear()
fmt.Fprintf(textView, "%s ", cv)
textView.SetTitle("CV")
}
func printHow() {
textView.Clear()
fmt.Fprintf(textView, "%s ", how)
textView.SetTitle("How")
}
func printWhy() {
textView.Clear()
fmt.Fprintf(textView, "%s ", why)
textView.SetTitle("Why")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment