diff --git a/constants/attributes.go b/constants/attributes.go index f8b1c98..79f6801 100644 --- a/constants/attributes.go +++ b/constants/attributes.go @@ -6,6 +6,7 @@ const Name = "name" const LastRead = "last-read" const Picture = "picture" const ShowBlocked = "show-blocked" +const Archived = "archived" const ProfileTypeV1DefaultPassword = "v1-defaultPassword" const ProfileTypeV1Password = "v1-userPassword" diff --git a/go.mod b/go.mod index 7cdf10e..80ae21c 100644 --- a/go.mod +++ b/go.mod @@ -6,5 +6,8 @@ require ( cwtch.im/cwtch v0.9.2 git.openprivacy.ca/openprivacy/connectivity v1.4.5 git.openprivacy.ca/openprivacy/log v1.0.2 - golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect + golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect + golang.org/x/mod v0.5.0 // indirect + golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect + golang.org/x/tools v0.1.5 // indirect ) diff --git a/go.sum b/go.sum index 0286330..50d591a 100644 --- a/go.sum +++ b/go.sum @@ -51,10 +51,14 @@ golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+o golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= +golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 h1:3In5TnfvnuXTF/uflgpYxSCEGP2NdYT37KsPh3VjZYU= +golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554/go.mod h1:jFTmtFYCV0MFtXBU+J5V/+5AUeVS0ON/0WkE/KSrl6E= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -72,6 +76,8 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -81,8 +87,11 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/lib.go b/lib.go index b4ce058..edcad46 100644 --- a/lib.go +++ b/lib.go @@ -621,10 +621,12 @@ func SendMessage(profileOnion, handle, msg string) { groupHandler, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { groupHandler.SendMessage(profile, handle, msg) + profile.SetGroupAttribute(handle, attr.GetLocalScope(constants.Archived), event.False) } } else { contactHandler, _ := contact.FunctionalityGate(utils.ReadGlobalSettings().Experiments) contactHandler.SendMessage(profile, handle, msg) + profile.SetContactAttribute(handle, attr.GetLocalScope(constants.Archived), event.False) } } @@ -713,32 +715,42 @@ func DeleteProfile(profile string, password string) { application.DeletePeer(profile, password) } -//export c_LeaveConversation -func c_LeaveConversation(profile_ptr *C.char, profile_len C.int, contact_ptr *C.char, contact_len C.int) { +//export c_ArchiveConversation +func c_ArchiveConversation(profile_ptr *C.char, profile_len C.int, contact_ptr *C.char, contact_len C.int) { profile := C.GoStringN(profile_ptr, profile_len) contact := C.GoStringN(contact_ptr, contact_len) - LeaveConversation(profile, contact) + ArchiveConversation(profile, contact) } -// LeaveConversation forces profile to leave the peer -func LeaveConversation(profile string, contact string) { +// ArchiveConversation sets the conversation to archived +func ArchiveConversation(profile string, handle string) { peer := application.GetPeer(profile) - peer.DeleteContact(contact) + ph := utils.NewPeerHelper(peer) + if ph.IsGroup(handle) { + peer.SetGroupAttribute(handle, attr.GetLocalScope(constants.Archived), event.True) + } else { + peer.SetContactAttribute(handle, attr.GetLocalScope(constants.Archived), event.True) + } } -//export c_LeaveGroup -func c_LeaveGroup(profile_ptr *C.char, profile_len C.int, group_ptr *C.char, group_len C.int) { +//export c_DeleteContact +func c_DeleteContact(profile_ptr *C.char, profile_len C.int, hanlde_ptr *C.char, handle_len C.int) { profile := C.GoStringN(profile_ptr, profile_len) - groupID := C.GoStringN(group_ptr, group_len) - LeaveGroup(profile, groupID) + groupID := C.GoStringN(hanlde_ptr, handle_len) + DeleteContact(profile, groupID) } -// LeaveGroup forces profile to leave the group groupID -func LeaveGroup(profile string, groupID string) { +// DeleteContact removes all trace of the contact from the profile +func DeleteContact(profile string, handle string) { peer := application.GetPeer(profile) - _, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments) - if err == nil { - peer.DeleteGroup(groupID) + ph := utils.NewPeerHelper(peer) + if ph.IsGroup(handle) { + _, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + peer.DeleteGroup(handle) + } + } else { + peer.DeleteContact(handle) } } diff --git a/utils/contacts.go b/utils/contacts.go index 2c9aa66..e9f80c8 100644 --- a/utils/contacts.go +++ b/utils/contacts.go @@ -12,4 +12,5 @@ type Contact struct { LastMessage string `json:"lastMsgTime"` IsGroup bool `json:"isGroup"` GroupServer string `json:"groupServer"` + IsArchived bool `json:"isArchived"` } diff --git a/utils/eventHandler.go b/utils/eventHandler.go index cba106b..f029890 100644 --- a/utils/eventHandler.go +++ b/utils/eventHandler.go @@ -166,6 +166,10 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { if !set { saveHistory = event.DeleteHistoryDefault } + isArchived, set := contactInfo.GetAttribute(attr.GetLocalScope(constants.Archived)) + if !set { + isArchived = event.False + } contacts = append(contacts, Contact{ Name: name, Onion: contactInfo.Onion, @@ -177,6 +181,7 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { Unread: 0, LastMessage: strconv.Itoa(getLastMessageTime(&contactInfo.Timeline)), IsGroup: false, + IsArchived: isArchived == event.True, }) } @@ -196,7 +201,10 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { if group.Accepted { authorization = model.AuthApproved } - + isArchived, set := group.GetAttribute(attr.GetLocalScope(constants.Archived)) + if !set { + isArchived = event.False + } // Use the server state when assessing group state state := profile.GetContact(group.GroupServer).State @@ -212,6 +220,7 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { LastMessage: strconv.Itoa(getLastMessageTime(&group.Timeline)), IsGroup: true, GroupServer: group.GroupServer, + IsArchived: isArchived == event.True, }) } @@ -257,10 +266,12 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string { // only needs contact nickname and picture, for displaying on popup notifications ev.Event.Data["Nick"] = ph.GetNick(ev.Event.Data["RemotePeer"]) ev.Event.Data["Picture"] = ph.GetProfilePic(ev.Event.Data["RemotePeer"]) + peer.SetContactAttribute(ev.Event.Data["RemotePeer"], attr.GetLocalScope(constants.Archived), event.False) case event.NewMessageFromGroup: // only needs contact nickname and picture, for displaying on popup notifications ev.Event.Data["Nick"] = ph.GetNick(ev.Event.Data[event.GroupID]) ev.Event.Data["Picture"] = ph.GetProfilePic(ev.Event.Data[event.GroupID]) + peer.SetGroupAttribute(ev.Event.Data[event.GroupID], attr.GetLocalScope(constants.Archived), event.False) case event.PeerAcknowledgement: // No enrichement required case event.PeerCreated: