Compare commits

..

2 commits
v1.0.5 ... main

Author SHA1 Message Date
MiTHRAL
1e3f165857 v1.0.7
All checks were successful
Build and Release Sanctum / Build App (push) Successful in 1m55s
2026-05-05 20:50:53 -04:00
MiTHRAL
8a9d621456 v1.0.6
Some checks failed
Build and Release Sanctum / Build App (push) Has been cancelled
2026-05-05 20:48:42 -04:00
4 changed files with 49 additions and 7 deletions

View file

@ -60,6 +60,7 @@
let globalObserver = null;
let refreshTimer = null;
let lastVoiceState = null;
let lastMemberIdentityKey = "";
let leaveWatchdog = null;
const recentRowActivity = new Map();
@ -87,6 +88,7 @@
leaveWatchdog = null;
recentRowActivity.clear();
lastVoiceState = null;
lastMemberIdentityKey = "";
playLeave();
console.debug("[VCSounds] self left");
const overlayApi = window.native?.overlay;
@ -508,6 +510,18 @@
};
}
function memberIdentityKey(members) {
return members
.map((member) =>
[
String(member?.name || "").trim().toLowerCase(),
String(member?.avatarUrl || "").trim().toLowerCase(),
].join(":"),
)
.sort()
.join("|");
}
function publishVoiceState() {
const overlayApi = window.native?.overlay;
if (!overlayApi || typeof overlayApi.setVoiceState !== "function") return;
@ -515,7 +529,28 @@
pruneRowActivity();
const next = collectVoiceState();
const voiceState = inVoice ? next : null;
const nextMemberKey = memberIdentityKey(next.members);
const nextKey = JSON.stringify(voiceState);
const memberChanged = nextMemberKey !== lastMemberIdentityKey;
if (memberChanged && inVoice && !initialising && lastMemberIdentityKey) {
const previousMembers = new Set(
lastMemberIdentityKey
.split("|")
.map((entry) => entry.trim())
.filter(Boolean),
);
const currentMembers = new Set(
nextMemberKey
.split("|")
.map((entry) => entry.trim())
.filter(Boolean),
);
const added = [...currentMembers].some((entry) => !previousMembers.has(entry));
const removed = [...previousMembers].some((entry) => !currentMembers.has(entry));
if (added) playJoin();
if (removed) playLeave();
}
lastMemberIdentityKey = nextMemberKey;
if (nextKey === lastVoiceState) return;
lastVoiceState = nextKey;

View file

@ -27,9 +27,9 @@
<control>pointing</control>
</supports>
<releases>
<release date="2026-05-05" version="1.0.5">
<release date="2026-05-05" version="1.0.7">
<description>
<p>Gameplay overlay and improved game presence support.</p>
<p>Fixed a main-process bootstrap race and improved VC sounds / game presence behavior.</p>
</description>
</release>
<release date="2026-04-22" version="1.0.0">

View file

@ -1,8 +1,8 @@
{
"name": "sanctum",
"productName": "Sanctum",
"version": "1.0.5",
"aviaVersion": "1.0.5",
"version": "1.0.7",
"aviaVersion": "1.0.7",
"main": ".vite/build/main.js",
"repository": "https://git.mithraic.cloud/ad3laid3/sanctum",
"scripts": {

View file

@ -46,8 +46,12 @@ const acquiredLock = app.requestSingleInstanceLock();
const loadInject = () => {
if (!mainWindow) return;
mainWindow.webContents.on("dom-ready", async () => {
const wc = mainWindow.webContents;
wc.removeAllListeners("dom-ready");
wc.once("dom-ready", async () => {
try {
if (mainWindow.isDestroyed() || wc.isDestroyed()) return;
const builtInLocalPlugins = [
{
id: "sanctum-vcsounds",
@ -58,13 +62,15 @@ const loadInject = () => {
},
];
await mainWindow.webContents.executeJavaScript(
await wc.executeJavaScript(
`window.__SANCTUM_BUILTIN_LOCAL_PLUGINS__ = ${JSON.stringify(
builtInLocalPlugins,
)};`,
true,
);
if (mainWindow.isDestroyed() || wc.isDestroyed()) return;
const plugins: string[] = [
"inject.js",
"LocalPlugins.js",
@ -84,9 +90,10 @@ const loadInject = () => {
];
for (const plugin of plugins) {
if (mainWindow.isDestroyed() || wc.isDestroyed()) return;
const pluginPath: string = path.join(__dirname, plugin);
const pluginCode: string = fs.readFileSync(pluginPath, "utf8");
await mainWindow.webContents.executeJavaScript(pluginCode, true);
await wc.executeJavaScript(pluginCode, true);
}
} catch {
/* empty */