Skip to content
Merged
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
8 changes: 2 additions & 6 deletions plugins/DiscordRPC/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@ export const { trace, errSignal } = Tracer("[DiscordRPC]");
export { Settings } from "./Settings";

redux.intercept(["playbackControls/SEEK", "playbackControls/SET_PLAYBACK_STATE"], unloads, () => {
updateActivity()
.then(() => (errSignal!._ = undefined))
.catch(trace.err.withContext("Failed to set activity"));
updateActivity();
});
MediaItem.onMediaTransition(unloads, (mediaItem) => {
updateActivity(mediaItem)
.then(() => (errSignal!._ = undefined))
.catch(trace.err.withContext("Failed to set activity"));
updateActivity(mediaItem);
});
unloads.add(cleanupRPC.bind(cleanupRPC));

Expand Down
54 changes: 53 additions & 1 deletion plugins/DiscordRPC/src/updateActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,63 @@ import type { SetActivity } from "@xhayper/discord-rpc";
import { fmtStr, getStatusText } from "./activityTextHelpers";
import { setActivity, StatusDisplayTypeEnum } from "./discord.native";
import { settings } from "./Settings";
import { trace, errSignal } from "./index";

// Proxy this so we dont try import a node native module
const StatusDisplayType = await StatusDisplayTypeEnum();

export const updateActivity = async (mediaItem?: MediaItem) => {
// Debounce state
const DEBOUNCE_MS = 300;
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
let isUpdating = false;
let pendingUpdate: MediaItem | undefined | null = null; // null = no pending, undefined = pending with no mediaItem

/**
* Debounced wrapper for _updateActivity
* - Waits DEBOUNCE_MS after last call before executing
* - If already updating, queues the next update
*/
export const updateActivity = (mediaItem?: MediaItem) => {
// If currently updating, mark that we need another update after
if (isUpdating) {
pendingUpdate = mediaItem;
return;
}

// Clear existing timer
if (debounceTimer) clearTimeout(debounceTimer);

// Set new debounce timer
debounceTimer = setTimeout(async () => {
debounceTimer = null;
await executeUpdate(mediaItem);
}, DEBOUNCE_MS);
};

/**
* Execute the actual update with mutex protection
*/
const executeUpdate = async (mediaItem?: MediaItem) => {
isUpdating = true;
try {
await _updateActivity(mediaItem);
errSignal!._ = undefined;
} catch (e) {
trace.err.withContext("Failed to set activity")(e);
} finally {
isUpdating = false;
if (pendingUpdate !== null) {
const pending = pendingUpdate;
pendingUpdate = null;
updateActivity(pending);
}
}
};

/**
* Internal update implementation (no debounce/mutex)
*/
const _updateActivity = async (mediaItem?: MediaItem) => {
if (!PlayState.playing && !settings.displayOnPause) return await setActivity();

mediaItem ??= await MediaItem.fromPlaybackContext();
Expand Down
2 changes: 1 addition & 1 deletion plugins/ListenBrainz/src/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const Settings = () => {
desc={
<>
User token from{" "}
<LunaLink fontWeight="bold" href={`${domain}/settings`}>
<LunaLink fontWeight="bold" href={`${domain?.replace("api.", "")}/settings`}>
listenbrainz.org/settings
</LunaLink>
</>
Expand Down
11 changes: 8 additions & 3 deletions plugins/NativeFullscreen/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { LunaUnload } from "@luna/core";
import { redux } from "@luna/lib";
import { observePromise, redux } from "@luna/lib";
import { storage } from "./Settings";
export { Settings } from "./Settings";

Expand All @@ -16,7 +16,12 @@ export const setTopBarVisibility = (visible: boolean) => {
const bar = document.querySelector<HTMLElement>("div[class^='_bar']");
if (bar) bar.style.display = visible ? "" : "none";
};
if (storage.hideTopBar) setTopBarVisibility(false);
// Apply hideTopBar setting on load
if (storage.hideTopBar) {
observePromise<HTMLElement>(unloads, "div[class^='_bar']").then((bar) => {
if (bar) setTopBarVisibility(false);
});
}

const onKeyDown = (event: KeyboardEvent) => {
if (event.key === "F11") {
Expand All @@ -27,7 +32,7 @@ const onKeyDown = (event: KeyboardEvent) => {

if (document.fullscreenElement || wimp?.classList.contains("is-fullscreen")) {
// Exiting fullscreen
document.exitFullscreen();
if (document.fullscreenElement) document.exitFullscreen();
if (wimp) wimp.classList.remove("is-fullscreen");
if (!storage.hideTopBar) setTopBarVisibility(true);
if (contentContainer) contentContainer.style.maxHeight = "";
Expand Down
18 changes: 8 additions & 10 deletions plugins/Themer/src/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,15 @@
});

require(["vs/editor/editor.main"], () => {
const editor = window.editor = monaco.editor.create(
document.getElementById("container"),
{
value: window.themerCSS,
language: "css",
theme: "vs-dark",
smoothScrolling: true,
}
);
const container = document.getElementById("container");
const editor = window.editor = monaco.editor.create(container, {
value: window.themerCSS,
language: "css",
theme: "vs-dark",
smoothScrolling: true,
});
editor.onDidChangeModelContent(() => ipcRenderer.setCSS(editor.getValue()));
window.addEventListener("resize", editor.layout.bind(editor));
new ResizeObserver(() => editor.layout()).observe(container);
});
</script>
</body>
Expand Down
Loading