Fixes from Cwtch UI Integration
This commit is contained in:
parent
b2da9fc54d
commit
3cc56fb011
|
@ -11,4 +11,3 @@ const (
|
|||
// StatusError is an event response for event.Status signifying a call failed in error, ideally accompanied by a event.Error
|
||||
StatusError = "error"
|
||||
)
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ func (gf *GroupFunctionality) GetServerInfoList(profile peer.CwtchPeer) []Server
|
|||
// GetServerInfo compiles all the information the UI might need regarding a particular server including any verified
|
||||
// cryptographic keys
|
||||
func (gf *GroupFunctionality) GetServerInfo(serverOnion string, profile peer.CwtchPeer) Server {
|
||||
serverInfo,_ := profile.FetchConversationInfo(serverOnion)
|
||||
serverInfo, _ := profile.FetchConversationInfo(serverOnion)
|
||||
keyTypes := []model.KeyType{model.KeyTypeServerOnion, model.KeyTypeTokenOnion, model.KeyTypePrivacyPass}
|
||||
var serverKeys []ServerKey
|
||||
|
||||
|
@ -60,4 +60,4 @@ func (gf *GroupFunctionality) GetServerInfo(serverOnion string, profile peer.Cwt
|
|||
}
|
||||
}
|
||||
return Server{Onion: serverOnion, Status: connections.ConnectionStateName[profile.GetPeerState(serverInfo.Handle)], Keys: serverKeys}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ const (
|
|||
ZeroServersLoaded = event.Type("ZeroServersLoaded")
|
||||
NewServer = event.Type("NewServer")
|
||||
ServerIntentUpdate = event.Type("ServerIntentUpdate")
|
||||
ServerDeleted = event.Type("ServerDeleted")
|
||||
ServerDeleted = event.Type("ServerDeleted")
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
58
lib.go
58
lib.go
|
@ -7,12 +7,12 @@ package main
|
|||
import "C"
|
||||
|
||||
import (
|
||||
// Import SQL Cipher
|
||||
_ "github.com/mutecomm/go-sqlcipher/v4"
|
||||
"crypto/rand"
|
||||
constants2 "cwtch.im/cwtch/model/constants"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
// Import SQL Cipher
|
||||
_ "github.com/mutecomm/go-sqlcipher/v4"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
@ -248,18 +248,18 @@ func ReconnectCwtchForeground() {
|
|||
}
|
||||
|
||||
settings := utils.ReadGlobalSettings()
|
||||
groupHandler,_ := groups.ExperimentGate(settings.Experiments)
|
||||
groupHandler, _ := groups.ExperimentGate(settings.Experiments)
|
||||
for _, profileOnion := range peerList {
|
||||
// fix peerpeercontact message counts
|
||||
profile := application.GetPeer(profileOnion)
|
||||
conversations,_ := profile.FetchConversations()
|
||||
conversations, _ := profile.FetchConversations()
|
||||
for _, conversation := range conversations {
|
||||
if (conversation.IsGroup() && groupHandler != nil) || conversation.IsServer() == false {
|
||||
totalMessages,_ := profile.GetChannelMessageCount(conversation.ID, 0)
|
||||
totalMessages, _ := profile.GetChannelMessageCount(conversation.ID, 0)
|
||||
eventHandler.Push(event.NewEvent(event.MessageCounterResync, map[event.Field]string{
|
||||
event.Identity: profileOnion,
|
||||
event.Identity: profileOnion,
|
||||
event.ConversationID: strconv.Itoa(conversation.ID),
|
||||
event.Data: strconv.Itoa(totalMessages),
|
||||
event.Data: strconv.Itoa(totalMessages),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -504,6 +504,7 @@ func c_GetMessage(profile_ptr *C.char, profile_len C.int, conversation_id C.int,
|
|||
// EnhancedMessage wraps a Cwtch model.Message with some additional data to reduce calls from the UI.
|
||||
type EnhancedMessage struct {
|
||||
model.Message
|
||||
ID int // the actual ID of the message in the database (not the row number)
|
||||
ContactImage string
|
||||
}
|
||||
|
||||
|
@ -516,15 +517,18 @@ func GetMessage(profileOnion string, conversationID int, messageIndex int) strin
|
|||
// these requests complete almost immediately v.s. being stalled for seconds to minutes on large groups.
|
||||
if application != nil {
|
||||
profile := application.GetPeer(profileOnion)
|
||||
messages, err := profile.GetMostRecentMessages(conversationID,0, messageIndex, 1)
|
||||
if err == nil && len (messages) == 1 {
|
||||
messages, err := profile.GetMostRecentMessages(conversationID, 0, messageIndex, 1)
|
||||
if err == nil && len(messages) == 1 {
|
||||
time, _ := time.Parse(time.RFC3339Nano, messages[0].Attr[constants2.AttrSentTimestamp])
|
||||
message.Message = model.Message{
|
||||
Message: messages[0].Body,
|
||||
Message: messages[0].Body,
|
||||
Acknowledged: messages[0].Attr[constants2.AttrAck] == constants2.True,
|
||||
Error: messages[0].Attr[constants2.AttrErr],
|
||||
PeerID: messages[0].Attr["Author"],
|
||||
Error: messages[0].Attr[constants2.AttrErr],
|
||||
PeerID: messages[0].Attr[constants2.AttrAuthor],
|
||||
Timestamp: time,
|
||||
}
|
||||
message.ContactImage = utils.RandomProfileImage(messages[0].Attr["Author"])
|
||||
message.ID = messages[0].ID
|
||||
message.ContactImage = utils.RandomProfileImage(message.PeerID)
|
||||
}
|
||||
}
|
||||
bytes, _ := json.Marshal(message)
|
||||
|
@ -542,7 +546,27 @@ func c_GetMessagesByContentHash(profile_ptr *C.char, profile_len C.int, conversa
|
|||
func GetMessagesByContentHash(profileOnion string, handle int, contentHash string) string {
|
||||
var indexedMessages []model.LocallyIndexedMessage
|
||||
if application != nil {
|
||||
// TODO
|
||||
profile := application.GetPeer(profileOnion)
|
||||
id, err := profile.GetChannelMessageByContentHash(handle, 0, contentHash)
|
||||
if err == nil {
|
||||
// TODO this is terrible
|
||||
messages, err := profile.GetMostRecentMessages(handle, 0, 0, 100)
|
||||
if err == nil {
|
||||
for i, message := range messages {
|
||||
if message.ID == id {
|
||||
time, _ := time.Parse(time.RFC3339Nano, messages[0].Attr[constants2.AttrSentTimestamp])
|
||||
msg := model.Message{
|
||||
Message: messages[0].Body,
|
||||
Acknowledged: messages[0].Attr[constants2.AttrAck] == constants2.True,
|
||||
Error: messages[0].Attr[constants2.AttrErr],
|
||||
PeerID: messages[0].Attr[constants2.AttrAuthor],
|
||||
Timestamp: time,
|
||||
}
|
||||
indexedMessages = append(indexedMessages, model.LocallyIndexedMessage{LocalIndex: i, Message: msg})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bytes, _ := json.Marshal(indexedMessages)
|
||||
return string(bytes)
|
||||
|
@ -554,8 +578,6 @@ func c_FreePointer(ptr *C.char) {
|
|||
C.free(unsafe.Pointer(ptr))
|
||||
}
|
||||
|
||||
|
||||
|
||||
//export c_SendMessage
|
||||
func c_SendMessage(profile_ptr *C.char, profile_len C.int, conversation_id C.int, msg_ptr *C.char, msg_len C.int) {
|
||||
profile := C.GoStringN(profile_ptr, profile_len)
|
||||
|
@ -569,7 +591,7 @@ func SendMessage(profileOnion string, conversationID int, msg string) {
|
|||
}
|
||||
|
||||
//export c_SendInvitation
|
||||
func c_SendInvitation(profile_ptr *C.char, profile_len C.int, conversation_id C.int, target_id C.int) {
|
||||
func c_SendInvitation(profile_ptr *C.char, profile_len C.int, conversation_id C.int, target_id C.int) {
|
||||
profile := C.GoStringN(profile_ptr, profile_len)
|
||||
SendInvitation(profile, int(conversation_id), int(target_id))
|
||||
}
|
||||
|
@ -589,7 +611,7 @@ func c_ShareFile(profile_ptr *C.char, profile_len C.int, conversation_id C.int,
|
|||
ShareFile(profile, int(conversation_id), sharefilepath)
|
||||
}
|
||||
|
||||
func ShareFile(profileOnion string , conversationID int, sharefilepath string) {
|
||||
func ShareFile(profileOnion string, conversationID int, sharefilepath string) {
|
||||
profile := application.GetPeer(profileOnion)
|
||||
fh, err := filesharing.FunctionalityGate(utils.ReadGlobalSettings().Experiments)
|
||||
if err != nil {
|
||||
|
|
|
@ -13,5 +13,5 @@ type Contact struct {
|
|||
IsGroup bool `json:"isGroup"`
|
||||
GroupServer string `json:"groupServer"`
|
||||
IsArchived bool `json:"isArchived"`
|
||||
Identifier int `json:"identifier"`
|
||||
Identifier int `json:"identifier"`
|
||||
}
|
||||
|
|
|
@ -123,7 +123,6 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
online, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants2.PeerOnline)
|
||||
// Name always exists
|
||||
e.Data[constants.Name], _ = profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
|
@ -152,8 +151,19 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
continue
|
||||
}
|
||||
|
||||
name,_ := conversationInfo.GetAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
cpicPath := RandomProfileImage(conversationInfo.Handle)
|
||||
name, exists := conversationInfo.GetAttribute(attr.LocalScope, attr.ProfileZone, constants.Name)
|
||||
if !exists {
|
||||
name, exists = conversationInfo.GetAttribute(attr.PeerScope, attr.ProfileZone, constants.Name)
|
||||
if !exists {
|
||||
name = conversationInfo.Handle
|
||||
}
|
||||
}
|
||||
var cpicPath string
|
||||
if conversationInfo.IsGroup() {
|
||||
cpicPath = RandomGroupImage(conversationInfo.Handle)
|
||||
} else {
|
||||
cpicPath = RandomProfileImage(conversationInfo.Handle)
|
||||
}
|
||||
saveHistory, set := conversationInfo.GetAttribute(attr.LocalScope, attr.ProfileZone, event.SaveHistoryKey)
|
||||
if !set {
|
||||
saveHistory = event.DeleteHistoryDefault
|
||||
|
@ -177,19 +187,18 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
authorization = model.AuthBlocked
|
||||
}
|
||||
|
||||
groupServer,_ := conversationInfo.GetAttribute(attr.LocalScope, attr.LegacyGroupZone, constants.GroupServer)
|
||||
groupServer, _ := conversationInfo.GetAttribute(attr.LocalScope, attr.LegacyGroupZone, constants.GroupServer)
|
||||
|
||||
count, err := profile.GetChannelMessageCount(conversationInfo.ID, 0)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching channel message count %v %v", conversationInfo.ID, err)
|
||||
}
|
||||
|
||||
lastMessage,_ := profile.GetMostRecentMessages(conversationInfo.ID, 0, 0,1)
|
||||
|
||||
lastMessage, _ := profile.GetMostRecentMessages(conversationInfo.ID, 0, 0, 1)
|
||||
|
||||
contacts = append(contacts, Contact{
|
||||
Name: name,
|
||||
Identifier: conversationInfo.ID,
|
||||
Identifier: conversationInfo.ID,
|
||||
Onion: conversationInfo.Handle,
|
||||
Status: connections.ConnectionStateName[state],
|
||||
Picture: cpicPath,
|
||||
|
@ -235,18 +244,19 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
profile.SetConversationAttribute(ci.ID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants2.Archived)), event.False)
|
||||
} else {
|
||||
// TODO This Conversation May Not Exist Yet...But we are not in charge of creating it...
|
||||
log.Errorf("todo wait for contact to be added before processing this event...")
|
||||
}
|
||||
ev.Event.Data["Nick"],_ = ci.GetAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
ev.Event.Data["Nick"], _ = ci.GetAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
ev.Event.Data["Picture"] = RandomProfileImage(ev.Event.Data["RemotePeer"])
|
||||
|
||||
case event.NewMessageFromGroup:
|
||||
// only needs contact nickname and picture, for displaying on popup notifications
|
||||
ci, err := profile.FetchConversationInfo(ev.Event.Data["RemotePeer"])
|
||||
if ci != nil && err == nil {
|
||||
ev.Event.Data["Nick"],_ = ci.GetAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
ev.Event.Data["Nick"], _ = ci.GetAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
}
|
||||
ev.Event.Data["Picture"] = RandomProfileImage(ev.Event.Data[event.GroupID])
|
||||
conversationID,_ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
conversationID, _ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
profile.SetConversationAttribute(conversationID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants2.Archived)), event.False)
|
||||
case event.PeerAcknowledgement:
|
||||
ci, err := profile.FetchConversationInfo(ev.Event.Data["RemotePeer"])
|
||||
|
@ -254,14 +264,14 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
ev.Event.Data[event.ConversationID] = strconv.Itoa(ci.ID)
|
||||
}
|
||||
case event.ContactCreated:
|
||||
conversationID,_ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
conversationID, _ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
handle := ev.Event.Data[event.RemotePeer]
|
||||
count, err := profile.GetChannelMessageCount(conversationID, 0)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching channel message count %v %v", conversationID, err)
|
||||
}
|
||||
|
||||
lastMessage,_ := profile.GetMostRecentMessages(conversationID, 0, 0,1)
|
||||
lastMessage, _ := profile.GetMostRecentMessages(conversationID, 0, 0, 1)
|
||||
ev.Event.Data["unread"] = strconv.Itoa(1) // we've just created this contact so by definition this must be 1...
|
||||
ev.Event.Data["picture"] = RandomProfileImage(handle)
|
||||
ev.Event.Data["numMessages"] = strconv.Itoa(count)
|
||||
|
@ -288,7 +298,7 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
}
|
||||
case event.PeerStateChange:
|
||||
cxnState := connections.ConnectionStateToType()[ev.Event.Data[event.ConnectionState]]
|
||||
contact,_ := profile.FetchConversationInfo(ev.Event.Data[event.RemotePeer])
|
||||
contact, _ := profile.FetchConversationInfo(ev.Event.Data[event.RemotePeer])
|
||||
|
||||
if cxnState == connections.AUTHENTICATED && contact == nil {
|
||||
profile.NewContactConversation(ev.Event.Data[event.RemotePeer], model.AccessControl{Read: false, Append: false, Blocked: false}, false)
|
||||
|
@ -307,13 +317,13 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
|
||||
case event.NewRetValMessageFromPeer:
|
||||
// auto handled event means the setting is already done, we're just deciding if we need to tell the UI
|
||||
conversationID,_ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
conversationID, _ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
scope := ev.Event.Data[event.Scope]
|
||||
path := ev.Event.Data[event.Path]
|
||||
exists, _ := strconv.ParseBool(ev.Event.Data[event.Exists])
|
||||
|
||||
if exists && attr.IntoScope(scope) == attr.PublicScope {
|
||||
zone,path := attr.ParseZone(path)
|
||||
zone, path := attr.ParseZone(path)
|
||||
if _, err := profile.GetConversationAttribute(conversationID, attr.LocalScope.ConstructScopedZonedPath(zone.ConstructZonedPath(path))); err != nil {
|
||||
// we have a locally set override, don't pass this remote set public scope update to UI
|
||||
return ""
|
||||
|
@ -396,4 +406,4 @@ func getLastMessageTime(conversationMessages []model.ConversationMessage) int {
|
|||
return 0
|
||||
}
|
||||
return int(time.Unix())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ func RandomProfileImage(onion string) string {
|
|||
choices := []string{"001-centaur", "002-kraken", "003-dinosaur", "004-tree-1", "005-hand", "006-echidna", "007-robot", "008-mushroom", "009-harpy", "010-phoenix", "011-dragon-1", "012-devil", "013-troll", "014-alien", "015-minotaur", "016-madre-monte", "017-satyr", "018-karakasakozou", "019-pirate", "020-werewolf", "021-scarecrow", "022-valkyrie", "023-curupira", "024-loch-ness-monster", "025-tree", "026-cerberus", "027-gryphon", "028-mermaid", "029-vampire", "030-goblin", "031-yeti", "032-leprechaun", "033-medusa", "034-chimera", "035-elf", "036-hydra", "037-cyclops", "038-pegasus", "039-narwhal", "040-woodcutter", "041-zombie", "042-dragon", "043-frankenstein", "044-witch", "045-fairy", "046-genie", "047-pinocchio", "048-ghost", "049-wizard", "050-unicorn"}
|
||||
barr, err := base32.StdEncoding.DecodeString(strings.ToUpper(onion))
|
||||
if err != nil || len(barr) != 35 {
|
||||
log.Errorf("error: %v %v %v\n", onion, err, barr)
|
||||
log.Errorf("error finding image for profile: %v %v %v\n", onion, err, barr)
|
||||
return "extra/openprivacy.png"
|
||||
}
|
||||
return "profiles/" + choices[int(barr[33])%len(choices)] + ".png"
|
||||
|
@ -22,7 +22,7 @@ func RandomGroupImage(handle string) string {
|
|||
choices := []string{"001-borobudur", "002-opera-house", "003-burj-al-arab", "004-chrysler", "005-acropolis", "006-empire-state-building", "007-temple", "008-indonesia-1", "009-new-zealand", "010-notre-dame", "011-space-needle", "012-seoul", "013-mosque", "014-milan", "015-statue", "016-pyramid", "017-cologne", "018-brandenburg-gate", "019-berlin-cathedral", "020-hungarian-parliament", "021-buckingham", "022-thailand", "023-independence", "024-angkor-wat", "025-vaticano", "026-christ-the-redeemer", "027-colosseum", "028-golden-gate-bridge", "029-sphinx", "030-statue-of-liberty", "031-cradle-of-humankind", "032-istanbul", "033-london-eye", "034-sagrada-familia", "035-tower-bridge", "036-burj-khalifa", "037-washington", "038-big-ben", "039-stonehenge", "040-white-house", "041-ahu-tongariki", "042-capitol", "043-eiffel-tower", "044-church-of-the-savior-on-spilled-blood", "045-arc-de-triomphe", "046-windmill", "047-louvre", "048-torii-gate", "049-petronas", "050-matsumoto-castle", "051-fuji", "052-temple-of-heaven", "053-pagoda", "054-chichen-itza", "055-forbidden-city", "056-merlion", "057-great-wall-of-china", "058-taj-mahal", "059-pisa", "060-indonesia"}
|
||||
barr, err := hex.DecodeString(handle)
|
||||
if err != nil || len(barr) == 0 {
|
||||
log.Errorf("error: %v %v %v\n", handle, err, barr)
|
||||
log.Errorf("error finding image for group: %v %v %v\n", handle, err, barr)
|
||||
return "extra/openprivacy.png"
|
||||
}
|
||||
return "servers/" + choices[int(barr[0])%len(choices)] + ".png"
|
||||
|
|
Reference in New Issue