Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user options to disable battery and certain connected messages #23

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func (br *GMBridge) RegisterCommands() {
cmdDisconnect,
cmdSetActive,
cmdPing,
cmdToggleBatteryNotifications,
cmdToggleVerboseNotifications,
cmdPM,
cmdDeletePortal,
cmdDeleteAllPortals,
Expand Down Expand Up @@ -402,6 +404,44 @@ func fnPing(ce *WrappedCommandEvent) {
}
}

var cmdToggleBatteryNotifications = &commands.FullHandler{
Func: wrapCommand(fnToggleBatteryNotifications),
Name: "toggle-battery-notifications",
Help: commands.HelpMeta{
Section: HelpSectionConnectionManagement,
Description: "Silence Battery statuses.",
},
}

func fnToggleBatteryNotifications(ce *WrappedCommandEvent) {
ce.User.toggleNotifyBattery()
if ce.User.DisableNotifyBattery {
ce.Reply("Disabled battery notifications")
} else {
ce.Reply("Enabled battery notifications")
}
ce.ZLog.Trace().Msg("ToggleBatteryNotifications command finished")
}

var cmdToggleVerboseNotifications = &commands.FullHandler{
Func: wrapCommand(fnToggleVerboseNotifications),
Name: "toggle-verbose-notifications",
Help: commands.HelpMeta{
Section: HelpSectionConnectionManagement,
Description: "Silence Connected statuses when session changes and no data received recently.",
},
}

func fnToggleVerboseNotifications(ce *WrappedCommandEvent) {
ce.User.toggleNotifyVerbose()
if ce.User.DisableNotifyVerbose {
ce.Reply("Disabled verbose notifications")
} else {
ce.Reply("Enabled verbose notifications")
}
ce.ZLog.Trace().Msg("ToggleVerboseNotifications command finished")
}

var cmdPM = &commands.FullHandler{
Func: wrapCommand(fnPM),
Name: "pm",
Expand Down
3 changes: 3 additions & 0 deletions database/upgrades/11-user-settings.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- v11 (compatible with v10+): User settings
ALTER TABLE "user" ADD COLUMN disable_notify_battery BOOLEAN NOT NULL DEFAULT false;
ALTER TABLE "user" ADD COLUMN disable_notify_verbose BOOLEAN NOT NULL DEFAULT false;
10 changes: 8 additions & 2 deletions database/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func newUser(qh *dbutil.QueryHelper[*User]) *User {
}

const (
getUserBaseQuery = `SELECT rowid, mxid, phone_id, session, self_participant_ids, sim_metadata, settings, management_room, space_room, access_token FROM "user"`
getUserBaseQuery = `SELECT rowid, mxid, phone_id, session, self_participant_ids, sim_metadata, settings, management_room, space_room, access_token, disable_notify_battery, disable_notify_verbose FROM "user"`
getAllUsersWithSessionQuery = getUserBaseQuery + " WHERE session IS NOT NULL"
getAllUsersWithDoublePuppetQuery = getUserBaseQuery + " WHERE access_token<>''"
getUserByRowIDQuery = getUserBaseQuery + " WHERE rowid=$1"
Expand All @@ -53,7 +53,8 @@ const (
updateUserQuery = `
UPDATE "user"
SET phone_id=$2, session=$3, self_participant_ids=$4, sim_metadata=$5, settings=$6,
management_room=$7, space_room=$8, access_token=$9
management_room=$7, space_room=$8, access_token=$9,
disable_notify_battery=$10, disable_notify_verbose=$11
WHERE mxid=$1
`
updateuserParticipantIDsQuery = `UPDATE "user" SET self_participant_ids=$2 WHERE mxid=$1`
Expand Down Expand Up @@ -103,6 +104,9 @@ type User struct {
Settings Settings

AccessToken string

DisableNotifyBattery bool
DisableNotifyVerbose bool
}

func (user *User) Scan(row dbutil.Scannable) (*User, error) {
Expand All @@ -111,6 +115,7 @@ func (user *User) Scan(row dbutil.Scannable) (*User, error) {
err := row.Scan(
&user.RowID, &user.MXID, &phoneID, &session, &selfParticipantIDs, &simMetadata,
&settings, &managementRoom, &spaceRoom, &accessToken,
&user.DisableNotifyBattery, &user.DisableNotifyVerbose,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -169,6 +174,7 @@ func (user *User) sqlVariables() []any {
return []any{
user.MXID, dbutil.StrPtr(user.PhoneID), session, string(selfParticipantIDs), string(simMetadata),
string(settings), dbutil.StrPtr(user.ManagementRoom), dbutil.StrPtr(user.SpaceRoom), dbutil.StrPtr(user.AccessToken),
user.DisableNotifyBattery, user.DisableNotifyVerbose,
}
}

Expand Down
2 changes: 2 additions & 0 deletions libgm/events/ready.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type GaiaLoggedOut struct{}

type NoDataReceived struct{}

type RecentlyDisconnected struct{}

type AccountChange struct {
*gmproto.AccountChangeOrSomethingEvent
IsFake bool
Expand Down
16 changes: 15 additions & 1 deletion libgm/longpoll.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ func (dp *dittoPinger) Loop() {
go dp.HandleNoRecentUpdates()
} else if time.Since(pingStart) > 5*time.Minute {
dp.log.Warn().Msg("Was disconnected for over 5 minutes, sending extra GET_UPDATES call")
go dp.HandleNoRecentUpdates()
go dp.HandleRecentlyDisconnected()
}
}
}
Expand All @@ -259,6 +259,20 @@ func (dp *dittoPinger) HandleNoRecentUpdates() {
}
}

func (dp *dittoPinger) HandleRecentlyDisconnected() {
dp.client.triggerEvent(&events.RecentlyDisconnected{})
err := dp.client.sessionHandler.sendMessageNoResponse(SendMessageParams{
Action: gmproto.ActionType_GET_UPDATES,
OmitTTL: true,
RequestID: dp.client.sessionHandler.sessionID,
})
if err != nil {
dp.log.Err(err).Msg("Failed to send extra GET_UPDATES call")
} else {
dp.log.Debug().Msg("Sent extra GET_UPDATES call")
}
}

func (c *Client) shouldDoDataReceiveCheck() bool {
c.nextDataReceiveCheckLock.Lock()
defer c.nextDataReceiveCheckLock.Unlock()
Expand Down
36 changes: 32 additions & 4 deletions user.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ type User struct {
phoneNotRespondingAlertSent bool
didHackySetActive bool
noDataReceivedRecently bool
recentlyDisconnected bool
lastDataReceived time.Time
gaiaHackyDeviceSwitcher int

Expand Down Expand Up @@ -660,6 +661,7 @@ func (user *User) DeleteSession() {
user.SelfParticipantIDs = []string{}
user.didHackySetActive = false
user.noDataReceivedRecently = false
user.recentlyDisconnected = false
user.lastDataReceived = time.Time{}
err := user.Update(context.TODO())
if err != nil {
Expand Down Expand Up @@ -849,6 +851,8 @@ func (user *User) syncHandleEvent(event any) {
user.handleSettings(v)
case *events.AccountChange:
user.handleAccountChange(v)
case *events.RecentlyDisconnected:
user.recentlyDisconnected = true
case *events.NoDataReceived:
user.noDataReceivedRecently = true
default:
Expand Down Expand Up @@ -970,17 +974,20 @@ func (user *User) handleUserAlert(v *gmproto.UserAlertEvent) {
user.ready = true
newSessionID := user.Client.CurrentSessionID()
sessionIDChanged := user.sessionID != newSessionID
if sessionIDChanged || wasInactive || user.noDataReceivedRecently {
if sessionIDChanged || wasInactive || user.noDataReceivedRecently || user.recentlyDisconnected {
user.zlog.Debug().
Str("old_session_id", user.sessionID).
Str("new_session_id", newSessionID).
Bool("was_inactive", wasInactive).
Bool("had_no_data_received", user.noDataReceivedRecently).
Bool("recently_disconeccted", user.recentlyDisconnected).
Time("last_data_received", user.lastDataReceived).
Msg("Session ID changed for browser active event, resyncing")
user.sessionID = newSessionID
go user.fetchAndSyncConversations(user.lastDataReceived, !sessionIDChanged && !wasInactive)
go user.sendMarkdownBridgeAlert(ctx, false, "Connected to Google Messages")
if (!user.DisableNotifyVerbose || wasInactive || user.recentlyDisconnected) {
go user.sendMarkdownBridgeAlert(ctx, false, "Connected to Google Messages")
}
} else {
user.zlog.Debug().
Str("session_id", user.sessionID).
Expand All @@ -990,6 +997,7 @@ func (user *User) handleUserAlert(v *gmproto.UserAlertEvent) {
Msg("Session ID didn't change for browser active event, not resyncing")
}
user.noDataReceivedRecently = false
user.recentlyDisconnected = false
user.lastDataReceived = time.Now()
case gmproto.AlertType_BROWSER_INACTIVE_FROM_TIMEOUT:
user.browserInactiveType = GMBrowserInactiveTimeout
Expand All @@ -1004,13 +1012,17 @@ func (user *User) handleUserAlert(v *gmproto.UserAlertEvent) {
case gmproto.AlertType_MOBILE_BATTERY_LOW:
user.batteryLow = true
if time.Since(user.batteryLowAlertSent) > 30*time.Minute {
go user.sendMarkdownBridgeAlert(ctx, true, "Your phone's battery is low")
if (!user.DisableNotifyBattery) {
go user.sendMarkdownBridgeAlert(ctx, true, "Your phone's battery is low")
}
user.batteryLowAlertSent = time.Now()
}
case gmproto.AlertType_MOBILE_BATTERY_RESTORED:
user.batteryLow = false
if !user.batteryLowAlertSent.IsZero() {
go user.sendMarkdownBridgeAlert(ctx, false, "Phone battery restored")
if (!user.DisableNotifyBattery) {
go user.sendMarkdownBridgeAlert(ctx, false, "Phone battery restored")
}
user.batteryLowAlertSent = time.Time{}
}
default:
Expand All @@ -1026,6 +1038,22 @@ func (user *User) handleUserAlert(v *gmproto.UserAlertEvent) {
user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected})
}

func (user *User) toggleNotifyBattery() {
user.DisableNotifyBattery = !user.DisableNotifyBattery
err := user.Update(context.TODO())
if err != nil {
user.zlog.Err(err).Msg("Failed to save notify battery preference")
}
}

func (user *User) toggleNotifyVerbose() {
user.DisableNotifyVerbose = !user.DisableNotifyVerbose
err := user.Update(context.TODO())
if err != nil {
user.zlog.Err(err).Msg("Failed to save notify verbose preference")
}
}

func (user *User) handleSettings(settings *gmproto.Settings) {
if settings.SIMCards == nil {
return
Expand Down