Skip to content

Commit 9b6fac4

Browse files
authored
[discordPresence] Added performers option and minor throttling (#385)
1 parent dcd41b0 commit 9b6fac4

File tree

3 files changed

+56
-31
lines changed

3 files changed

+56
-31
lines changed

plugins/discordPresence/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ Below are a list of available variable names:
5050
- `{url}`
5151
- `{studio_name}`
5252
- `{file_duration}`
53+
- `{performers}`

plugins/discordPresence/discordPresence.js

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,17 @@
1616
* @typedef {{
1717
* id, title, code, details, director, urls?: string[], date, rating100, o_counter,
1818
* organized, interactive, interactive_speed, created_at, updated_at, resume_time,
19-
* last_played_at, play_duration, play_count, files: {duration:number}[], studio?: {id, name}
19+
* last_played_at, play_duration, play_count, files: {duration:number}[],
20+
* studio?: {id, name}, performers: {name, gender}[]
2021
* }} SceneData
2122
*/
2223

2324
/**
24-
* @typedef {{ studio_name: string, url: string, file_duration: string }
25-
* & Omit<SceneData, ['urls', 'files', 'studio']>
25+
* @typedef {{ studio_name: string, url: string, file_duration: string, performers: string }
26+
* & Omit<SceneData, ['urls', 'files', 'studio', 'performers']>
2627
* } FlattenedSceneData
2728
*/
2829

29-
/**
30-
* @typedef {{ data: { findScene: SceneData | null } }} GQLSceneDataResponse
31-
*/
32-
3330
const SCENE_GQL_QUERY = `
3431
query FindScene($id: ID!) {
3532
findScene(id: $id) {
@@ -58,6 +55,7 @@
5855
play_count
5956
files { duration }
6057
studio { name }
58+
performers { name, gender }
6159
}
6260
`;
6361

@@ -82,6 +80,19 @@
8280

8381
console.debug("Discord Presence Plugin: loaded config", CONFIG);
8482

83+
function throttle(mainFunction, delay) {
84+
let timerFlag = null;
85+
86+
return (...args) => {
87+
if (timerFlag === null) {
88+
mainFunction(...args);
89+
timerFlag = setTimeout(() => {
90+
timerFlag = null;
91+
}, delay);
92+
}
93+
};
94+
}
95+
8596
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
8697
const player = () => document.querySelector("#VideoJsPlayer video");
8798

@@ -92,23 +103,6 @@
92103
/** @type {WebSocket} */ let ws;
93104
const wsAlive = () => ws && ws.readyState === 1;
94105

95-
const videoListener = (video) => {
96-
SCENE_ID = parseInt(location.pathname.split("/")[2]);
97-
video.addEventListener("playing", setDiscordActivity);
98-
video.addEventListener("play", setDiscordActivity);
99-
video.addEventListener("timeupdate", setDiscordActivity);
100-
video.addEventListener("seeked", setDiscordActivity);
101-
video.addEventListener("ended", clearDiscordActivity);
102-
};
103-
104-
const unbindVideoListener = (video) => {
105-
video.removeEventListener("playing", setDiscordActivity);
106-
video.removeEventListener("play", setDiscordActivity);
107-
video.removeEventListener("timeupdate", setDiscordActivity);
108-
video.removeEventListener("seeked", setDiscordActivity);
109-
video.removeEventListener("ended", clearDiscordActivity);
110-
};
111-
112106
// Start ws connection to RPC server and add video listener
113107
// Will retry on disconnection/error after 10s
114108
async function start() {
@@ -167,7 +161,7 @@
167161
query: SCENE_GQL_QUERY,
168162
};
169163

170-
/** @type {GQLSceneDataResponse} */
164+
/** @type {SceneData} */
171165
const sceneData = await csLib
172166
.callGQL(reqData)
173167
.then((data) => data.findScene);
@@ -178,17 +172,21 @@
178172
studio_name: sceneData.studio?.name ?? "Unknown Studio",
179173
url: sceneData.urls?.length ? sceneData.urls[0] : "",
180174
file_duration: sceneData.files?.length ? sceneData.files[0].duration : 0,
175+
performers: sceneData.performers.length
176+
? sceneData.performers.map((performer) => performer.name).join(", ")
177+
: "Unlisted Performer(s)",
181178
};
182179

183180
delete sceneData.urls;
184181
delete sceneData.studio;
185182
delete sceneData.files;
183+
delete sceneData.performers;
186184

187185
cachedSceneData = { ...sceneData, ...newProps };
188186
return cachedSceneData;
189187
}
190188

191-
function clearDiscordActivity() {
189+
const clearDiscordActivity = () => {
192190
if (!!SCENE_ID === false || !wsAlive()) {
193191
return;
194192
}
@@ -200,9 +198,9 @@
200198
clearActivity: true,
201199
})
202200
);
203-
}
201+
};
204202

205-
async function setDiscordActivity(event) {
203+
const setDiscordActivity = throttle(async (event) => {
206204
if (event?.type === "timeupdate") {
207205
if (!WAITING_FOR_REFRESH) {
208206
return;
@@ -249,7 +247,7 @@
249247
presence: body,
250248
})
251249
);
252-
}
250+
}, 1000);
253251

254252
/**
255253
* Performs string replacement on templated config vars with scene data
@@ -258,6 +256,32 @@
258256
*/
259257
function replaceVars(templateStr, sceneData) {
260258
const pattern = /{\s*(\w+?)\s*}/g;
261-
return templateStr.replace(pattern, (_, token) => sceneData[token] ?? "");
259+
260+
const replacedStr = templateStr
261+
.replace(pattern, (_, token) => sceneData[token] ?? "")
262+
.trim();
263+
264+
if (replacedStr.length <= 128) {
265+
return replacedStr;
266+
}
267+
268+
return replacedStr.substring(0, 125) + "...";
262269
}
270+
271+
const videoListener = (video) => {
272+
SCENE_ID = parseInt(location.pathname.split("/")[2]);
273+
video.addEventListener("playing", setDiscordActivity);
274+
video.addEventListener("play", setDiscordActivity);
275+
video.addEventListener("timeupdate", setDiscordActivity);
276+
video.addEventListener("seeked", setDiscordActivity);
277+
video.addEventListener("ended", clearDiscordActivity);
278+
};
279+
280+
const unbindVideoListener = (video) => {
281+
video.removeEventListener("playing", setDiscordActivity);
282+
video.removeEventListener("play", setDiscordActivity);
283+
video.removeEventListener("timeupdate", setDiscordActivity);
284+
video.removeEventListener("seeked", setDiscordActivity);
285+
video.removeEventListener("ended", clearDiscordActivity);
286+
};
263287
})();

plugins/discordPresence/discordPresence.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Discord Presence
22
description: Sets currently playing scene data as your Discord status. See README for prerequisites and config options (blue hyperlink next to enable/disable button)
33
url: https://github.com/stashapp/CommunityScripts/tree/main/plugins/discordPresence
44
# requires: CommunityScriptsUILibrary
5-
version: 1.2
5+
version: 1.3
66
settings:
77
discordClientId:
88
displayName: Custom Discord application ID

0 commit comments

Comments
 (0)