mirror of
https://github.com/samuelthomas2774/nxapi.git
synced 2026-07-07 21:04:14 -05:00
Allow selecting multiple users for friend notifications
This commit is contained in:
parent
59adbe7b83
commit
a2f3d7d2e2
|
|
@ -197,6 +197,8 @@ export class PresenceMonitorManager {
|
|||
this.monitors.splice(index, 1);
|
||||
|
||||
i.disable();
|
||||
|
||||
this.notifications.removeAccount(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -267,7 +269,7 @@ export class ElectronNotificationManager extends NotificationManager {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
async onFriendOnline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
async onFriendOnline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
const currenttitle = friend.presence.game as Game;
|
||||
|
||||
new Notification({
|
||||
|
|
@ -278,7 +280,7 @@ export class ElectronNotificationManager extends NotificationManager {
|
|||
}).show();
|
||||
}
|
||||
|
||||
async onFriendOffline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
async onFriendOffline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
new Notification({
|
||||
title: friend.name,
|
||||
body: 'Offline',
|
||||
|
|
@ -286,7 +288,7 @@ export class ElectronNotificationManager extends NotificationManager {
|
|||
}).show();
|
||||
}
|
||||
|
||||
async onFriendPlayingChangeTitle(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
async onFriendPlayingChangeTitle(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
const currenttitle = friend.presence.game as Game;
|
||||
|
||||
new Notification({
|
||||
|
|
@ -297,7 +299,7 @@ export class ElectronNotificationManager extends NotificationManager {
|
|||
}).show();
|
||||
}
|
||||
|
||||
async onFriendTitleStateChange(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
async onFriendTitleStateChange(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
const currenttitle = friend.presence.game as Game;
|
||||
|
||||
new Notification({
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { WebService } from '../../api/znc-types.js';
|
|||
import openWebService from './webservices.js';
|
||||
import { getToken, SavedToken } from '../../cli/nso/util.js';
|
||||
import { SavedMoonToken } from '../../cli/pctl/util.js';
|
||||
import { dev } from '../../util.js';
|
||||
|
||||
const debug = createDebug('app:main:menu');
|
||||
|
||||
|
|
@ -48,9 +49,11 @@ export default class MenuApp {
|
|||
{label: 'NSA ID: ' + data.nsoAccount.user.nsaId, enabled: false},
|
||||
{type: 'separator'},
|
||||
{label: 'Enable Discord Presence', type: 'checkbox', checked: discordPresenceActive,
|
||||
enabled: discordPresenceActive,
|
||||
click: () => this.setActiveDiscordPresenceUser(discordPresenceActive ? null : data.user.id)},
|
||||
{label: 'Enable notifications for this user\'s presence', type: 'checkbox',
|
||||
checked: monitor?.user_notifications,
|
||||
enabled: !!monitor?.user_notifications,
|
||||
click: () => this.setUserNotificationsActive(data.user.id, !monitor?.user_notifications)},
|
||||
{label: 'Enable notifications for this friends of this user\'s presence', type: 'checkbox',
|
||||
checked: monitor?.friend_notifications,
|
||||
|
|
@ -88,6 +91,10 @@ export default class MenuApp {
|
|||
menu.append(new MenuItem({label: 'Add account', click: this.addPctlAccount}));
|
||||
|
||||
menu.append(new MenuItem({type: 'separator'}));
|
||||
if (dev) menu.append(new MenuItem({label: 'Dump notifications state', click: () => {
|
||||
debug('Accounts', this.monitors.notifications.accounts);
|
||||
debug('Friends', this.monitors.notifications.onlinefriends);
|
||||
}}));
|
||||
menu.append(new MenuItem({label: 'Quit', click: () => app.quit()}));
|
||||
|
||||
this.tray.setContextMenu(menu);
|
||||
|
|
|
|||
|
|
@ -648,7 +648,7 @@ export async function handler(argv: ArgumentsCamelCase<Arguments>) {
|
|||
const nintendoAccountSessionToken = req.headers['authorization']!.substr(3);
|
||||
const i = new ZncNotifications({
|
||||
...argv,
|
||||
userNotifications: true,
|
||||
userNotifications: false,
|
||||
friendNotifications: true,
|
||||
}, storage, nintendoAccountSessionToken, req.znc!, req.zncAuth!);
|
||||
|
||||
|
|
@ -702,25 +702,25 @@ class EventStreamNotificationManager extends NotificationManager {
|
|||
this.res.write('\n');
|
||||
}
|
||||
|
||||
onFriendOnline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
onFriendOnline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
this.sendEvent(ZncPresenceEventStreamEvent.FRIEND_ONLINE, {
|
||||
id: friend.nsaId, presence: friend.presence, prev: prev?.presence,
|
||||
});
|
||||
}
|
||||
|
||||
onFriendOffline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
onFriendOffline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
this.sendEvent(ZncPresenceEventStreamEvent.FRIEND_OFFLINE, {
|
||||
id: friend.nsaId, presence: friend.presence, prev: prev?.presence,
|
||||
});
|
||||
}
|
||||
|
||||
onFriendPlayingChangeTitle(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
onFriendPlayingChangeTitle(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
this.sendEvent(ZncPresenceEventStreamEvent.FRIEND_TITLE_CHANGE, {
|
||||
id: friend.nsaId, presence: friend.presence, prev: prev?.presence,
|
||||
});
|
||||
}
|
||||
|
||||
onFriendTitleStateChange(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
onFriendTitleStateChange(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
this.sendEvent(ZncPresenceEventStreamEvent.FRIEND_TITLE_STATECHANGE, {
|
||||
id: friend.nsaId, presence: friend.presence, prev: prev?.presence,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -218,22 +218,27 @@ export class ZncNotifications extends Loop {
|
|||
this.splatnet2_monitors.size ? 'user' : null,
|
||||
]);
|
||||
|
||||
await this.updatePresenceForNotifications(user, friends, true);
|
||||
await this.updatePresenceForNotifications(user, friends, this.data.user.id, true);
|
||||
if (user) await this.updatePresenceForSplatNet2Monitors([user]);
|
||||
|
||||
return LoopResult.OK;
|
||||
}
|
||||
|
||||
async updateFriendsStatusForNotifications(friends: (CurrentUser | Friend)[], initialRun?: boolean) {
|
||||
this.notifications.updateFriendsStatusForNotifications(friends, initialRun);
|
||||
async updateFriendsStatusForNotifications(
|
||||
friends: (CurrentUser | Friend)[],
|
||||
naid = this.data.user.id,
|
||||
initialRun?: boolean
|
||||
) {
|
||||
this.notifications.updateFriendsStatusForNotifications(friends, naid, initialRun);
|
||||
}
|
||||
|
||||
async updatePresenceForNotifications(
|
||||
user: CurrentUser | undefined, friends: Friend[] | undefined, initialRun?: boolean
|
||||
user: CurrentUser | undefined, friends: Friend[] | undefined,
|
||||
naid = this.data.user.id, initialRun?: boolean
|
||||
) {
|
||||
await this.updateFriendsStatusForNotifications(([] as (CurrentUser | Friend)[])
|
||||
.concat(this.user_notifications && user ? [user] : [])
|
||||
.concat(this.friend_notifications && friends ? friends : []), initialRun);
|
||||
.concat(this.friend_notifications && friends ? friends : []), naid, initialRun);
|
||||
}
|
||||
|
||||
async updatePresenceForSplatNet2Monitors(friends: (CurrentUser | Friend)[]) {
|
||||
|
|
@ -312,7 +317,7 @@ export class ZncNotifications extends Loop {
|
|||
}
|
||||
|
||||
export class NotificationManager {
|
||||
onFriendOnline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
onFriendOnline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
const currenttitle = friend.presence.game as Game;
|
||||
|
||||
notifier.notify({
|
||||
|
|
@ -324,7 +329,7 @@ export class NotificationManager {
|
|||
});
|
||||
}
|
||||
|
||||
onFriendOffline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
onFriendOffline(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
notifier.notify({
|
||||
title: friend.name,
|
||||
message: 'Offline',
|
||||
|
|
@ -332,7 +337,7 @@ export class NotificationManager {
|
|||
});
|
||||
}
|
||||
|
||||
onFriendPlayingChangeTitle(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
onFriendPlayingChangeTitle(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
const currenttitle = friend.presence.game as Game;
|
||||
|
||||
notifier.notify({
|
||||
|
|
@ -344,7 +349,7 @@ export class NotificationManager {
|
|||
});
|
||||
}
|
||||
|
||||
onFriendTitleStateChange(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, ir?: boolean) {
|
||||
onFriendTitleStateChange(friend: CurrentUser | Friend, prev?: CurrentUser | Friend, naid?: string, ir?: boolean) {
|
||||
const currenttitle = friend.presence.game as Game;
|
||||
|
||||
notifier.notify({
|
||||
|
|
@ -356,18 +361,32 @@ export class NotificationManager {
|
|||
});
|
||||
}
|
||||
|
||||
onlinefriends: (CurrentUser | Friend)[] = [];
|
||||
onlinefriends = new Map</** NA ID */ string, (CurrentUser | Friend)[]>();
|
||||
accounts = new Map</** NSA ID */ string, /** NA ID */ string>();
|
||||
|
||||
async updateFriendsStatusForNotifications(friends: (CurrentUser | Friend)[], initialRun?: boolean) {
|
||||
updateFriendsStatusForNotifications(friends: (CurrentUser | Friend)[], naid: string, initialRun?: boolean) {
|
||||
const newonlinefriends: (CurrentUser | Friend)[] = [];
|
||||
|
||||
for (const friend of friends) {
|
||||
const prev = this.onlinefriends.find(f => f.nsaId === friend.nsaId);
|
||||
const prev = this.onlinefriends.get(naid)?.find(f => f.nsaId === friend.nsaId);
|
||||
const lastpresence = prev?.presence;
|
||||
const online = friend.presence.state === PresenceState.ONLINE ||
|
||||
friend.presence.state === PresenceState.PLAYING;
|
||||
const wasonline = lastpresence?.state === PresenceState.ONLINE ||
|
||||
lastpresence?.state === PresenceState.PLAYING;
|
||||
const consolewasonline = wasonline ||
|
||||
lastpresence?.state === PresenceState.INACTIVE;
|
||||
|
||||
if (friend.presence.state !== PresenceState.OFFLINE || friend.presence.updatedAt) {
|
||||
if (!this.accounts.has(friend.nsaId)) {
|
||||
this.accounts.set(friend.nsaId, naid);
|
||||
}
|
||||
}
|
||||
|
||||
newonlinefriends.push(friend);
|
||||
|
||||
// Another account is monitoring this user's presence
|
||||
if (this.accounts.get(friend.nsaId) !== naid) continue;
|
||||
|
||||
if (!wasonline && online) {
|
||||
// Friend has come online
|
||||
|
|
@ -375,16 +394,14 @@ export class NotificationManager {
|
|||
|
||||
debugFriends('%s is now online%s%s, title %s %s - played for %s since %s', friend.name,
|
||||
friend.presence.state === PresenceState.ONLINE ? '' : ' (' + friend.presence.state + ')',
|
||||
lastpresence ? ' (console was already online)' : '',
|
||||
consolewasonline ? ' (console was already online)' : '',
|
||||
currenttitle.name, JSON.stringify(currenttitle.sysDescription),
|
||||
hrduration(currenttitle.totalPlayTime),
|
||||
currenttitle.firstPlayedAt ? new Date(currenttitle.firstPlayedAt * 1000).toString() : 'now');
|
||||
|
||||
this.onFriendOnline(friend, prev, initialRun);
|
||||
this.onFriendOnline(friend, prev, naid, initialRun);
|
||||
|
||||
newonlinefriends.push(friend);
|
||||
|
||||
if (lastpresence) {
|
||||
if (consolewasonline) {
|
||||
// Friend's console was already online
|
||||
}
|
||||
} else if (wasonline && !online) {
|
||||
|
|
@ -395,11 +412,10 @@ export class NotificationManager {
|
|||
friend.presence.state !== PresenceState.OFFLINE ? ' (console still online)' : '',
|
||||
lasttitle.name, JSON.stringify(lasttitle.sysDescription));
|
||||
|
||||
this.onFriendOffline(friend, prev, initialRun);
|
||||
this.onFriendOffline(friend, prev, naid, initialRun);
|
||||
|
||||
if (friend.presence.state !== PresenceState.OFFLINE) {
|
||||
// Friend's console is still online
|
||||
newonlinefriends.push(friend);
|
||||
}
|
||||
} else if (wasonline && online) {
|
||||
// Friend is still online
|
||||
|
|
@ -418,7 +434,7 @@ export class NotificationManager {
|
|||
hrduration(currenttitle.totalPlayTime),
|
||||
currenttitle.firstPlayedAt ? new Date(currenttitle.firstPlayedAt * 1000).toString() : 'now');
|
||||
|
||||
this.onFriendPlayingChangeTitle(friend, prev, initialRun);
|
||||
this.onFriendPlayingChangeTitle(friend, prev, naid, initialRun);
|
||||
} else if (
|
||||
lastpresence.state !== friend.presence.state ||
|
||||
lasttitle.sysDescription !== currenttitle.sysDescription
|
||||
|
|
@ -430,7 +446,7 @@ export class NotificationManager {
|
|||
friend.presence.state, JSON.stringify(currenttitle.sysDescription),
|
||||
lastpresence.state, JSON.stringify(lasttitle.sysDescription));
|
||||
|
||||
this.onFriendTitleStateChange(friend, prev, initialRun);
|
||||
this.onFriendTitleStateChange(friend, prev, naid, initialRun);
|
||||
} else if (
|
||||
lastpresence.state !== friend.presence.state ||
|
||||
lasttitle.sysDescription !== currenttitle.sysDescription
|
||||
|
|
@ -442,26 +458,62 @@ export class NotificationManager {
|
|||
friend.presence.state, JSON.stringify(currenttitle.sysDescription),
|
||||
lastpresence.state, JSON.stringify(lasttitle.sysDescription));
|
||||
}
|
||||
|
||||
newonlinefriends.push(friend);
|
||||
} else if (!lastpresence && friend.presence.state !== PresenceState.OFFLINE) {
|
||||
} else if (!consolewasonline && friend.presence.state !== PresenceState.OFFLINE) {
|
||||
// Friend's console is now online, but the user is not playing
|
||||
|
||||
debugFriends('%s\'s console is now online', friend.name);
|
||||
|
||||
newonlinefriends.push(friend);
|
||||
} else if (lastpresence && friend.presence.state !== PresenceState.OFFLINE) {
|
||||
} else if (consolewasonline && friend.presence.state !== PresenceState.OFFLINE) {
|
||||
// Friend's console is still online, the user is still not playing
|
||||
|
||||
newonlinefriends.push(friend);
|
||||
} else if (lastpresence && friend.presence.state === PresenceState.OFFLINE) {
|
||||
} else if (consolewasonline && friend.presence.state === PresenceState.OFFLINE) {
|
||||
// Friend's console is now offline
|
||||
|
||||
debugFriends('%s\'s console is now offline', friend.name);
|
||||
}
|
||||
}
|
||||
|
||||
this.onlinefriends = newonlinefriends;
|
||||
for (const friend of this.onlinefriends.get(naid) ?? []) {
|
||||
const updated = newonlinefriends.find(f => f.nsaId === friend.nsaId);
|
||||
|
||||
if (!updated) {
|
||||
// The authenticated user is no longer friends with this user, or received an empty presence
|
||||
// object (no longer has permission to view the user's status?)
|
||||
|
||||
if (this.accounts.get(friend.nsaId) !== naid) continue;
|
||||
this.accounts.delete(friend.nsaId);
|
||||
|
||||
for (const [naid, onlinefriends] of this.onlinefriends) {
|
||||
if (onlinefriends.find(f => f.nsaId === friend.nsaId &&
|
||||
(f.presence.state !== PresenceState.OFFLINE || f.presence.updatedAt)
|
||||
)) {
|
||||
this.accounts.set(friend.nsaId, naid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.onlinefriends.set(naid, newonlinefriends);
|
||||
}
|
||||
|
||||
removeAccount(naid: string) {
|
||||
const onlinefriends = this.onlinefriends.get(naid);
|
||||
if (!onlinefriends) return;
|
||||
|
||||
this.onlinefriends.delete(naid);
|
||||
|
||||
for (const friend of onlinefriends) {
|
||||
if (this.accounts.get(friend.nsaId) !== naid) continue;
|
||||
this.accounts.delete(friend.nsaId);
|
||||
|
||||
for (const [naid, onlinefriends] of this.onlinefriends) {
|
||||
if (onlinefriends.find(f => f.nsaId === friend.nsaId &&
|
||||
(f.presence.state !== PresenceState.OFFLINE || f.presence.updatedAt)
|
||||
)) {
|
||||
this.accounts.set(friend.nsaId, naid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user