broke up monolithic structure
This commit is contained in:
182
frontend/js/storage.js
Normal file
182
frontend/js/storage.js
Normal file
@@ -0,0 +1,182 @@
|
||||
window.App = window.App || {};
|
||||
App.storage = App.storage || {};
|
||||
App.session = App.session || {};
|
||||
|
||||
(function() {
|
||||
const { FAVORITES_KEY, FAVORITES_VISIBILITY_KEY } = App.constants;
|
||||
|
||||
// Basic localStorage helpers.
|
||||
App.storage.getConfig = function() {
|
||||
return JSON.parse(localStorage.getItem('config')) || { servers: [] };
|
||||
};
|
||||
|
||||
App.storage.setConfig = function(nextConfig) {
|
||||
localStorage.setItem('config', JSON.stringify(nextConfig));
|
||||
};
|
||||
|
||||
App.storage.getSession = function() {
|
||||
return JSON.parse(localStorage.getItem('session')) || null;
|
||||
};
|
||||
|
||||
App.storage.setSession = function(nextSession) {
|
||||
localStorage.setItem('session', JSON.stringify(nextSession));
|
||||
};
|
||||
|
||||
App.storage.getPreferences = function() {
|
||||
return JSON.parse(localStorage.getItem('preferences')) || {};
|
||||
};
|
||||
|
||||
App.storage.setPreferences = function(nextPreferences) {
|
||||
localStorage.setItem('preferences', JSON.stringify(nextPreferences));
|
||||
};
|
||||
|
||||
App.storage.getServerEntries = function() {
|
||||
const config = App.storage.getConfig();
|
||||
if (!config.servers || !Array.isArray(config.servers)) return [];
|
||||
return config.servers.map((serverObj) => {
|
||||
const server = Object.keys(serverObj)[0];
|
||||
return {
|
||||
url: server,
|
||||
data: serverObj[server] || null
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Options/session helpers that power channel selection and filters.
|
||||
App.session.serializeOptions = function(options) {
|
||||
const serialized = {};
|
||||
Object.entries(options || {}).forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
serialized[key] = value.map((entry) => entry.id);
|
||||
} else if (value && value.id) {
|
||||
serialized[key] = value.id;
|
||||
}
|
||||
});
|
||||
return serialized;
|
||||
};
|
||||
|
||||
App.session.hydrateOptions = function(channel, savedOptions) {
|
||||
const hydrated = {};
|
||||
if (!channel || !Array.isArray(channel.options)) return hydrated;
|
||||
const saved = savedOptions || {};
|
||||
channel.options.forEach((optionGroup) => {
|
||||
const allOptions = optionGroup.options || [];
|
||||
const savedValue = saved[optionGroup.id];
|
||||
if (optionGroup.multiSelect) {
|
||||
const selectedIds = Array.isArray(savedValue) ? savedValue : [];
|
||||
const selected = allOptions.filter((opt) => selectedIds.includes(opt.id));
|
||||
hydrated[optionGroup.id] = selected.length > 0 ? selected : allOptions.slice(0, 1);
|
||||
} else {
|
||||
const selected = allOptions.find((opt) => opt.id === savedValue) || allOptions[0];
|
||||
if (selected) hydrated[optionGroup.id] = selected;
|
||||
}
|
||||
});
|
||||
return hydrated;
|
||||
};
|
||||
|
||||
App.session.savePreference = function(session) {
|
||||
if (!session || !session.server || !session.channel) return;
|
||||
const prefs = App.storage.getPreferences();
|
||||
const serverPrefs = prefs[session.server] || {};
|
||||
serverPrefs.channelId = session.channel.id;
|
||||
serverPrefs.optionsByChannel = serverPrefs.optionsByChannel || {};
|
||||
serverPrefs.optionsByChannel[session.channel.id] = App.session.serializeOptions(session.options);
|
||||
prefs[session.server] = serverPrefs;
|
||||
App.storage.setPreferences(prefs);
|
||||
};
|
||||
|
||||
App.session.buildDefaultOptions = function(channel) {
|
||||
const selected = {};
|
||||
if (!channel || !Array.isArray(channel.options)) return selected;
|
||||
channel.options.forEach((optionGroup) => {
|
||||
if (!optionGroup.options || optionGroup.options.length === 0) return;
|
||||
if (optionGroup.multiSelect) {
|
||||
selected[optionGroup.id] = [optionGroup.options[0]];
|
||||
} else {
|
||||
selected[optionGroup.id] = optionGroup.options[0];
|
||||
}
|
||||
});
|
||||
return selected;
|
||||
};
|
||||
|
||||
// Ensures defaults exist and refreshes server status.
|
||||
App.storage.ensureDefaults = async function() {
|
||||
if (!localStorage.getItem('config')) {
|
||||
localStorage.setItem('config', JSON.stringify({
|
||||
servers: [
|
||||
{ "https://getfigleaf.com": {} },
|
||||
{ "https://hottubapp.io": {} },
|
||||
{ "https://hottub.spacemoehre.de": {} }
|
||||
]
|
||||
}));
|
||||
}
|
||||
if (!localStorage.getItem('theme')) {
|
||||
localStorage.setItem('theme', 'dark');
|
||||
}
|
||||
if (!localStorage.getItem(FAVORITES_KEY)) {
|
||||
localStorage.setItem(FAVORITES_KEY, JSON.stringify([]));
|
||||
}
|
||||
if (!localStorage.getItem(FAVORITES_VISIBILITY_KEY)) {
|
||||
localStorage.setItem(FAVORITES_VISIBILITY_KEY, 'true');
|
||||
}
|
||||
await App.storage.initializeServerStatus();
|
||||
};
|
||||
|
||||
// Fetches server status and keeps the session pointing to a valid channel/options.
|
||||
App.storage.initializeServerStatus = async function() {
|
||||
const config = JSON.parse(localStorage.getItem('config'));
|
||||
if (!config || !config.servers) return;
|
||||
|
||||
const statusPromises = config.servers.map(async (serverObj) => {
|
||||
const server = Object.keys(serverObj)[0];
|
||||
try {
|
||||
const response = await fetch(`/api/status`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
server: server
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
});
|
||||
const status = await response.json();
|
||||
serverObj[server] = status;
|
||||
} catch (err) {
|
||||
serverObj[server] = {
|
||||
online: false,
|
||||
channels: []
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(statusPromises);
|
||||
localStorage.setItem('config', JSON.stringify(config));
|
||||
|
||||
const existingSession = App.storage.getSession();
|
||||
const serverKeys = config.servers.map((serverObj) => Object.keys(serverObj)[0]);
|
||||
if (serverKeys.length === 0) return;
|
||||
const selectedServerKey = existingSession && serverKeys.includes(existingSession.server)
|
||||
? existingSession.server
|
||||
: serverKeys[0];
|
||||
const serverEntry = config.servers.find((serverObj) => Object.keys(serverObj)[0] === selectedServerKey);
|
||||
const serverData = serverEntry ? serverEntry[selectedServerKey] : null;
|
||||
|
||||
if (serverData && serverData.channels && serverData.channels.length > 0) {
|
||||
const prefs = App.storage.getPreferences();
|
||||
const serverPrefs = prefs[selectedServerKey] || {};
|
||||
const preferredChannelId = serverPrefs.channelId;
|
||||
const channel = serverData.channels.find((ch) => ch.id === preferredChannelId) || serverData.channels[0];
|
||||
const savedOptions = serverPrefs.optionsByChannel ? serverPrefs.optionsByChannel[channel.id] : null;
|
||||
const options = savedOptions ? App.session.hydrateOptions(channel, savedOptions) : App.session.buildDefaultOptions(channel);
|
||||
|
||||
const sessionData = {
|
||||
server: selectedServerKey,
|
||||
channel: channel,
|
||||
options: options,
|
||||
};
|
||||
|
||||
App.storage.setSession(sessionData);
|
||||
App.session.savePreference(sessionData);
|
||||
}
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user