Move responsibility for delete history default to Settings (where it should be)
continuous-integration/drone/pr Build is pending Details

This commit is contained in:
Sarah Jamie Lewis 2023-08-17 09:47:15 -07:00
parent aae8a7fc03
commit fac34ad814
5 changed files with 41 additions and 19 deletions

View File

@ -329,21 +329,24 @@ const (
// Define Attribute Keys related to history preservation // Define Attribute Keys related to history preservation
const ( const (
SaveHistoryDefaultKey = "SaveHistoryDefault" // profile level default PreserveHistoryDefaultSettingKey = "SaveHistoryDefault" // profile level default
SaveHistoryKey = "SavePeerHistory" SaveHistoryKey = "SavePeerHistory" // peer level setting
DeleteHistoryDefault = "DefaultDeleteHistory" // used at both profile and contact level.
) )
// Define Default Attribute Values // Define Default Attribute Values
const ( const (
// Save History has 3 distinct states. By default we refer to the profile level // Save History has 3 distinct states. By default we refer to the profile level
// attribute SaveHistoryDefaultKey ( default: unset i.e. DefaultDeleteHistory), // attribute PreserveHistoryDefaultSettingKey ( default: false i.e. DefaultDeleteHistory),
// For each contact, if the profile owner confirms this we change to DeleteHistoryConfirmed, // For each contact, if the profile owner confirms deletion we change to DeleteHistoryConfirmed,
// if the profile owner confirms they want to save history then this becomes SaveHistoryConfirmed // if the profile owner confirms they want to save history then this becomes SaveHistoryConfirmed
// These settings are set at the UI level using Get/SetScopeZoneAttribute with scoped zone: local.profile.* // These settings are set at the UI level using Get/SetScopeZoneAttribute with scoped zone: local.profile.*
SaveHistoryConfirmed = "SaveHistory" SaveHistoryConfirmed = "SaveHistory"
DeleteHistoryConfirmed = "DeleteHistoryConfirmed" DeleteHistoryConfirmed = "DeleteHistoryConfirmed"
SaveHistoryDefault = "DefaultSaveHistory" SaveHistoryDefault = "DefaultSaveHistory"
// NOTE: While this says "[DeleteHistory]Default", The actual behaviour will now depend on the
// global app/profile value of PreserveHistoryDefaultSettingKey
DeleteHistoryDefault = "DefaultDeleteHistory"
) )
// Bool strings // Bool strings

View File

@ -194,10 +194,16 @@ func (cp *cwtchPeer) UpdateExperiments(enabled bool, experiments map[string]bool
cp.experiments = model.InitExperiments(enabled, experiments) cp.experiments = model.InitExperiments(enabled, experiments)
} }
// NotifySettingsUpdate notifies a Cwtch profile of a change in the nature of global experiments. The Cwtch Profile uses // NotifySettingsUpdate notifies a Cwtch profile of a change in the nature of global settings.
// this information to update registered extensions. // The Cwtch Profile uses this information to update registered extensions in addition
// to updating internal settings.
func (cp *cwtchPeer) NotifySettingsUpdate(settings settings.GlobalSettings) { func (cp *cwtchPeer) NotifySettingsUpdate(settings settings.GlobalSettings) {
log.Debugf("Cwtch Profile Settings Update: %v", settings) log.Debugf("Cwtch Profile Settings Update: %v", settings)
// update the save history default...
cp.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, event.PreserveHistoryDefaultSettingKey, strconv.FormatBool(settings.DefaultSaveHistory))
// pass these seetings updates
cp.extensionLock.Lock() cp.extensionLock.Lock()
defer cp.extensionLock.Unlock() defer cp.extensionLock.Unlock()
for _, extension := range cp.extensions { for _, extension := range cp.extensions {
@ -545,7 +551,7 @@ func ImportLegacyProfile(profile *model.Profile, cps *CwtchProfileStorage) Cwtch
if err == nil { if err == nil {
for key, value := range contact.Attributes { for key, value := range contact.Attributes {
switch key { switch key {
case event.SaveHistoryKey: case event.PreserveHistoryDefaultSettingKey:
cp.SetConversationAttribute(conversationID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(event.SaveHistoryKey)), value) cp.SetConversationAttribute(conversationID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(event.SaveHistoryKey)), value)
case string(model.BundleType): case string(model.BundleType):
cp.AddServer(value) cp.AddServer(value)
@ -1537,6 +1543,13 @@ func (cp *cwtchPeer) eventHandler() {
} }
case event.PeerStateChange: case event.PeerStateChange:
handle := ev.Data[event.RemotePeer] handle := ev.Data[event.RemotePeer]
// we need to do this first because calls in the rest of this block may result in
// events that result the UI or bindings fetching new data.
cp.mutex.Lock()
cp.state[handle] = connections.ConnectionStateToType()[ev.Data[event.ConnectionState]]
cp.mutex.Unlock()
if connections.ConnectionStateToType()[ev.Data[event.ConnectionState]] == connections.AUTHENTICATED { if connections.ConnectionStateToType()[ev.Data[event.ConnectionState]] == connections.AUTHENTICATED {
ci, err := cp.FetchConversationInfo(handle) ci, err := cp.FetchConversationInfo(handle)
var cid int var cid int
@ -1577,9 +1590,6 @@ func (cp *cwtchPeer) eventHandler() {
} }
cp.extensionLock.Unlock() cp.extensionLock.Unlock()
cp.mutex.Lock()
cp.state[ev.Data[event.RemotePeer]] = connections.ConnectionStateToType()[ev.Data[event.ConnectionState]]
cp.mutex.Unlock()
case event.ServerStateChange: case event.ServerStateChange:
cp.mutex.Lock() cp.mutex.Lock()
prevState := cp.state[ev.Data[event.GroupServer]] prevState := cp.state[ev.Data[event.GroupServer]]

View File

@ -13,6 +13,7 @@ import (
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"sync" "sync"
) )
@ -836,23 +837,27 @@ func (cps *CwtchProfileStorage) PurgeConversationChannel(conversation int, chann
// PurgeNonSavedMessages deletes all message conversations that are not explicitly set to saved. // PurgeNonSavedMessages deletes all message conversations that are not explicitly set to saved.
func (cps *CwtchProfileStorage) PurgeNonSavedMessages() { func (cps *CwtchProfileStorage) PurgeNonSavedMessages() {
// check to see if the profile global setting has been explicitly set to save (peer) conversations by default.
defaultSave := false defaultSave := false
key, err := cps.LoadProfileKeyValue(TypeAttribute, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(event.SaveHistoryDefaultKey)).ToString()) key, err := cps.LoadProfileKeyValue(TypeAttribute, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(event.PreserveHistoryDefaultSettingKey)).ToString())
if err == nil { if err == nil {
if string(key) == event.SaveHistoryDefault { if defaultSaveSetting, err := strconv.ParseBool(string(key)); err == nil {
defaultSave = true defaultSave = defaultSaveSetting
} }
} }
// Purge Messages that are not stored... // For each conversation, all that is not explicitly saved will be lost...
ci, err := cps.FetchConversations() ci, err := cps.FetchConversations()
if err == nil { if err == nil {
for _, conversation := range ci { for _, conversation := range ci {
// unless this is a server or a group...for which we default save always (for legacy reasons)
// FIXME: revisit this for hybrid groups.
if !conversation.IsGroup() && !conversation.IsServer() { if !conversation.IsGroup() && !conversation.IsServer() {
saveHistoryConfirmed := conversation.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(event.SaveHistoryKey)).ToString()] == event.SaveHistoryConfirmed // Note that we only check for confirmed status here...if it is set to any other value we will fallthrough to the default.
deleteHistoryConfirmed := conversation.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(event.SaveHistoryKey)).ToString()] == event.DeleteHistoryConfirmed saveHistoryConfirmed := conversation.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(event.PreserveHistoryDefaultSettingKey)).ToString()] == event.SaveHistoryConfirmed
deleteHistoryConfirmed := conversation.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(event.PreserveHistoryDefaultSettingKey)).ToString()] == event.DeleteHistoryConfirmed
// we purge conversation history in two specific instances... // we purge conversation history in two specific instances...
// if the conversation has been explicitly marked as default history confirmed OR // if the conversation has been explicitly marked as delete history confirmed OR
// if save history hasn't been confirmed and default save history is false - i.e. in all other cases // if save history hasn't been confirmed and default save history is false - i.e. in all other cases
if deleteHistoryConfirmed || (!saveHistoryConfirmed && !defaultSave) { if deleteHistoryConfirmed || (!saveHistoryConfirmed && !defaultSave) {
log.Debugf("purging conversation...") log.Debugf("purging conversation...")

View File

@ -57,6 +57,7 @@ type GlobalSettings struct {
TorCacheDir string TorCacheDir string
BlodeuweddPath string BlodeuweddPath string
FontScaling float64 FontScaling float64
DefaultSaveHistory bool
} }
var DefaultGlobalSettings = GlobalSettings{ var DefaultGlobalSettings = GlobalSettings{
@ -83,6 +84,7 @@ var DefaultGlobalSettings = GlobalSettings{
TorCacheDir: "", TorCacheDir: "",
BlodeuweddPath: "", BlodeuweddPath: "",
FontScaling: 1.0, // use the system pixel scaling default FontScaling: 1.0, // use the system pixel scaling default
DefaultSaveHistory: false,
} }
func InitGlobalSettingsFile(directory string, password string) (*GlobalSettingsFile, error) { func InitGlobalSettingsFile(directory string, password string) (*GlobalSettingsFile, error) {
@ -131,6 +133,8 @@ func (globalSettingsFile *GlobalSettingsFile) ReadGlobalSettings() GlobalSetting
return settings //firstTime = true return settings //firstTime = true
} }
// note: by giving json.Unmarshal settings we are providing it defacto defaults
// from DefaultGlobalSettings
err = json.Unmarshal(settingsBytes, &settings) err = json.Unmarshal(settingsBytes, &settings)
if err != nil { if err != nil {
log.Errorf("Could not parse global ui settings: %v\n", err) log.Errorf("Could not parse global ui settings: %v\n", err)

View File

@ -65,7 +65,7 @@ func (ps *ProfileStoreV1) load() error {
} }
} }
if contact.Attributes[event.SaveHistoryKey] == event.SaveHistoryConfirmed { if contact.Attributes[event.PreserveHistoryDefaultSettingKey] == event.SaveHistoryConfirmed {
ss := NewStreamStore(ps.directory, contact.LocalID, ps.key) ss := NewStreamStore(ps.directory, contact.LocalID, ps.key)
cp.Contacts[contact.Onion].Timeline.SetMessages(ss.Read()) cp.Contacts[contact.Onion].Timeline.SetMessages(ss.Read())
} }