This repository has been archived on 2021-06-24. You can view files and clone it, but cannot push or open issues or pull requests.
ui/main.go

216 lines
6.0 KiB
Go
Raw Normal View History

2018-10-23 18:52:13 +00:00
package main
import (
2018-11-22 00:01:17 +00:00
libapp "cwtch.im/cwtch/app"
2018-11-28 22:14:02 +00:00
"cwtch.im/ui/go/characters"
"cwtch.im/ui/go/gobjects"
"cwtch.im/ui/go/gothings"
2019-05-03 18:28:11 +00:00
"cwtch.im/ui/go/gothings/android"
2018-11-28 22:14:02 +00:00
"cwtch.im/ui/go/the"
2019-03-25 19:10:46 +00:00
"flag"
2018-11-28 22:14:02 +00:00
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
2018-11-28 22:14:02 +00:00
"github.com/therecipe/qt/core"
2019-03-18 23:52:46 +00:00
"github.com/therecipe/qt/gui"
2019-01-28 22:00:46 +00:00
"github.com/therecipe/qt/network"
"github.com/therecipe/qt/qml"
2018-10-25 00:13:03 +00:00
"github.com/therecipe/qt/quickcontrols2"
"os"
2019-03-18 23:52:46 +00:00
"os/user"
2018-10-25 00:13:03 +00:00
"path"
"path/filepath"
2019-03-18 23:52:46 +00:00
"runtime"
2019-05-09 21:45:02 +00:00
"time"
2018-10-28 02:49:14 +00:00
)
2018-10-23 18:52:13 +00:00
2019-04-08 21:01:53 +00:00
const androidBaseDir = "/data/data/ca.openprivacy.cwtch.ui/"
2019-02-19 21:32:52 +00:00
var (
buildVer string
buildDate string
)
2018-11-22 00:01:17 +00:00
func init() {
// make go-defined types available in qml
gothings.GrandCentralDispatcher_QmlRegisterType2("CustomQmlTypes", 1, 0, "GrandCentralDispatcher")
2018-10-23 18:52:13 +00:00
}
2018-11-22 00:01:17 +00:00
func main() {
2019-05-09 21:45:02 +00:00
log.Infoln("ui main()\n")
2019-03-25 19:10:46 +00:00
flagDebug := flag.Bool("debug", false, "turn on extra logging. WARNING: THIS MAY EXPOSE PRIVATE INFORMATION IN CONSOLE OUTPUT!")
flagLocal := flag.Bool("local", false, "load user interface from the local folder \"qml\" instead of the built-in UI")
2019-05-09 21:45:02 +00:00
flagService := flag.Bool("service", false, "indicate this process should run as an android service")
2019-03-25 19:10:46 +00:00
flag.Parse()
2019-03-25 19:10:46 +00:00
if *flagDebug {
log.SetLevel(log.LevelDebug)
} else {
log.SetLevel(log.LevelInfo)
}
if os.Getenv("CWTCH_FOLDER") != "" {
the.CwtchDir = os.Getenv("CWTCH_FOLDER")
} else if runtime.GOOS == "android" {
the.CwtchDir = path.Join(androidBaseDir, "files")
2019-02-14 02:53:36 +00:00
} else {
usr, err := user.Current()
if err != nil {
log.Errorf("\nerror: could not load current user: %v\n", err)
os.Exit(1)
2019-05-09 21:45:02 +00:00
}
the.CwtchDir = path.Join(usr.HomeDir, ".cwtch")
}
the.ACN = nil
2019-05-09 21:45:02 +00:00
if *flagService {
mainService()
} else {
mainUi(*flagLocal)
}
2019-05-09 21:45:02 +00:00
if the.ACN != nil {
the.ACN.Close()
}
}
2019-05-09 21:45:02 +00:00
func mainService() {
log.Infoln("I am the service")
loadACN()
log.Infoln("Starting a cwtch app...")
the.CwtchApp = libapp.NewApp(the.ACN, the.CwtchDir)
log.Infoln("Sleepinging???")
for true {
time.Sleep(5 * time.Second)
log.Infoln("Wake up, repeat")
}
}
2019-05-09 21:45:02 +00:00
func mainUi(flagLocal bool) {
log.Infoln("I am the application")
2019-05-09 21:45:02 +00:00
app := gui.NewQGuiApplication(len(os.Args), os.Args)
2019-05-09 21:45:02 +00:00
// our globals
gcd := gothings.NewGrandCentralDispatcher(nil)
gcd.SetOs(runtime.GOOS)
if buildVer != "" {
gcd.SetVersion(buildVer)
gcd.SetBuildDate(buildDate)
} else {
gcd.SetVersion("development")
gcd.SetBuildDate("now")
2019-05-09 21:45:02 +00:00
}
gcd.UIState = gothings.NewUIState(gcd)
the.AcknowledgementIDs = make(map[string][]*the.AckId)
gcd.OutgoingMessages = make(chan gobjects.Letter, 1000)
//TODO: put theme stuff somewhere better
gcd.SetThemeScale(1.0)
// this is to load local qml files quickly when developing
var qmlSource *core.QUrl
if flagLocal {
qmlSource = core.QUrl_FromLocalFile("./qml/main.qml")
} else {
qmlSource = core.NewQUrl3("qrc:/qml/main.qml", 0)
}
2018-10-23 18:52:13 +00:00
app.SetWindowIcon(gui.NewQIcon5(":/qml/images/cwtch-icon.png"))
// load english first so it becomes the default in case we don't have a .ts for the user's locale, or if it contains unfinished strings
translator := core.NewQTranslator(nil)
translator.Load("translation_en", ":/i18n/", "", "")
core.QCoreApplication_InstallTranslator(translator)
gcd.Translator = core.NewQTranslator(nil)
gcd.Translator.Load("translation_"+core.QLocale_System().Name(), ":/i18n/", "", "")
core.QCoreApplication_InstallTranslator(gcd.Translator)
core.QCoreApplication_SetAttribute(core.Qt__AA_EnableHighDpiScaling, true)
quickcontrols2.QQuickStyle_SetStyle("Universe")
engine := qml.NewQQmlApplicationEngine(nil)
gcd.QMLEngine = engine
// prevent qt from initiating network connections (possible deanon attempts!)
factory := qml.NewQQmlNetworkAccessManagerFactory()
factory.ConnectCreate(func(parent *core.QObject) *network.QNetworkAccessManager {
nam := network.NewQNetworkAccessManager(parent)
nam.SetNetworkAccessible(network.QNetworkAccessManager__NotAccessible)
proxy := network.NewQNetworkProxy()
proxy.SetHostName("0.0.0.0")
nam.SetProxy(proxy)
//nam.ConnectCreateRequest(func(op network.QNetworkAccessManager__Operation, originalReq *network.QNetworkRequest, outgoingData *core.QIODevice) *network.QNetworkReply {
// log.Errorf("network access request detected - possible remote content insertion bug!!!")
// return nil
//})
return nam
})
engine.SetNetworkAccessManagerFactory(factory)
// variables we want to access from inside qml
if runtime.GOOS == "android" {
gcd.SetThemeScale(2.9)
} else {
gcd.SetThemeScale(1.0)
}
engine.RootContext().SetContextProperty("gcd", gcd)
var androidCwtchActivity = android.NewCwtchActivity(nil)
engine.RootContext().SetContextProperty("androidCwtchActivity", androidCwtchActivity)
//engine.addImportPath(QStringLiteral("qrc:/"));
//engine.load(QUrl(QStringLiteral("qrc:/source/qml/main.qml")));
engine.Load(qmlSource)
go loadNetworkingAndFiles(gcd)
app.Exec()
}
func loadACN() {
2019-02-14 02:53:36 +00:00
torpath := "tor"
if runtime.GOOS == "android" {
2019-02-19 21:32:52 +00:00
torpath = path.Join(androidBaseDir, "lib/libtor.so")
} else {
dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
if _, err := os.Stat(path.Join(dir, "tor")); os.IsNotExist(err) {
if _, err := os.Stat(path.Join(dir, "deploy", "linux", "tor")); os.IsNotExist(err) {
if _, err := os.Stat(path.Join(dir, "deploy", "windows", "tor")); os.IsNotExist(err) {
log.Warnln("Cannot find bundled Tor")
} else {
torpath = path.Join(dir, "deploy", "windows", "tor")
}
} else {
torpath = path.Join(dir, "deploy", "linux", "tor")
}
} else {
torpath = path.Join(dir, "tor")
}
2019-02-14 02:53:36 +00:00
}
var err error
the.ACN, err = connectivity.StartTor(the.CwtchDir, torpath)
if err != nil {
log.Errorf("Could not start Tor: %v", err)
os.Exit(1)
}
}
func loadNetworkingAndFiles(gcd *gothings.GrandCentralDispatcher) {
if runtime.GOOS != "android" {
loadACN()
}
the.Peer = nil
2018-11-22 00:01:17 +00:00
os.MkdirAll(the.CwtchDir, 0700)
the.CwtchApp = libapp.NewApp(the.ACN, the.CwtchDir)
the.AppBus = the.CwtchApp.GetPrimaryBus()
go characters.AppEventListener(gcd)
the.CwtchApp.LoadProfiles("be gay do crime")
2018-11-28 22:14:02 +00:00
}