M main.go => main.go +27 -28
@@ 6,19 6,18 @@ import (
"strings"
_ "time"
- _ "humungus.tedunangst.com/r/go-sqlite3"
- "golang.org/x/term"
"github.com/muesli/termenv"
+ "golang.org/x/term"
+ _ "humungus.tedunangst.com/r/go-sqlite3"
)
// Our widgets are global so anyone can print to them easily
var (
statusBar *Widget
- s *ScrollView
- inputBar *Widget
+ s *ScrollView
+ inputBar *Widget
)
-
func (account *Account) readSettings() {
var err error
@@ 27,7 26,7 @@ func (account *Account) readSettings() {
if err != nil {
s.Printf("Cannot open database: %s\n", err)
}
- // SelectOne/QueryRow can't stay, we need a proper way to handle multi-account support.
+ // SelectOne/QueryRow can't stay, we need a proper way to handle multi-account support.
row := db.QueryRow("SELECT username, server_URL, access_token FROM accounts")
// defer row.Close() // QueryRow has no close(), only the plural does
err = row.Scan(&account.UserName, &account.Server.URL, &account.AccessToken)
@@ 51,47 50,47 @@ func main() {
defer term.Restore(int(os.Stdin.Fd()), oldState)
// Get screen size
- // TODO: put this in an update. SIGWINCH?
+ // TODO: put this in an update. SIGWINCH?
_, h, _ := term.GetSize(int(os.Stdin.Fd()))
// Status bar
statusBar = &Widget{
- Height: 1,
+ Height: 1,
YPosition: 1,
- Cursor: Pos{1, 1},
+ Cursor: Pos{1, 1},
}
statusBar.Printf("Matt tricks client")
// Input bar
inputBar = &Widget{
- Height: 1,
+ Height: 1,
YPosition: h,
- Cursor: Pos{1, 1},
+ Cursor: Pos{1, 1},
}
inputBar.Focus()
// Scroll view
- s = NewScrollView(2, h - 2)
+ s = NewScrollView(2, h-2)
- // Grab our two channels to catch events on.
+ // Grab our two channels to catch events on.
lineEvents, keyEvents := Readline()
- // Read our account out of the database.
+ // Read our account out of the database.
account.readSettings()
// Scrolling test
/*
- go func() {
- i := 0
- for {
- i++
- s.Printf("%d", i)
- time.Sleep(1000 * time.Millisecond)
- }
- }()
+ go func() {
+ i := 0
+ for {
+ i++
+ s.Printf("%d", i)
+ time.Sleep(1000 * time.Millisecond)
+ }
+ }()
*/
- // Key events. Handle all the typing/keybinds here.
+ // Key events. Handle all the typing/keybinds here.
go func() {
for {
ev := <-keyEvents
@@ 124,8 123,8 @@ func main() {
continue
}
- // And anything starting with a slash should be a command.
- // Catch non-existent commands rather than send them (possible leak).
+ // And anything starting with a slash should be a command.
+ // Catch non-existent commands rather than send them (possible leak).
command := strings.Split(line, " ")
switch command[0] {
case "/quit":
@@ 151,9 150,9 @@ func main() {
for _, room := range roomList {
alias, _ := account.GetRoomAlias(room.ID)
/*
- if err != nil {
- s.Printf("%v", err)
- }
+ if err != nil {
+ s.Printf("%v", err)
+ }
*/
s.Printf("[%s] - %s", room.ID, alias)
}
M matt_tricks.go => matt_tricks.go +37 -39
@@ 2,65 2,65 @@ package main
import (
"bytes"
- "io"
"encoding/json"
"fmt"
+ "io"
"net/http"
)
// Account data structures
type Server struct {
- URL string
- IdentityServer string
+ URL string
+ IdentityServer string
}
type Room struct {
- ID string
- Name string
+ ID string
+ Name string
}
type Account struct {
- UserName string
- MatrixID string
- AccessToken string
- DeviceID string
- Server Server
- Rooms []Room
+ UserName string
+ MatrixID string
+ AccessToken string
+ DeviceID string
+ Server Server
+ Rooms []Room
http.Client
}
func (account *Account) Login(password string) error {
var resp struct {
- AccessToken string `json:"access_token"`
- DeviceID string `json:"device_id"`
- UserID string `json:"user_id"`
- WellKnown struct {
- HomeServer struct {
- BaseURL string `json:"base_url"`
- } `json:"m.homeserver"`
- IdentServer struct {
- BaseURL string `json:"base_url"`
- } `json:"m.identity_server"`
- } `json:"well_known"`
+ AccessToken string `json:"access_token"`
+ DeviceID string `json:"device_id"`
+ UserID string `json:"user_id"`
+ WellKnown struct {
+ HomeServer struct {
+ BaseURL string `json:"base_url"`
+ } `json:"m.homeserver"`
+ IdentServer struct {
+ BaseURL string `json:"base_url"`
+ } `json:"m.identity_server"`
+ } `json:"well_known"`
}
requestBody, err := json.Marshal(&struct {
- Identifier struct {
- Type string `json:"type"`
- User string `json:"user"`
- } `json:"identifier"`
- Type string `json:"type"`
- Password string `json:"password"`
+ Identifier struct {
+ Type string `json:"type"`
+ User string `json:"user"`
+ } `json:"identifier"`
+ Type string `json:"type"`
+ Password string `json:"password"`
}{
Identifier: struct {
- Type string `json:"type"`
- User string `json:"user"`
+ Type string `json:"type"`
+ User string `json:"user"`
}{
Type: "m.id.user",
User: account.UserName,
},
- Type: "m.login.password",
+ Type: "m.login.password",
Password: password,
})
if err != nil {
@@ 91,10 91,10 @@ func (account *Account) GetRooms() ([]Room, error) {
return nil, err
}
- // TODO: Merge our room list somehow to we don't fall out of sync.
+ // TODO: Merge our room list somehow to we don't fall out of sync.
var rooms []Room
- for _,roomId := range resp.JoinedRooms {
- room := Room{ ID: roomId }
+ for _, roomId := range resp.JoinedRooms {
+ room := Room{ID: roomId}
rooms = append(rooms, room)
}
@@ 106,7 106,7 @@ func (account *Account) GetRoomAlias(roomId string) (string, error) {
Alias string `json:"alias"`
}
- err := account.get("/_matrix/client/v3/rooms/" + roomId + "/state/m.room.canonical_alias", &resp)
+ err := account.get("/_matrix/client/v3/rooms/"+roomId+"/state/m.room.canonical_alias", &resp)
if err != nil {
return "", err
}
@@ 114,8 114,6 @@ func (account *Account) GetRoomAlias(roomId string) (string, error) {
return resp.Alias, nil
}
-
-
// HTTP client helper functions
// Inspiration taken from the Decred wallet http client implementation
// https://github.com/decred/dcrwallet/blob/master/internal/vsp/client.go
@@ 137,8 135,8 @@ func (a *Account) do(method, path string, resp, req interface{}) error {
}
reqBody = bytes.NewReader(body)
}
- httpReq, err := http.NewRequest(method, a.Server.URL + path +
- "?access_token=" + a.AccessToken, reqBody)
+ httpReq, err := http.NewRequest(method, a.Server.URL+path+
+ "?access_token="+a.AccessToken, reqBody)
if err != nil {
return fmt.Errorf("New request: %w", err)
}
M noisy_lines.go => noisy_lines.go +7 -6
@@ 12,6 12,7 @@ type KeyEvent struct {
Key Key
Ch rune
}
+
var KeyChan chan KeyEvent
var Line strings.Builder
@@ 90,8 91,8 @@ const (
KeyDEL Key = 0x7F
)
-// Named keys.
-// KeyRune is not a real key, but used to signify a printable character as in tcell.
+// Named keys.
+// KeyRune is not a real key, but used to signify a printable character as in tcell.
const (
KeyRune Key = iota + 0x100
KeyUp
@@ 218,7 219,7 @@ func GetKey() KeyEvent {
break
}
- // One of the control keys
+ // One of the control keys
ev.Key = Key(b[0])
}
@@ 236,17 237,17 @@ func Readline() (<-chan string, <-chan KeyEvent) {
case KeyNone:
break
case KeyRune:
- // Send a key event (KeyRune) for the client to display.
+ // Send a key event (KeyRune) for the client to display.
KeyChan <- ev
Line.WriteRune(ev.Ch)
case KeyEnter:
// Shove the current line down the pipe
LineChan <- Line.String()
- // Let the pipe know there was an enter event.
+ // Let the pipe know there was an enter event.
// This can be safely ignored, or used to separate drawing logic
KeyChan <- ev
// Reset our line contents
- // TODO: Lock me?
+ // TODO: Lock me?
Line.Reset()
default:
// Send all non-editing events down the pipe
M widgets.go => widgets.go +11 -11
@@ 7,19 7,19 @@ import (
"github.com/muesli/termenv"
)
-// Our shared printing mutex.
+// Our shared printing mutex.
// Don't steal the cursor while another routing is moving it.
var PrintMutex sync.Mutex
type Pos struct {
- Col int
- Row int
+ Col int
+ Row int
}
type Widget struct {
- Height int
- YPosition int
- Cursor Pos
+ Height int
+ YPosition int
+ Cursor Pos
}
/*
@@ 32,11 32,11 @@ type ScrollView struct {
type ScrollView Widget
func NewScrollView(yposition int, height int) *ScrollView {
- // Init the cursor to row 0
+ // Init the cursor to row 0
s := ScrollView{
- Height: height,
+ Height: height,
YPosition: yposition,
- Cursor: Pos{1, 0},
+ Cursor: Pos{1, 0},
}
s.UpdateSize(yposition, height)
@@ 56,7 56,7 @@ func (s *ScrollView) UpdateSize(yposition int, height int) {
s.Height = height
s.YPosition = yposition
- termenv.ChangeScrollingRegion(yposition, height + 1)
+ termenv.ChangeScrollingRegion(yposition, height+1)
// TODO: Adjust cursor to put it back inside the ScrollView
}
@@ 81,7 81,7 @@ func (s *ScrollView) Printf(format string, a ...interface{}) {
}
// Move to the current line on the ScrollView.
- termenv.MoveCursor(s.YPosition + s.Cursor.Row - 1, s.Cursor.Col)
+ termenv.MoveCursor(s.YPosition+s.Cursor.Row-1, s.Cursor.Col)
fmt.Printf(format, a...)
}