erinn
/
ui
forked from cwtch.im/ui
1
0
Fork 0
ui/main.go

185 lines
5.3 KiB
Go

package main
import (
libapp "cwtch.im/cwtch/app"
"cwtch.im/cwtch/model"
"cwtch.im/ui/go/characters"
"cwtch.im/ui/go/cwtchthings"
"cwtch.im/ui/go/cwutil"
"cwtch.im/ui/go/gobjects"
"cwtch.im/ui/go/gothings"
"cwtch.im/ui/go/the"
"fmt"
"git.openprivacy.ca/openprivacy/libricochet-go/application"
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"github.com/therecipe/qt/core"
"github.com/therecipe/qt/quick"
"github.com/therecipe/qt/quickcontrols2"
"github.com/therecipe/qt/widgets"
"log"
"os"
"os/user"
"path"
)
func init() {
// make go-defined types available in qml
gothings.GrandCentralDispatcher_QmlRegisterType2("CustomQmlTypes", 1, 0, "GrandCentralDispatcher")
}
func main() {
// our globals
gcd := gothings.NewGrandCentralDispatcher(nil)
gcd.UIState = gothings.NewUIState(gcd)
the.AcknowledgementIDs = make(map[uint32]uint)
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 len(os.Args) == 2 && os.Args[1] == "-local" {
qmlSource = core.QUrl_FromLocalFile("./qml/main.qml")
} else {
qmlSource = core.NewQUrl3("qrc:/qml/main.qml", 0)
}
// window construction boilerplate
view := initializeQtView()
// variables we want to access from inside qml
view.RootContext().SetContextProperty("gcd", gcd)
// this actually loads the qml
view.SetSource(qmlSource)
// these are long-lived pollers/listeners for incoming messages and status changes
loadCwtchData(gcd)
go characters.PostmanPat(gcd.OutgoingMessages)
go characters.TorStatusPoller(gcd.TorStatus)
go characters.PresencePoller(gcd.UIState.GetContact, gcd.UIState.AddContact, gcd.UIState.UpdateContact)
go characters.GroupPoller(gcd.UIState.GetContact, gcd.UIState.UpdateContact)
// here we go!
view.Show()
widgets.QApplication_Exec()
}
// window construction boilerplate
func initializeQtView() *quick.QQuickView {
core.QCoreApplication_SetAttribute(core.Qt__AA_EnableHighDpiScaling, true)
widgets.NewQApplication(len(os.Args), os.Args)
quickcontrols2.QQuickStyle_SetStyle("Universe")
view := quick.NewQQuickView(nil)
view.SetResizeMode(quick.QQuickView__SizeRootObjectToView)
view.SetMinimumHeight(280)
view.SetMinimumWidth(300)
view.SetTitle("cwtch")
return view
}
// this is mostly going to get factored out when we add profile support
// for now, it loads a single peer and fills the ui with its data
func loadCwtchData(gcd *gothings.GrandCentralDispatcher) {
var err error
if os.Getenv("CWTCH_FOLDER") != "" {
the.CwtchDir = os.Getenv("CWTCH_FOLDER")
} else {
usr, err := user.Current()
if err != nil {
fmt.Printf("\nerror: could not load current user: %v\n", err)
os.Exit(1)
}
the.CwtchDir = path.Join(usr.HomeDir, ".cwtch")
}
/*_, err := app2.NewApp(dirname, "/data/data/org.qtproject.example.go/lib/libtor.so")
if err != nil {
log.Printf("ERROR CREATING CWTCH APP: %v", err)
}
time.Sleep(time.Second * 10)
*/
os.MkdirAll(the.CwtchDir, 0700)
mn, err := connectivity.StartTor(the.CwtchDir, "")
if err != nil {
log.Printf("[!!!] Could not start Tor: %v", err)
}
the.CwtchApp = libapp.NewApp(mn, the.CwtchDir)
err = the.CwtchApp.LoadProfiles("be gay do crime")
if err != nil {
//TODO no more fatalfs
log.Fatalf("couldn't load profiles: %v", err)
}
if len(the.CwtchApp.ListPeers()) == 0 {
log.Printf("couldn't load your config file. attempting to create one now")
the.Peer, err = the.CwtchApp.CreatePeer("alice", "be gay do crime")
if err != nil {
log.Fatalf("couldn't create one. is your cwtch folder writable?")
}
the.CwtchApp.SaveProfile(the.Peer)
} else {
the.Peer = the.CwtchApp.PrimaryIdentity()
}
gcd.UpdateMyProfile(the.Peer.GetProfile().Name, the.Peer.GetProfile().Onion, cwutil.RandomProfileImage(the.Peer.GetProfile().Onion))
aif := application.ApplicationInstanceFactory{}
aif.Init()
app := new(application.RicochetApplication)
aif.AddHandler("im.ricochet.chat", func(rai *application.ApplicationInstance) func() channels.Handler {
ccl := new(cwtchthings.ChatChannelListener)
ccl.Init(rai, app, gcd.UIState.AddMessage, gcd.Acknowledged)
return func() channels.Handler {
chat := new(channels.ChatChannel)
chat.Handler = ccl
return chat
}
})
the.Peer.SetApplicationInstanceFactory(aif)
the.CwtchApp.LaunchPeers()
contacts := the.Peer.GetContacts()
for i := range contacts {
contact, _ := the.Peer.GetProfile().GetContact(contacts[i])
displayName, _ := contact.GetAttribute("name")
gcd.UIState.AddContact(&gobjects.Contact{
contacts[i],
displayName,
cwutil.RandomProfileImage(contacts[i]),
"",
0,
0,
contact.Trusted,
})
}
groups := the.Peer.GetGroups()
for i := range groups {
log.Printf("adding saved group %v", groups[i])
group := the.Peer.GetGroup(groups[i])
group.NewMessage = make(chan model.Message)
go characters.CwtchListener(gcd.UIState.AddMessage, groups[i], group.NewMessage)
the.Peer.JoinServer(group.GroupServer)
nick, exists := group.GetAttribute("nick")
if !exists {
nick = group.GroupID[:12]
}
gcd.UIState.AddContact(&gobjects.Contact{
group.GroupID,
nick,
cwutil.RandomGroupImage(group.GroupID),
group.GroupServer,
0,
0,
group.Accepted,
})
}
}