YouBar+: fix presence updates never firing (wrong Flux event name) and inbox toggle needing a restart
This commit is contained in:
parent
d6d3c711c7
commit
1663602e72
3 changed files with 40 additions and 19 deletions
|
|
@ -1,11 +1,10 @@
|
||||||
import { logger } from "@vendetta";
|
import { logger } from "@vendetta";
|
||||||
import { storage } from "@vendetta/plugin";
|
import { storage } from "@vendetta/plugin";
|
||||||
import patchYouBarButtons from "./patches/youBarButtons";
|
import patchYouBarButtons from "./patches/youBarButtons";
|
||||||
import { startTrackingNotifications } from "./lib/notifications";
|
import { setInboxTracking } from "./lib/notifications";
|
||||||
import Settings from "./ui/Settings";
|
import Settings from "./ui/Settings";
|
||||||
|
|
||||||
let unpatchButtons: () => void = () => {};
|
let unpatchButtons: () => void = () => {};
|
||||||
let stopTrackingNotifications: () => void = () => {};
|
|
||||||
let patched = false;
|
let patched = false;
|
||||||
let retryHandle: ReturnType<typeof setInterval> | undefined;
|
let retryHandle: ReturnType<typeof setInterval> | undefined;
|
||||||
|
|
||||||
|
|
@ -39,11 +38,7 @@ export default {
|
||||||
storage.showInboxButton ??= false;
|
storage.showInboxButton ??= false;
|
||||||
storage.notifications ??= [];
|
storage.notifications ??= [];
|
||||||
|
|
||||||
// Same "may require a restart" contract as the other buttons - only tracks in the
|
setInboxTracking(!!storage.showInboxButton);
|
||||||
// background when the feature is actually on, not for every YouBar+ user by default.
|
|
||||||
if (storage.showInboxButton) {
|
|
||||||
stopTrackingNotifications = startTrackingNotifications();
|
|
||||||
}
|
|
||||||
|
|
||||||
attempt();
|
attempt();
|
||||||
if (!patched) {
|
if (!patched) {
|
||||||
|
|
@ -57,7 +52,7 @@ export default {
|
||||||
onUnload: () => {
|
onUnload: () => {
|
||||||
stopRetrying();
|
stopRetrying();
|
||||||
unpatchButtons();
|
unpatchButtons();
|
||||||
stopTrackingNotifications();
|
setInboxTracking(false);
|
||||||
},
|
},
|
||||||
settings: Settings
|
settings: Settings
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -263,9 +263,10 @@ function handleThreadMembersUpdate(payload: any) {
|
||||||
|
|
||||||
// Friends only, no bots - a status update from a random server member or a bot's "Playing" state
|
// Friends only, no bots - a status update from a random server member or a bot's "Playing" state
|
||||||
// isn't the kind of thing worth an inbox entry for.
|
// isn't the kind of thing worth an inbox entry for.
|
||||||
function handlePresenceUpdate(payload: any) {
|
function handlePresenceUpdate(update: any) {
|
||||||
try {
|
try {
|
||||||
const userId = payload?.user?.id ?? payload?.userId;
|
const user = update?.user;
|
||||||
|
const userId = user?.id;
|
||||||
if (!userId) return;
|
if (!userId) return;
|
||||||
|
|
||||||
const currentUser = UserStore?.getCurrentUser?.();
|
const currentUser = UserStore?.getCurrentUser?.();
|
||||||
|
|
@ -273,11 +274,9 @@ function handlePresenceUpdate(payload: any) {
|
||||||
|
|
||||||
const friendIds: string[] = RelationshipStore?.getFriendIDs?.() ?? [];
|
const friendIds: string[] = RelationshipStore?.getFriendIDs?.() ?? [];
|
||||||
if (!friendIds.includes(userId)) return;
|
if (!friendIds.includes(userId)) return;
|
||||||
|
if (user.bot) return;
|
||||||
|
|
||||||
const user = UserStore?.getUser?.(userId);
|
const activities = update?.activities;
|
||||||
if (user?.bot) return;
|
|
||||||
|
|
||||||
const activities = payload?.activities;
|
|
||||||
const activity = Array.isArray(activities) ? activities.find((a: any) => a?.type !== 4) : undefined;
|
const activity = Array.isArray(activities) ? activities.find((a: any) => a?.type !== 4) : undefined;
|
||||||
|
|
||||||
const signature = activity ? `${activity.type}:${activity.name}` : "";
|
const signature = activity ? `${activity.type}:${activity.name}` : "";
|
||||||
|
|
@ -287,7 +286,7 @@ function handlePresenceUpdate(payload: any) {
|
||||||
if (!activity) return; // cleared their activity - nothing to notify about
|
if (!activity) return; // cleared their activity - nothing to notify about
|
||||||
|
|
||||||
const verb = ACTIVITY_VERBS[activity.type] ?? "Playing";
|
const verb = ACTIVITY_VERBS[activity.type] ?? "Playing";
|
||||||
const displayName = user?.globalName || user?.username || payload?.user?.globalName || payload?.user?.username || "A friend";
|
const displayName = user.globalName || user.username || "A friend";
|
||||||
|
|
||||||
pushNotification({
|
pushNotification({
|
||||||
id: `presence-${userId}-${Date.now()}`,
|
id: `presence-${userId}-${Date.now()}`,
|
||||||
|
|
@ -297,14 +296,24 @@ function handlePresenceUpdate(payload: any) {
|
||||||
guildName: "",
|
guildName: "",
|
||||||
channelName: "",
|
channelName: "",
|
||||||
timestamp: new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
|
timestamp: new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
|
||||||
author: user ?? payload?.user,
|
author: user,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("[YouBar+] Inbox presence error:", err);
|
console.error("[YouBar+] Inbox presence error:", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startTrackingNotifications(): () => void {
|
// The raw gateway op is singular PRESENCE_UPDATE, but Discord's own socket layer batches them
|
||||||
|
// before they ever reach Flux - confirmed against the decompiled bundle's handlePresenceUpdates,
|
||||||
|
// which reads payload.updates (an array of {guildId, user, status, activities}). Subscribing to
|
||||||
|
// the singular name means this handler simply never fires.
|
||||||
|
function handlePresenceUpdates(payload: any) {
|
||||||
|
const updates = payload?.updates;
|
||||||
|
if (!Array.isArray(updates)) return;
|
||||||
|
for (const update of updates) handlePresenceUpdate(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTrackingNotifications(): () => void {
|
||||||
memoryNotifications = Array.isArray(storage.notifications) ? [...storage.notifications] : [];
|
memoryNotifications = Array.isArray(storage.notifications) ? [...storage.notifications] : [];
|
||||||
|
|
||||||
const unsubMessage = fluxSubscribe("MESSAGE_CREATE", handleIncomingMessage);
|
const unsubMessage = fluxSubscribe("MESSAGE_CREATE", handleIncomingMessage);
|
||||||
|
|
@ -312,7 +321,7 @@ export function startTrackingNotifications(): () => void {
|
||||||
const unsubRelationship = fluxSubscribe("RELATIONSHIP_ADD", handleRelationshipAdd);
|
const unsubRelationship = fluxSubscribe("RELATIONSHIP_ADD", handleRelationshipAdd);
|
||||||
const unsubFriendAccepted = fluxSubscribe("FRIEND_REQUEST_ACCEPTED", handleFriendRequestAccepted);
|
const unsubFriendAccepted = fluxSubscribe("FRIEND_REQUEST_ACCEPTED", handleFriendRequestAccepted);
|
||||||
const unsubThreadMembers = fluxSubscribe("THREAD_MEMBERS_UPDATE", handleThreadMembersUpdate);
|
const unsubThreadMembers = fluxSubscribe("THREAD_MEMBERS_UPDATE", handleThreadMembersUpdate);
|
||||||
const unsubPresence = fluxSubscribe("PRESENCE_UPDATE", handlePresenceUpdate);
|
const unsubPresence = fluxSubscribe("PRESENCE_UPDATES", handlePresenceUpdates);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (saveTimeout) clearTimeout(saveTimeout);
|
if (saveTimeout) clearTimeout(saveTimeout);
|
||||||
|
|
@ -326,3 +335,18 @@ export function startTrackingNotifications(): () => void {
|
||||||
lastActivitySignature.clear();
|
lastActivitySignature.clear();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let stopTracking: () => void = () => {};
|
||||||
|
let tracking = false;
|
||||||
|
|
||||||
|
// Lets the settings toggle flip tracking on/off live instead of requiring a restart to take effect.
|
||||||
|
export function setInboxTracking(enabled: boolean) {
|
||||||
|
if (enabled === tracking) return;
|
||||||
|
tracking = enabled;
|
||||||
|
if (enabled) {
|
||||||
|
stopTracking = startTrackingNotifications();
|
||||||
|
} else {
|
||||||
|
stopTracking();
|
||||||
|
stopTracking = () => {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { TableRowGroup, TableSwitchRow } from "@shared/ui/table";
|
||||||
import SettingsScaffold from "@shared/ui/SettingsScaffold";
|
import SettingsScaffold from "@shared/ui/SettingsScaffold";
|
||||||
import NoteBox from "@shared/ui/NoteBox";
|
import NoteBox from "@shared/ui/NoteBox";
|
||||||
import { updateYouBar } from "../patches/youBarButtons";
|
import { updateYouBar } from "../patches/youBarButtons";
|
||||||
|
import { setInboxTracking } from "../lib/notifications";
|
||||||
|
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
|
|
@ -34,10 +35,11 @@ export default function Settings() {
|
||||||
/>
|
/>
|
||||||
<TableSwitchRow
|
<TableSwitchRow
|
||||||
label="Inbox button"
|
label="Inbox button"
|
||||||
subLabel="Show a categorized mentions/replies/reactions inbox in the YouBar - requires a restart to take effect"
|
subLabel="Show a categorized mentions/replies/reactions inbox in the YouBar"
|
||||||
value={!!storage.showInboxButton}
|
value={!!storage.showInboxButton}
|
||||||
onValueChange={(v: boolean) => {
|
onValueChange={(v: boolean) => {
|
||||||
storage.showInboxButton = v;
|
storage.showInboxButton = v;
|
||||||
|
setInboxTracking(v);
|
||||||
updateYouBar();
|
updateYouBar();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue