diff --git a/.gitignore b/.gitignore index 0e7f8c5..2d8a696 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ deploy/ rcc.cpp rcc_cgo_linux_linux_amd64.go +moc* +rcc.qrc *~ *.autosave diff --git a/BlueBox.qml b/BlueBox.qml deleted file mode 100644 index 760dd53..0000000 --- a/BlueBox.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - - -Box { - color: "#157efb" -} diff --git a/Box.qml b/Box.qml deleted file mode 100644 index 6ee4522..0000000 --- a/Box.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width: 64 - height: 64 - color: "#ffffff" - border.color: Qt.darker(color, 1.2) - property alias text: label.text - property color fontColor: '#1f1f1f' - Text { - id: label - anchors.centerIn: parent - font.pixelSize: 14 - color: root.fontColor - } -} diff --git a/README.md b/README.md new file mode 100644 index 0000000..66f6fd0 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# qt Cwtch Bulletin + +## Building + +You need Go, QT (plus dev tools) and the GO QT dev tools from https://github.com/therecipe/qt + + qtdeploy diff --git a/assets/cwtch-logo.png b/assets/cwtch-logo.png new file mode 100644 index 0000000..9d3c7fe Binary files /dev/null and b/assets/cwtch-logo.png differ diff --git a/main.go b/main.go index 4b12096..ed2bb27 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,72 @@ import ( "github.com/therecipe/qt/gui" "github.com/therecipe/qt/qml" "github.com/therecipe/qt/quickcontrols2" + "git.openprivacy.ca/openprivacy/asaur" + "cwtch.im/cwtch/app" + "os/exec" + "log" + "os/user" + "path" + "time" + "strconv" ) +type QmlCwtchApp struct { + core.QObject + + _ int `property:"torStatusProgress"` + _ string `property:"torStatusSummary"` + + _ func() `constructor:"init"` +} + +func (qCwtchApp *QmlCwtchApp) init() { + +} + +var cwtchApp app.Application + +func InitCwtch(engine *qml.QQmlApplicationEngine, qCwtchApp *QmlCwtchApp) error { + + torPath, err := exec.LookPath("tor") + if err != nil { + log.Fatal("tor could not be found on this system. Please install it in the system $PATH") + } + + usr, err := user.Current() + if err != nil { + log.Fatalf("\nError: could not load current user: %v\n", err) + } + + doneChan := make(chan bool) + + go func() { + for { + time.Sleep(100 * time.Millisecond) + status, _ := asaur.GetInfo("localhost:9051", "tcp4", "", "status/bootstrap-phase") + + progress, _ := strconv.Atoi(status["PROGRESS"]) + qCwtchApp.SetTorStatusProgress(progress) + + qCwtchApp.SetTorStatusSummary(status["SUMMARY"]) + + if status["TAG"] == "done" { + break + } + } + doneChan <- true + }() + + cwtchApp, err = app.NewApp(path.Join(usr.HomeDir, ".cwtch"), torPath) + if err != nil { + log.Fatalf("Error initializing application: %v", err) + } + + <-doneChan + + return nil +} + func main() { // enable high dpi scaling @@ -24,21 +88,28 @@ func main() { // Default, Fusion, Imagine, Universal quickcontrols2.QQuickStyle_SetStyle("Material") + var qCwtchApp = NewQmlCwtchApp(nil) // create the qml application engine engine := qml.NewQQmlApplicationEngine(nil) + engine.RootContext().SetContextProperty("cwtchApp", qCwtchApp) + // load the embeeded qml file // created by either qtrcc or qtdeploy - //engine.Load(core.NewQUrl3("qrc:./Box.qml", 0)) - //engine.Load(core.NewQUrl3("qrc:./BlueBox.qml", 0)) - //engine.Load(core.NewQUrl3("qrc:./main.qml", 0)) - engine.Load(core.NewQUrl3("qrc:/main.qml", 0)) + //engine.Load(core.NewQUrl3("qrc:/qml/LoadingWindow.qml", 0)) + //engine.Load(core.NewQUrl3("qrc:/qml/MainWindow.qml", 0)) + // you can also load a local file like this instead: //engine.Load(core.QUrl_FromLocalFile("./qml/main.qml")) + engine.Load(core.NewQUrl3("qrc:/qml/main.qml", 0)) + go InitCwtch(engine, qCwtchApp) // start the main Qt event loop // and block until app.Exit() is called // or the window is closed by the user gui.QGuiApplication_Exec() + + // Cleanup + cwtchApp.Shutdown() } diff --git a/qml.qrc b/qml.qrc index 90156e9..24a9466 100644 --- a/qml.qrc +++ b/qml.qrc @@ -1,9 +1,11 @@ - main.qml - BlueBox.qml - Box.qml - ProfilesColumn.qml - GroupsColumn.qml + qml/GroupsColumn.qml + qml/LoadingWindow.qml + qml/MainWindow.qml + qml/ProfilesColumn.qml + assets/open_privacy_logo_white_bg.png + qml/main.qml + assets/cwtch-logo.png diff --git a/GroupsColumn.qml b/qml/GroupsColumn.qml similarity index 99% rename from GroupsColumn.qml rename to qml/GroupsColumn.qml index 0af9931..5f153c6 100644 --- a/GroupsColumn.qml +++ b/qml/GroupsColumn.qml @@ -15,6 +15,8 @@ Rectangle { width: parent.width clip: true + highlight: Rectangle { color: "#ffffff"; radius: 5 } + delegate: Component { id: groupsDelegate @@ -55,10 +57,6 @@ Rectangle { } - highlight: Rectangle { color: "#ffffff"; radius: 5 } - - - - } + } } diff --git a/qml/LoadingWindow.qml b/qml/LoadingWindow.qml new file mode 100644 index 0000000..884f59b --- /dev/null +++ b/qml/LoadingWindow.qml @@ -0,0 +1,37 @@ +import QtQuick 2.0 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.2 + +Window { + //id: loadingWindow + visible: true + title: "Cwtch Bulletin" + color: "#ffffff" + width: 349 + height: 145 + + Column { + Image { + source: "../assets/cwtch-logo.png" + width: 349 + height: 125 + } + ProgressBar { + id: loadingProgressBar + width: parent.width + indeterminate: false + value: 0 + } + Text { + id: loadingProgressText + text: "" + } + } + + Connections { + target: cwtchApp + + onTorStatusProgressChanged: loadingProgressBar.value = cwtchApp.torStatusProgress/100 + onTorStatusSummaryChanged: loadingProgressText.text = cwtchApp.torStatusSummary + } +} diff --git a/main.qml b/qml/MainWindow.qml similarity index 90% rename from main.qml rename to qml/MainWindow.qml index cba37d4..98e47af 100644 --- a/main.qml +++ b/qml/MainWindow.qml @@ -2,7 +2,8 @@ import QtQuick 2.9 import QtQuick.Window 2.2 Window { - visible: true + //visible: false + id: mainWindow width: 1024 height: 800 title: qsTr("Bulletin") @@ -24,7 +25,7 @@ Window { ListElement {name: "alice"; onion: "710829b408e8b368273cbc20b07f1c0d"; pcolor: "#ff0000"} ListElement {name: "bob"; onion: "a219b9740fc76367833cbc20b07d1cee"; pcolor: "#00ff00" } ListElement {name: "carol"; onion: "930829b408e8b364563cbc20b07a6560"; pcolor: "#0000ff" } - + ListElement {name: "+"; onion: "930829b408e8b364563cbc20b07a6560"; pcolor: "#a0a0a0" } } ListModel { diff --git a/ProfilesColumn.qml b/qml/ProfilesColumn.qml similarity index 91% rename from ProfilesColumn.qml rename to qml/ProfilesColumn.qml index ef1cea4..44c7a04 100644 --- a/ProfilesColumn.qml +++ b/qml/ProfilesColumn.qml @@ -15,8 +15,9 @@ Rectangle { ListView { id: list - height: parent.height + //height: parent.height width: parent.width + anchors.fill: parent //highlight: Rectangle { border-color: "white"; radius: 5 } @@ -33,10 +34,6 @@ Rectangle { } } } - - - - } diff --git a/qml/main.qml b/qml/main.qml new file mode 100644 index 0000000..6b8bb2e --- /dev/null +++ b/qml/main.qml @@ -0,0 +1,44 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0 +import QtQuick.Layouts 1.0 +import QtQuick.Window 2.0 + +// Root non-graphical object providing window management and other logic. +QtObject { + id: root + + property MainWindow mainWindow: MainWindow { + onVisibleChanged: if (!visible) Qt.quit() + } + + property LoadingWindow loadingWindow: LoadingWindow { visible: true } + + property Timer timer: Timer { + id: timer + } + + function delay(delayTime, cb) { + timer.interval = delayTime; + timer.repeat = false; + timer.triggered.connect(cb); + timer.start(); + } + + property list commObjs: [ + Connections { + target: cwtchApp + + onTorStatusProgressChanged: { if (cwtchApp.torStatusProgress === 100) { + delay(1000, function() { + loadingWindow.visible = false + mainWindow.visible = true + }) + } + } + + } + ] +} + + +