~f4814n/frost

31059434029fcca2ea4da59e14941f9c955c76dc — Fabian Geiselhart 8 months ago 29d189d
platform: Split into own package
10 files changed, 296 insertions(+), 145 deletions(-)

M cmd/frost/main.go
D cmd/frost/platform.go
M go.mod
M go.sum
A platform/platform.go
R cmd/frost/platform_android.go => platform/platform_android.go
A platform/platform_default.go
R cmd/frost/platform_linux.go => platform/platform_linux.go
A platform/platform_macos.go
R cmd/frost/platform_windows.go => platform/platform_windows.go
M cmd/frost/main.go => cmd/frost/main.go +22 -19
@@ 13,6 13,7 @@ import (
	"gioui.org/widget/material"
	"git.sr.ht/~f4814n/frost"
	"git.sr.ht/~f4814n/frost/component/cache"
	"git.sr.ht/~f4814n/frost/platform"
	"git.sr.ht/~f4814n/frost/view/login"
	"git.sr.ht/~f4814n/frost/view/memberlist"
	"git.sr.ht/~f4814n/frost/view/roomhistory"


@@ 28,22 29,14 @@ type (
	Dims = layout.Dimensions
)

type AppConfig struct {
	Session *SessionConfig `json:"session"`
}

type SessionConfig struct {
	MxID     string `json:"mxid"`
	DeviceID string `json:"device_id"`
}

type App struct {
	window   *app.Window
	cli      *matrix.Client
	rx, tx   chan frost.Event
	config   AppConfig
	platform Platform
	config   platform.AppConfig
	platform platform.Platform
	logger   *zap.Logger
	cache    frost.Component

	mux *frost.Mux



@@ 52,21 45,32 @@ type App struct {
}

func newApp() *App {
	platform := InitPlatform()
	zap, _ := zap.NewDevelopment()
	return &App{
	platform, err := platform.Init()
	if err != nil {
		panic(err.Error())
	}

	backend := platform.Backend()
	logger := platform.Logger()
	platformCache := platform.Cache()

	a := &App{
		mux: frost.NewMux(),
		cli: matrix.NewClient(matrix.ClientOpts{
			HTTPClient: http.DefaultClient,
			Backend:    platform.NewBackend(),
			Backend:    backend,
		}),
		window: app.NewWindow(
			app.Size(unit.Dp(400), unit.Dp(800)),
			app.Title("Frost"),
		),
		platform: platform,
		logger:   zap.Named("frost"),
		logger:   logger.Named("frost"),
	}

	a.cache = cache.New(a.cli, platformCache, logger.Named("cache"))

	return a
}

func (a *App) run() error {


@@ 79,9 83,8 @@ func (a *App) run() error {
	a.tx = tx

	// Cache
	cache := cache.New(a.cli, a.platform.Cache, a.logger.Named("cache"))
	_, rx, tx = a.mux.Register()
	go cache.Run(rx, tx)
	go a.cache.Run(rx, tx)

	matrixEvents := make(chan matrix.Event, 100)
	a.cli.Notify(matrixEvents)


@@ 241,7 244,7 @@ func (a *App) login(event login.StartEvent) {
	}
	a.logger.Debug("Successfully authenticated")

	a.config.Session = &SessionConfig{
	a.config.Session = &platform.SessionConfig{
		MxID:     a.cli.MxID(),
		DeviceID: a.cli.DeviceID(),
	}

D cmd/frost/platform.go => cmd/frost/platform.go +0 -36
@@ 1,36 0,0 @@
//+build !linux,!android,!windows

package main

import (
	"git.sr.ht/~f4814n/matrix"
	backend "git.sr.ht/~f4814n/matrix/backend/memory"
	"git.sr.ht/~f4814n/matrix/util/cache"
	"github.com/sirupsen/logrus"
)

// This is the fallback platform. It does not support persisting information. It does not require cgo
type Platform struct {
	Logger *logrus.Logger
	Cache  cache.Cache
}

func InitPlatform() Platform {
	return Platform{
		Cache:  new(cache.MemoryCache),
		Logger: logrus.New(),
	}
}

func (p Platform) LoadConfig() (cfg AppConfig, err error) {
	p.Logger.WithField("component", "platform").Warn("This platform does not support persisting information")
	return
}

func (p Platform) FlushConfig(cfg AppConfig) error {
	return nil
}

func (p Platform) NewBackend() matrix.Backend {
	return backend.New()
}

M go.mod => go.mod +1 -3
@@ 5,7 5,7 @@ go 1.14
require (
	gioui.org v0.0.0-20201018162216-7a4b48f67b54
	gioui.org/cmd v0.0.0-20201020094634-d5bdf0756a5a
	git.sr.ht/~f4814n/matrix v0.0.0-20201215165513-ab5355096a5a
	git.sr.ht/~f4814n/matrix v0.0.0-20201218143803-770e10bd6252
	github.com/sirupsen/logrus v1.7.0
	go.uber.org/zap v1.16.0
	golang.org/x/exp v0.0.0-20201008143054-e3b2a7f2fdc7


@@ 18,5 18,3 @@ require (
	gopkg.in/yaml.v2 v2.2.4 // indirect
	honnef.co/go/tools v0.1.0 // indirect
)

replace git.sr.ht/~f4814n/matrix => ../matrix

M go.sum => go.sum +4 -0
@@ 4,6 4,10 @@ gioui.org v0.0.0-20201018162216-7a4b48f67b54 h1:mM+tSH6C2GBkaErKviXhGL22qiGNgUMu
gioui.org v0.0.0-20201018162216-7a4b48f67b54/go.mod h1:Y+uS7hHMvku1Q+ooaoq6fYD5B2LGoT8JtFgvmYmRzTw=
gioui.org/cmd v0.0.0-20201020094634-d5bdf0756a5a h1:BPgJqeQSxuX6CzFQ2EGDj4Kr2ZzwiqwdLyAYLXgxR+k=
gioui.org/cmd v0.0.0-20201020094634-d5bdf0756a5a/go.mod h1:dlmJnCEkOpRaChYxRmJZ5S4jk6y7DCfWnec39xGbUYk=
git.sr.ht/~f4814n/matrix v0.0.0-20201215165513-ab5355096a5a h1:ajvU++oT9ggUUqPQ4LuNTv2BbZoWtbytZTkfPl4fZWA=
git.sr.ht/~f4814n/matrix v0.0.0-20201215165513-ab5355096a5a/go.mod h1:yR3YNkJR8S3qLkGh178oKRm3MnsT5cERNEXOF8eFOIo=
git.sr.ht/~f4814n/matrix v0.0.0-20201218143803-770e10bd6252 h1:82PU+gyoqJQWqdCZ5aefQ0YtIbcTlpCGQ1366UEChpc=
git.sr.ht/~f4814n/matrix v0.0.0-20201218143803-770e10bd6252/go.mod h1:yR3YNkJR8S3qLkGh178oKRm3MnsT5cERNEXOF8eFOIo=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=

A platform/platform.go => platform/platform.go +26 -0
@@ 0,0 1,26 @@
// Package platform contains all platform specific code in frost.
package platform

import (
	"git.sr.ht/~f4814n/matrix"
	"git.sr.ht/~f4814n/matrix/util/cache"
	"go.uber.org/zap"
)

type AppConfig struct {
	Session *SessionConfig `json:"session"`
}

type SessionConfig struct {
	MxID     string `json:"mxid"`
	DeviceID string `json:"device_id"`
}

type Platform interface {
	Backend() matrix.Backend
	Cache() cache.Cache
	Logger() *zap.Logger

	LoadConfig() (AppConfig, error)
	FlushConfig(AppConfig) error
}

R cmd/frost/platform_android.go => platform/platform_android.go +34 -32
@@ 1,51 1,57 @@
// +build android

package main
package platform

import (
	"encoding/json"
	"os"

	"git.sr.ht/~f4814n/matrix"
	backend "git.sr.ht/~f4814n/matrix/backend/sqlite"
	"git.sr.ht/~f4814n/matrix/util/cache"
	"github.com/sirupsen/logrus"
	"os"
	"go.uber.org/zap"
)

var (
	baseDir        = "/data/data/de.f4814n.frost"
	dataDir        = baseDir + "/data"
	configFilePath = baseDir + "/config.json"
	cacheDir       = baseDir + "/cache"
)
type platformAndroid struct {
	dataDir, cacheDir, configFilePath string
}

func Init() (Platform, error) {
	baseDir := "/data/data/de.f4814n.frost"
	dataDir := baseDir + "/data"
	cacheDir := baseDir + "/cache"
	configFilePath := baseDir + "/config.json"

type Platform struct {
	Logger *logrus.Logger
	Cache  cache.Cache
	return platformAndroid{
		dataDir:        dataDir,
		cacheDir:       cacheDir,
		configFilePath: configFilePath,
	}, nil
}

func InitPlatform() Platform {
	// Create Cache
	cache, err := cache.NewFSCache(cacheDir)
func (p platformAndroid) Backend() matrix.Backend {
	return backend.New(p.dataDir)
}

func (p platformAndroid) Cache() cache.Cache {
	cache, err := cache.NewFSCache(p.cacheDir)
	if err != nil {
		// XXX Fallback to memory cache, warn
		panic(err.Error())
	}

	// Initialize Logfile
	logFile, err := os.OpenFile(baseDir+"/frost.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	return cache
}

func (p platformAndroid) Logger() *zap.Logger {
	logger, err := zap.NewDevelopment()
	if err != nil {
		panic(err.Error())
	}

	log := logrus.New()
	log.SetLevel(logrus.DebugLevel)
	log.Out = logFile

	return Platform{Cache: cache, Logger: log}
	return logger
}

func (p Platform) LoadConfig() (cfg AppConfig, err error) {
	f, err := os.Open(configFilePath)
func (p platformAndroid) LoadConfig() (cfg AppConfig, err error) {
	f, err := os.Open(p.configFilePath)
	if err != nil {
		return
	}


@@ 54,8 60,8 @@ func (p Platform) LoadConfig() (cfg AppConfig, err error) {
	return
}

func (p Platform) FlushConfig(cfg AppConfig) (err error) {
	f, err := os.Create(configFilePath)
func (p platformAndroid) FlushConfig(cfg AppConfig) (err error) {
	f, err := os.Create(p.configFilePath)
	if err != nil {
		return
	}


@@ 63,7 69,3 @@ func (p Platform) FlushConfig(cfg AppConfig) (err error) {
	err = json.NewEncoder(f).Encode(cfg)
	return
}

func (p Platform) NewBackend() matrix.Backend {
	return backend.New(dataDir)
}

A platform/platform_default.go => platform/platform_default.go +43 -0
@@ 0,0 1,43 @@
//+build !linux,!windows,!android

package platform

import (
	"git.sr.ht/~f4814n/matrix"
	backend "git.sr.ht/~f4814n/matrix/backend/memory"
	"git.sr.ht/~f4814n/matrix/util/cache"
	"go.uber.org/zap"
)

type platformDefault struct {
	logger *zap.Logger
}

func Init() (Platform, error) {
	logger, err := zap.NewDevelopment()
	return platformDefault{
		logger: logger,
	}, err
}

func (p platformDefault) Backend() matrix.Backend {
	return backend.New()
}

func (p platformDefault) Cache() cache.Cache {
	return new(cache.MemoryCache)
}

func (p platformDefault) Logger() *zap.Logger {
	return p.logger
}

func (p platformDefault) LoadConfig() (AppConfig, error) {
	p.logger.Named("platform").Warn("This Platform does not support persisting information")
	return AppConfig{}, nil
}

func (p platformDefault) FlushConfig(AppConfig) error {
	p.logger.Named("platform").Warn("This Platform does not support persisting information")
	return nil
}

R cmd/frost/platform_linux.go => platform/platform_linux.go +43 -28
@@ 1,48 1,67 @@
// +build linux,!android
//+build linux,!android

package main
package platform

import (
	"encoding/json"
	"fmt"
	"os"

	"git.sr.ht/~f4814n/matrix"
	backend "git.sr.ht/~f4814n/matrix/backend/sqlite"
	"git.sr.ht/~f4814n/matrix/util/cache"
	"github.com/sirupsen/logrus"
	"os"
)

var (
	dataDir        = fmt.Sprintf("%s/frost", getenv("XDG_DATA_HOME", "~/.local/share"))
	cacheDir       = fmt.Sprintf("%s/frost", getenv("XDG_CACHE_HOME", "~/.cache"))
	configFilePath = dataDir + "/config.json"
	"go.uber.org/zap"
)

type Platform struct {
	Logger *logrus.Logger
	Cache  cache.Cache
type platformLinux struct {
	dataDir, cacheDir, configFilePath string
}

func InitPlatform() Platform {
	// Create b.Path directory
func Init() (Platform, error) {
	dataDir := fmt.Sprintf("%s/frost", getenv("XDG_DATA_HOME", "~/.local/share"))
	cacheDir := fmt.Sprintf("%s/frost", getenv("XDG_CACHE_HOME", "~/.cache"))
	configFilePath := dataDir + "/config.json"

	// Create dataDir
	if _, err := os.Stat(dataDir); os.IsNotExist(err) {
		os.Mkdir(dataDir, os.ModePerm) // XXX Correct permissions
		err := os.Mkdir(dataDir, os.ModePerm) // XXX Correct permissions
		if err != nil {
			return nil, err
		}
	}

	// Create Cache
	cache, err := cache.NewFSCache(cacheDir)
	return platformLinux{
		dataDir:        dataDir,
		cacheDir:       cacheDir,
		configFilePath: configFilePath,
	}, nil
}

func (p platformLinux) Backend() matrix.Backend {
	return backend.New(p.dataDir)
}

func (p platformLinux) Cache() cache.Cache {
	cache, err := cache.NewFSCache(p.cacheDir)
	if err != nil {
		// XXX Fallback to memory cache, warn
		panic(err.Error())
	}

	logrus.SetLevel(logrus.DebugLevel)
	return cache
}

func (p platformLinux) Logger() *zap.Logger {
	logger, err := zap.NewDevelopment()
	if err != nil {
		panic(err.Error())
	}

	return Platform{Cache: cache, Logger: logrus.New()}
	return logger
}

func (p Platform) LoadConfig() (cfg AppConfig, err error) {
	f, err := os.Open(configFilePath)
func (p platformLinux) LoadConfig() (cfg AppConfig, err error) {
	f, err := os.Open(p.configFilePath)
	if err != nil {
		return
	}


@@ 51,8 70,8 @@ func (p Platform) LoadConfig() (cfg AppConfig, err error) {
	return
}

func (p Platform) FlushConfig(cfg AppConfig) (err error) {
	f, err := os.Create(configFilePath)
func (p platformLinux) FlushConfig(cfg AppConfig) (err error) {
	f, err := os.Create(p.configFilePath)
	if err != nil {
		return
	}


@@ 61,10 80,6 @@ func (p Platform) FlushConfig(cfg AppConfig) (err error) {
	return
}

func (p Platform) NewBackend() matrix.Backend {
	return backend.New(dataDir)
}

func getenv(key, fallback string) (res string) {
	if val, ok := os.LookupEnv(key); ok {
		res = val

A platform/platform_macos.go => platform/platform_macos.go +80 -0
@@ 0,0 1,80 @@
//+build macos

package platform

import (
	"encoding/json"
	"os"

	"git.sr.ht/~f4814n/matrix"
	backend "git.sr.ht/~f4814n/matrix/backend/sqlite"
	"git.sr.ht/~f4814n/matrix/util/cache"
	"go.uber.org/zap"
)

type platforMacOS struct {
	dataDir, cacheDir, configFilePath string
}

func Init() (Platform, error) {
	dataDir := "~/Library/Preferences/f4814n/frost"
	cacheDir := "~/Library/Caches/f4814n/frost"
	configFilePath := dataDir + "/config.json"

	// Create dataDir
	if _, err := os.Stat(dataDir); os.IsNotExist(err) {
		err := os.Mkdir(dataDir, os.ModePerm) // XXX Correct permissions
		if err != nil {
			return nil, err
		}
	}

	return platforMacOS{
		dataDir:        dataDir,
		cacheDir:       cacheDir,
		configFilePath: configFilePath,
	}, nil
}

func (p platforMacOS) Backend() matrix.Backend {
	return backend.New(p.dataDir)
}

func (p platforMacOS) Cache() cache.Cache {
	cache, err := cache.NewFSCache(p.cacheDir)
	if err != nil {
		// XXX Fallback to memory cache, warn
		panic(err.Error())
	}

	return cache
}

func (p platforMacOS) Logger() *zap.Logger {
	logger, err := zap.NewDevelopment()
	if err != nil {
		panic(err.Error())
	}

	return logger
}

func (p platforMacOS) LoadConfig() (cfg AppConfig, err error) {
	f, err := os.Open(p.configFilePath)
	if err != nil {
		return
	}

	err = json.NewDecoder(f).Decode(&cfg)
	return
}

func (p platforMacOS) FlushConfig(cfg AppConfig) (err error) {
	f, err := os.Create(p.configFilePath)
	if err != nil {
		return
	}

	err = json.NewEncoder(f).Encode(cfg)
	return
}

R cmd/frost/platform_windows.go => platform/platform_windows.go +43 -27
@@ 1,55 1,75 @@
// +build windows

package main
package platform

import (
	"encoding/json"
	"fmt"
	"os"

	"git.sr.ht/~f4814n/matrix"
	backend "git.sr.ht/~f4814n/matrix/backend/sqlite"
	"git.sr.ht/~f4814n/matrix/util/cache"
	"github.com/sirupsen/logrus"
	"os"
	"go.uber.org/zap"
)

type Platform struct {
	cacheDir, dataDir, configFile string

	Logger *logrus.Logger
	Cache  cache.Cache
type platformWindows struct {
	dataDir, cacheDir, configFilePath string
}

func InitPlatform() Platform {
func Init() (Platform, error) {
	dataDir, err := os.UserConfigDir()
	if err != nil {
		panic(err.Error())
		return err
	}
	dataDir += "\\frost"

	cacheDir, err := os.UserCacheDir()
	if err != nil {
		panic(err.Error())
		return err
	}
	cacheDir += "\\frost"

	configFile := dataDir + "/config.json"
	configFilePath := dataDir + "/config.json"

	// Create b.Path directory
	// Create dataDir
	if _, err := os.Stat(dataDir); os.IsNotExist(err) {
		os.Mkdir(dataDir, os.ModePerm) // XXX Correct permissions
		err := os.Mkdir(dataDir, os.ModePerm) // XXX Correct permissions
		if err != nil {
			return nil, err
		}
	}

	// Create Cache
	cache, err := cache.NewFSCache(cacheDir)
	return platformWindows{
		dataDir:        dataDir,
		cacheDir:       cacheDir,
		configFilePath: configFilePath,
	}, nil
}

func (p platformWindows) Backend() matrix.Backend {
	return backend.New(p.dataDir)
}

func (p platformWindows) Cache() cache.Cache {
	cache, err := cache.NewFSCache(p.cacheDir)
	if err != nil {
		// XXX Fallback to memory cache, warn
		panic(err.Error())
	}

	return Platform{Cache: cache, cacheDir: cacheDir, dataDir: dataDir, configFile: configFile, Logger: logrus.New()}
	return cache
}

func (p platformWindows) Logger() *zap.Logger {
	logger, err := zap.NewDevelopment()
	if err != nil {
		panic(err.Error())
	}

	return logger
}

func (p Platform) LoadConfig() (cfg AppConfig, err error) {
	f, err := os.Open(p.configFile)
func (p platformWindows) LoadConfig() (cfg AppConfig, err error) {
	f, err := os.Open(p.configFilePath)
	if err != nil {
		return
	}


@@ 58,8 78,8 @@ func (p Platform) LoadConfig() (cfg AppConfig, err error) {
	return
}

func (p Platform) FlushConfig(cfg AppConfig) (err error) {
	f, err := os.Create(p.configFile)
func (p platformWindows) FlushConfig(cfg AppConfig) (err error) {
	f, err := os.Create(p.configFilePath)
	if err != nil {
		return
	}


@@ 67,7 87,3 @@ func (p Platform) FlushConfig(cfg AppConfig) (err error) {
	err = json.NewEncoder(f).Encode(cfg)
	return
}

func (p Platform) NewBackend() matrix.Backend {
	return backend.New(p.dataDir)
}