Skip to content

Commit b8e2ba3

Browse files
Move to main.js
1 parent b8e88c6 commit b8e2ba3

File tree

2 files changed

+329
-220
lines changed

2 files changed

+329
-220
lines changed

local/main.js

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
// Wait for DOM to be fully loaded before initializing
2+
document.addEventListener('DOMContentLoaded', initializeApp);
3+
let isMusicPlaying = false;
4+
var musicBtn = document.getElementById('music-btn');
5+
async function initializeApp() {
6+
musicBtn = document.getElementById('music-btn');
7+
8+
// Check get parameter to get URL
9+
const queryString = window.location.search;
10+
const urlParams = new URLSearchParams(queryString);
11+
const url = urlParams.get('url');
12+
13+
// If the URL is not provided, redirect to the update page
14+
if (url == null) {
15+
try {
16+
const updateUrl = await window.electronAPI.getUrl('update');
17+
window.location.href = updateUrl;
18+
} catch (error) {
19+
}
20+
}
21+
22+
// Store URL in a global variable for other functions to access
23+
window.initialURL = url;
24+
25+
var page;
26+
var prevpage;
27+
var pagestat;
28+
29+
// Set up document content
30+
document.getElementById("content-frame").setAttribute('src', url);
31+
32+
// Initialize the button state
33+
checkmax();
34+
35+
await openDB();
36+
isMusicPlaying = await loadMusicState();
37+
38+
// Set the initial appearance of the button based on the loaded state
39+
if (isMusicPlaying) {
40+
musicBtn.classList.remove('crossed-out');
41+
} else {
42+
musicBtn.classList.add('crossed-out');
43+
}
44+
45+
// Set up additional window state listeners
46+
setTimeout(() => {
47+
window.addEventListener('resize', () => {
48+
setTimeout(checkmax, 50);
49+
});
50+
51+
// Additional event listener for the title bar
52+
const titleBar = document.querySelector('.title-bar');
53+
if (titleBar) {
54+
titleBar.addEventListener('mouseup', () => setTimeout(checkmax, 50));
55+
titleBar.addEventListener('dblclick', () => setTimeout(checkmax, 50));
56+
}
57+
58+
// Listen for window state changes directly from the main process
59+
if (window.electronAPI && window.electronAPI.onWindowStateChange) {
60+
window.electronAPI.onWindowStateChange((isMaximized) => {
61+
const maxButton = document.getElementById('max-btn');
62+
if (maxButton) {
63+
maxButton.setAttribute('aria-label', isMaximized ? 'Restore' : 'Maximize');
64+
}
65+
});
66+
}
67+
}, 100);
68+
69+
// Start the interval functions
70+
setInterval(discordrpc, 15000);
71+
}
72+
73+
// Window control functions using IPC
74+
async function toggleMaximize() {
75+
try {
76+
const maxButton = document.getElementById('max-btn');
77+
if (!maxButton) return; // Safety check
78+
79+
// Call the maximize function which returns true if window is now maximized
80+
const isMaximized = await window.electronAPI.maximizeWindow();
81+
82+
// Update button appearance immediately based on the returned state
83+
if (isMaximized) {
84+
maxButton.setAttribute('aria-label', 'Restore');
85+
} else {
86+
maxButton.setAttribute('aria-label', 'Maximize');
87+
}
88+
} catch (error) {
89+
console.error('Error in toggleMaximize:', error);
90+
}
91+
}
92+
93+
async function checkmax() {
94+
try {
95+
const maxButton = document.getElementById('max-btn');
96+
if (!maxButton) return; // Safety check
97+
98+
// Get the current window state
99+
const isMaximized = await window.electronAPI.isWindowMaximized();
100+
101+
// Update the button's appearance based on the window state
102+
if (isMaximized) {
103+
if (maxButton.getAttribute('aria-label') !== 'Restore') {
104+
maxButton.setAttribute('aria-label', 'Restore');
105+
}
106+
} else {
107+
if (maxButton.getAttribute('aria-label') !== 'Maximize') {
108+
maxButton.setAttribute('aria-label', 'Maximize');
109+
}
110+
}
111+
} catch (error) {
112+
console.error('Error in checkmax:', error);
113+
}
114+
}
115+
116+
// Run checkmax at a regular interval to keep the button state in sync
117+
setInterval(checkmax, 100);
118+
119+
// Add event listeners for window state changes
120+
window.addEventListener('resize', checkmax);
121+
document.addEventListener('mouseup', checkmax);
122+
123+
// Keep updating the Discord RPC message
124+
var rpcinfo;
125+
function discordrpc() {
126+
try {
127+
// Try to get RPC info from the iframe content
128+
const frameWindow = document.getElementById("content-frame").contentWindow;
129+
if (frameWindow && frameWindow.rpcinfo) {
130+
rpcinfo = frameWindow.rpcinfo;
131+
// Update the Discord RPC status in the main process
132+
if (window.electronAPI && window.electronAPI.updateRpcStatus) {
133+
window.electronAPI.updateRpcStatus(rpcinfo);
134+
}
135+
}
136+
} catch (error) {
137+
// Silently handle cross-origin errors or other issues
138+
// This is expected when the iframe contains external content
139+
}
140+
}
141+
setInterval(discordrpc, 15000);
142+
// Custom built code to check if user is online.
143+
// I have no idea how or why this works.
144+
async function online() {
145+
if (document.getElementById("content-frame").contentWindow.location.href != "chrome-error://chromewebdata/") {
146+
page = document.getElementById("content-frame").contentWindow.location.href;
147+
} else if (page == undefined) {
148+
page = window.initialURL || ''; // Use the stored global URL
149+
}
150+
if (page.includes("offline.html")) {
151+
page = "test";
152+
} else {
153+
154+
155+
const frame = document.getElementById('content-frame');
156+
try {
157+
var pingUrl = await window.electronAPI.getUrl('ping');
158+
var xhttp = new XMLHttpRequest();
159+
xhttp.onreadystatechange = function () {
160+
161+
if (this.readyState == 4 && this.status != 200 && frame.getAttribute('src') != "offline.html?retry=" + page) {
162+
if (page != "test") {
163+
prevpage = page;
164+
}
165+
pagestat = "offline";
166+
page = "offline.html";
167+
frame.setAttribute('src', 'offline.html?retry=' + page);
168+
169+
} else if (document.getElementById("content-frame").contentWindow.location.href != "chrome-error://chromewebdata/") {
170+
page = document.getElementById("content-frame").contentWindow.location.href;
171+
} else {
172+
if ((page == "test") && (pagestat == "offline")) {
173+
frame.setAttribute('src', prevpage);
174+
}
175+
//pagestat = "online";
176+
}
177+
178+
};
179+
xhttp.open("GET", pingUrl, true);
180+
xhttp.send();
181+
} catch (error) {
182+
console.error('Error getting ping URL:', error);
183+
}
184+
}
185+
}
186+
// Add window focus and blur listeners to check window state
187+
window.addEventListener('focus', function () {
188+
setTimeout(checkmax, 50);
189+
});
190+
191+
window.addEventListener('blur', function () {
192+
setTimeout(checkmax, 50);
193+
});
194+
195+
// Prevent scrolling using JavaScript
196+
window.addEventListener('scroll', () => {
197+
window.scrollTo(0, 0); // Keep the window locked at the top
198+
});
199+
200+
// Disable scroll-related JavaScript methods
201+
window.onscroll = () => window.scrollTo(0, 0);
202+
203+
document.addEventListener('wheel', (event) => {
204+
event.preventDefault(); // Disable mouse wheel scrolling
205+
}, { passive: false });
206+
207+
document.addEventListener('keydown', (event) => {
208+
if (["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End"].includes(event.key)) {
209+
event.preventDefault(); // Disable keyboard scrolling
210+
}
211+
});
212+
213+
214+
215+
function toggleMusic() {
216+
const musicBtn = document.getElementById('music-btn');
217+
// Update the global state variable
218+
isMusicPlaying = !isMusicPlaying;
219+
220+
if (isMusicPlaying) {
221+
musicBtn.classList.remove('crossed-out');
222+
// Unmute music logic here
223+
if (window.electronAPI && window.electronAPI.setMusicMuted) {
224+
window.electronAPI.setMusicMuted(false);
225+
}
226+
} else {
227+
musicBtn.classList.add('crossed-out');
228+
// Mute music logic here
229+
if (window.electronAPI && window.electronAPI.setMusicMuted) {
230+
window.electronAPI.setMusicMuted(true);
231+
}
232+
}
233+
234+
// Save the new state to IndexedDB
235+
saveMusicState(isMusicPlaying);
236+
}
237+
238+
let db;
239+
const dbName = 'musicAppState';
240+
const dbVersion = 1;
241+
const storeName = 'preferences';
242+
243+
const openDB = () => {
244+
return new Promise((resolve, reject) => {
245+
const request = indexedDB.open(dbName, dbVersion);
246+
247+
request.onerror = (event) => {
248+
console.error('IndexedDB error:', event.target.errorCode);
249+
reject('IndexedDB error');
250+
};
251+
252+
request.onsuccess = (event) => {
253+
db = event.target.result;
254+
resolve(db);
255+
};
256+
257+
request.onupgradeneeded = (event) => {
258+
db = event.target.result;
259+
// Create the object store if it doesn't exist
260+
db.createObjectStore(storeName);
261+
};
262+
});
263+
};
264+
265+
const saveMusicState = (isMusicPlaying) => {
266+
if (!db) {
267+
console.error('Database is not open.');
268+
return;
269+
}
270+
const transaction = db.transaction([storeName], 'readwrite');
271+
const store = transaction.objectStore(storeName);
272+
273+
// Use a specific key, like 'musicState', to store the value
274+
const request = store.put(isMusicPlaying, 'musicState');
275+
276+
277+
request.onerror = (event) => {
278+
console.error('Error saving music state:', event.target.error);
279+
};
280+
};
281+
282+
const loadMusicState = () => {
283+
return new Promise((resolve, reject) => {
284+
if (!db) {
285+
console.error('Database is not open.');
286+
reject('Database not open');
287+
return;
288+
}
289+
const transaction = db.transaction([storeName], 'readonly');
290+
const store = transaction.objectStore(storeName);
291+
292+
// Retrieve the value using the same key
293+
const request = store.get('musicState');
294+
295+
request.onsuccess = (event) => {
296+
// If the key exists, resolve with the value; otherwise, resolve with a default state
297+
const state = event.target.result !== undefined ? event.target.result : false;
298+
resolve(state);
299+
};
300+
301+
request.onerror = (event) => {
302+
console.error('Error loading music state:', event.target.error);
303+
reject('Error loading state');
304+
};
305+
});
306+
};
307+
308+
const getMusicList = async () => {
309+
try {
310+
const baseUrl = await window.electronAPI.getUrl('music');
311+
312+
// Fetch and parse the modules list
313+
const modulesResponse = await fetch(`${baseUrl}/modules/index.m3u`);
314+
const modulesText = await modulesResponse.text();
315+
const modules = modulesText.split('\n').map(line => line.trim()).filter(line => line.includes('.mod'));
316+
317+
// Fetch and parse the arcade list
318+
const arcadeResponse = await fetch(`${baseUrl}/arcade/index.m3u`);
319+
const arcadeText = await arcadeResponse.text();
320+
const arcade = arcadeText.split('\n').map(line => line.trim()).filter(line => line.includes('.mp3'));
321+
322+
return { modules, arcade };
323+
} catch (error) {
324+
console.error('Error fetching music lists:', error);
325+
return { modules: [], arcade: [] };
326+
}
327+
};

0 commit comments

Comments
 (0)