|
16 | 16 | * @typedef {{ |
17 | 17 | * id, title, code, details, director, urls?: string[], date, rating100, o_counter, |
18 | 18 | * 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}[] |
20 | 21 | * }} SceneData |
21 | 22 | */ |
22 | 23 |
|
23 | 24 | /** |
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']> |
26 | 27 | * } FlattenedSceneData |
27 | 28 | */ |
28 | 29 |
|
29 | | - /** |
30 | | - * @typedef {{ data: { findScene: SceneData | null } }} GQLSceneDataResponse |
31 | | - */ |
32 | | - |
33 | 30 | const SCENE_GQL_QUERY = ` |
34 | 31 | query FindScene($id: ID!) { |
35 | 32 | findScene(id: $id) { |
|
58 | 55 | play_count |
59 | 56 | files { duration } |
60 | 57 | studio { name } |
| 58 | + performers { name, gender } |
61 | 59 | } |
62 | 60 | `; |
63 | 61 |
|
|
82 | 80 |
|
83 | 81 | console.debug("Discord Presence Plugin: loaded config", CONFIG); |
84 | 82 |
|
| 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 | + |
85 | 96 | const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); |
86 | 97 | const player = () => document.querySelector("#VideoJsPlayer video"); |
87 | 98 |
|
|
92 | 103 | /** @type {WebSocket} */ let ws; |
93 | 104 | const wsAlive = () => ws && ws.readyState === 1; |
94 | 105 |
|
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 | | - |
112 | 106 | // Start ws connection to RPC server and add video listener |
113 | 107 | // Will retry on disconnection/error after 10s |
114 | 108 | async function start() { |
|
167 | 161 | query: SCENE_GQL_QUERY, |
168 | 162 | }; |
169 | 163 |
|
170 | | - /** @type {GQLSceneDataResponse} */ |
| 164 | + /** @type {SceneData} */ |
171 | 165 | const sceneData = await csLib |
172 | 166 | .callGQL(reqData) |
173 | 167 | .then((data) => data.findScene); |
|
178 | 172 | studio_name: sceneData.studio?.name ?? "Unknown Studio", |
179 | 173 | url: sceneData.urls?.length ? sceneData.urls[0] : "", |
180 | 174 | 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)", |
181 | 178 | }; |
182 | 179 |
|
183 | 180 | delete sceneData.urls; |
184 | 181 | delete sceneData.studio; |
185 | 182 | delete sceneData.files; |
| 183 | + delete sceneData.performers; |
186 | 184 |
|
187 | 185 | cachedSceneData = { ...sceneData, ...newProps }; |
188 | 186 | return cachedSceneData; |
189 | 187 | } |
190 | 188 |
|
191 | | - function clearDiscordActivity() { |
| 189 | + const clearDiscordActivity = () => { |
192 | 190 | if (!!SCENE_ID === false || !wsAlive()) { |
193 | 191 | return; |
194 | 192 | } |
|
200 | 198 | clearActivity: true, |
201 | 199 | }) |
202 | 200 | ); |
203 | | - } |
| 201 | + }; |
204 | 202 |
|
205 | | - async function setDiscordActivity(event) { |
| 203 | + const setDiscordActivity = throttle(async (event) => { |
206 | 204 | if (event?.type === "timeupdate") { |
207 | 205 | if (!WAITING_FOR_REFRESH) { |
208 | 206 | return; |
|
249 | 247 | presence: body, |
250 | 248 | }) |
251 | 249 | ); |
252 | | - } |
| 250 | + }, 1000); |
253 | 251 |
|
254 | 252 | /** |
255 | 253 | * Performs string replacement on templated config vars with scene data |
|
258 | 256 | */ |
259 | 257 | function replaceVars(templateStr, sceneData) { |
260 | 258 | 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) + "..."; |
262 | 269 | } |
| 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 | + }; |
263 | 287 | })(); |
0 commit comments