Save settings between sessions

Saves settings to cookies
This commit is contained in:
Pyro Nicampt committed 2025-06-12 22:40:03 -05:00
1 parent 4500e426fe
commit c0ffc43ae6
2 files changed
+139 -12

No files matched your search

+8 -7
View File
@@ -27,7 +27,7 @@
</div> </div>
<div id="zoomLevelDisplay"></div> <div id="zoomLevelDisplay"></div>
<div id="cursorCoordDisplay"></div> <div id="cursorCoordDisplay"></div>
Map v0.6.3 alpha Map v0.6.4 alpha
<br> <br>
Updated for Game Build 99.5 Updated for Game Build 99.5
<br> <br>
@@ -41,6 +41,12 @@
</div> </div>
<div id="legend"> <div id="legend">
<div id="legendContents"> <div id="legendContents">
<div class="panel">
<a href="https://github.com/PyroNicampt/DV-Community-Map">Source</a> &#8226;
<a href="https://github.com/PyroNicampt/DV-Community-Map/issues">Issue Tracker</a> &#8226;
<a href="https://derailvalley.wiki.gg/wiki/Derail_Valley_Wiki">DV Wiki</a> &#8226;
<a href="https://wiki.derailvalley.com/wiki/Main_Page">Official Manual</a>
</div>
<div class="panel"> <div class="panel">
Welcome to the WIP community map of <a href="https://www.derailvalley.com/" style="white-space:nowrap;">Derail Valley</a>, a resource for documenting and displaying all tracks and points of interest. Welcome to the WIP community map of <a href="https://www.derailvalley.com/" style="white-space:nowrap;">Derail Valley</a>, a resource for documenting and displaying all tracks and points of interest.
<p> <p>
@@ -62,14 +68,9 @@
</div> </div>
<div id="settingsPanel" class="panel"> <div id="settingsPanel" class="panel">
<h3>Map Settings</h3> <h3>Map Settings</h3>
<div class="quiet" style="margin: 0 0 5px 0;font-size: 10px;">(Page uses local-only cookies to keep settings)</div>
<hr> <hr>
</div> </div>
<div class="panel">
<a href="https://github.com/PyroNicampt/DV-Community-Map">Source</a> &#8226;
<a href="https://github.com/PyroNicampt/DV-Community-Map/issues">Issue Tracker</a> &#8226;
<a href="https://derailvalley.wiki.gg/wiki/Derail_Valley_Wiki">DV Wiki</a> &#8226;
<a href="https://wiki.derailvalley.com/wiki/Main_Page">Official Manual</a>
</div>
</div> </div>
<button id="legendButton" class="panel orange"><svg style="transform:rotate(180deg) translateY(0px)" viewBox="0 0 32 32"><path fill="currentColor" d="M31 16 20 31l-16 0L15 16 4 1l16 0Z"/></svg></button> <button id="legendButton" class="panel orange"><svg style="transform:rotate(180deg) translateY(0px)" viewBox="0 0 32 32"><path fill="currentColor" d="M31 16 20 31l-16 0L15 16 4 1l16 0Z"/></svg></button>
</div> </div>
+131 -5
View File
@@ -5,10 +5,22 @@ import * as Config from './config.js';
import { Color } from './js/colorlib.js'; import { Color } from './js/colorlib.js';
import * as MapData from './js/mapdata.js'; import * as MapData from './js/mapdata.js';
const settingsVersion = 1;
let settingEntries = [ let settingEntries = [
{
label: 'Reset All',
id: 'button_resetSettings',
func: () =>{
for(let entry of settingEntries){
resetSettingEntry(entry);
}
}
},
{ {
label: 'Color Mode', label: 'Color Mode',
id: 'dropdown_trackColor', id: 'dropdown_trackColor',
saveState: true,
options: [ options: [
'None', 'None',
'Grade', 'Grade',
@@ -26,6 +38,7 @@ let settingEntries = [
{ {
label: 'Signage', label: 'Signage',
id: 'toggle_signage', id: 'toggle_signage',
saveState: true,
state: true, state: true,
func: state =>{ func: state =>{
MapData.layers.signage = state; MapData.layers.signage = state;
@@ -35,6 +48,7 @@ let settingEntries = [
{ {
label: 'Speed Signage', label: 'Speed Signage',
id: 'toggle_speedSigns', id: 'toggle_speedSigns',
saveState: true,
state: true, state: true,
func: state =>{ func: state =>{
MapData.layers.speedSigns = state; MapData.layers.speedSigns = state;
@@ -44,6 +58,7 @@ let settingEntries = [
{ {
label: 'Grade Arrows', label: 'Grade Arrows',
id: 'toggle_gradeSigns', id: 'toggle_gradeSigns',
saveState: true,
state: true, state: true,
func: state =>{ func: state =>{
MapData.layers.gradeArrows = state; MapData.layers.gradeArrows = state;
@@ -53,6 +68,7 @@ let settingEntries = [
{ {
label: 'Yard Signage', label: 'Yard Signage',
id: 'toggle_yardSigns', id: 'toggle_yardSigns',
saveState: true,
state: true, state: true,
func: state =>{ func: state =>{
MapData.layers.yardSigns = state; MapData.layers.yardSigns = state;
@@ -62,6 +78,7 @@ let settingEntries = [
{ {
label: 'Junctions', label: 'Junctions',
id: 'toggle_junctions', id: 'toggle_junctions',
saveState: true,
state: true, state: true,
func: state =>{ func: state =>{
MapData.layers.junctions = state; MapData.layers.junctions = state;
@@ -73,6 +90,7 @@ let settingEntries = [
{ {
label: 'Points of Interest', label: 'Points of Interest',
id: 'toggle_poi', id: 'toggle_poi',
saveState: true,
state: true, state: true,
func: state => { func: state => {
MapData.layers.poi = state; MapData.layers.poi = state;
@@ -82,6 +100,7 @@ let settingEntries = [
{ {
label: 'Stations', label: 'Stations',
id: 'toggle_stations', id: 'toggle_stations',
saveState: true,
state: true, state: true,
func: state =>{ func: state =>{
MapData.layers.stations = state; MapData.layers.stations = state;
@@ -91,6 +110,7 @@ let settingEntries = [
{ {
label: 'Services', label: 'Services',
id: 'toggle_services', id: 'toggle_services',
saveState: true,
state: true, state: true,
func: state =>{ func: state =>{
MapData.layers.services = state; MapData.layers.services = state;
@@ -100,6 +120,7 @@ let settingEntries = [
{ {
label: 'Landmarks', label: 'Landmarks',
id: 'toggle_landmarks', id: 'toggle_landmarks',
saveState: true,
state: true, state: true,
func: state =>{ func: state =>{
MapData.layers.landmarks = state; MapData.layers.landmarks = state;
@@ -109,6 +130,7 @@ let settingEntries = [
{ {
label: 'Demonstrator Spawns', label: 'Demonstrator Spawns',
id: 'dropdown_demonstrators', id: 'dropdown_demonstrators',
saveState: true,
options: [ options: [
'None', 'None',
'Hint', 'Hint',
@@ -126,6 +148,7 @@ let settingEntries = [
{ {
label: 'Grade Arrow Direction', label: 'Grade Arrow Direction',
id: 'dropdown_gradeArrowDirection', id: 'dropdown_gradeArrowDirection',
saveState: true,
options: [ options: [
'Uphill', 'Uphill',
'Downhill', 'Downhill',
@@ -139,6 +162,7 @@ let settingEntries = [
{ {
label: 'Terrain', label: 'Terrain',
id: 'dropdown_terrain', id: 'dropdown_terrain',
saveState: true,
options: [ options: [
'None', 'None',
'Simple', 'Simple',
@@ -146,6 +170,7 @@ let settingEntries = [
], ],
state: 'None', state: 'None',
func: state =>{ func: state =>{
console.log(state);
let mapTerrain = document.getElementById('mapTerrain'); let mapTerrain = document.getElementById('mapTerrain');
if(state == 'None'){ if(state == 'None'){
MapData.layers.terrain = false; MapData.layers.terrain = false;
@@ -171,6 +196,7 @@ let settingEntries = [
label: 'Location Host', label: 'Location Host',
id: 'field_locationHost', id: 'field_locationHost',
state: 'localhost:9090', state: 'localhost:9090',
saveState: true,
button: 'Wait', button: 'Wait',
func: state =>{ func: state =>{
let button = document.getElementById('field_locationHost').nextSibling; let button = document.getElementById('field_locationHost').nextSibling;
@@ -191,6 +217,7 @@ let settingEntries = [
label: 'Location Update Rate (seconds)', label: 'Location Update Rate (seconds)',
id: 'dropdown_locationFrequency', id: 'dropdown_locationFrequency',
tooltip: 'Lower update intervals may cause poor performance', tooltip: 'Lower update intervals may cause poor performance',
saveState: true,
state: '0.2', state: '0.2',
options: [ options: [
'0.05', '0.05',
@@ -214,9 +241,17 @@ const legendKey = document.getElementById('legendKey');
export function initialize(){ export function initialize(){
const settingsPanel = document.getElementById('settingsPanel'); const settingsPanel = document.getElementById('settingsPanel');
const oldSettingVersion = loadSetting('version');
for(let thisSetting of settingEntries){ for(let thisSetting of settingEntries){
if(oldSettingVersion != settingsVersion){
resetSetting(thisSetting.id);
addSettingEntry(thisSetting, settingsPanel);
resetSettingEntry(thisSetting);
}else{
addSettingEntry(thisSetting, settingsPanel); addSettingEntry(thisSetting, settingsPanel);
} }
}
saveSetting('version', settingsVersion);
const legend = document.getElementById('legend'); const legend = document.getElementById('legend');
const legendContents = document.getElementById('legendContents'); const legendContents = document.getElementById('legendContents');
const legendButton = document.getElementById('legendButton'); const legendButton = document.getElementById('legendButton');
@@ -240,6 +275,8 @@ function addSettingEntry(thisSetting, parent, indent=0){
thisSetting.divContainer.appendChild(thisSetting.labelElement); thisSetting.divContainer.appendChild(thisSetting.labelElement);
thisSetting.settingType = thisSetting.id.split('_')[0]; thisSetting.settingType = thisSetting.id.split('_')[0];
thisSetting.default = thisSetting.state;
if(thisSetting.saveState) thisSetting.state = loadSetting(thisSetting.id, thisSetting.state);
switch(thisSetting.settingType){ switch(thisSetting.settingType){
case 'toggle': case 'toggle':
thisSetting.inputElement = document.createElement('input'); thisSetting.inputElement = document.createElement('input');
@@ -249,12 +286,14 @@ function addSettingEntry(thisSetting, parent, indent=0){
if(thisSetting.func){ if(thisSetting.func){
thisSetting.inputElement.addEventListener('input', e =>{ thisSetting.inputElement.addEventListener('input', e =>{
thisSetting.func(e.target.checked); thisSetting.func(e.target.checked);
if(thisSetting.saveState) saveSetting(thisSetting.id, e.target.checked);
if(thisSetting.children){ if(thisSetting.children){
for(const child of thisSetting.children){ for(const child of thisSetting.children){
document.getElementById(child.id).parentElement.style.display = e.target.checked ? '' : 'none'; document.getElementById(child.id).parentElement.style.display = e.target.checked ? '' : 'none';
} }
} }
}); });
thisSetting.func(thisSetting.state);
} }
break; break;
case 'dropdown': case 'dropdown':
@@ -274,7 +313,9 @@ function addSettingEntry(thisSetting, parent, indent=0){
if(thisSetting.func){ if(thisSetting.func){
thisSetting.inputElement.addEventListener('change', e =>{ thisSetting.inputElement.addEventListener('change', e =>{
thisSetting.func(e.target.value); thisSetting.func(e.target.value);
}) if(thisSetting.saveState) saveSetting(thisSetting.id, e.target.value);
});
thisSetting.func(thisSetting.state);
} }
break; break;
case 'slider': case 'slider':
@@ -286,7 +327,9 @@ function addSettingEntry(thisSetting, parent, indent=0){
if(thisSetting.func){ if(thisSetting.func){
thisSetting.inputElement.addEventListener('input', e => { thisSetting.inputElement.addEventListener('input', e => {
thisSetting.func(e.target.value); thisSetting.func(e.target.value);
if(thisSetting.saveState) saveSetting(thisSetting.id, e.target.value);
}); });
thisSetting.func(thisSetting.state);
} }
break; break;
case 'field': case 'field':
@@ -300,9 +343,25 @@ function addSettingEntry(thisSetting, parent, indent=0){
if(thisSetting.func){ if(thisSetting.func){
thisSetting.buttonElement.addEventListener('click', e => { thisSetting.buttonElement.addEventListener('click', e => {
thisSetting.func(thisSetting.inputElement.value); thisSetting.func(thisSetting.inputElement.value);
if(thisSetting.saveState) saveSetting(thisSetting.id, e.target.value);
}); });
} }
} }
if(thisSetting.saveState){
thisSetting.inputElement.addEventListener('input', e => {
saveSetting(thisSetting.id, e.target.value);
});
}
break;
case 'button':
thisSetting.inputElement = document.createElement('input');
thisSetting.inputElement.type = 'button';
thisSetting.inputElement.value = thisSetting.label;
if(thisSetting.func){
thisSetting.inputElement.addEventListener('click', e => {
thisSetting.func(0);
});
}
break; break;
case 'header': case 'header':
break; break;
@@ -311,9 +370,11 @@ function addSettingEntry(thisSetting, parent, indent=0){
return; return;
} }
parent.appendChild(thisSetting.divContainer); parent.appendChild(thisSetting.divContainer);
if(thisSetting.settingType != 'button'){
thisSetting.labelElement.innerHTML = thisSetting.label; thisSetting.labelElement.innerHTML = thisSetting.label;
thisSetting.labelElement.htmlFor = thisSetting.id; thisSetting.labelElement.htmlFor = thisSetting.id;
if(thisSetting.tooltip) thisSetting.labelElement.title = thisSetting.tooltip; if(thisSetting.tooltip) thisSetting.labelElement.title = thisSetting.tooltip;
}
if(thisSetting.settingType == 'field'){ if(thisSetting.settingType == 'field'){
thisSetting.buttonElement.style.margin = `0 0.5em 0 ${indent}em`; thisSetting.buttonElement.style.margin = `0 0.5em 0 ${indent}em`;
@@ -326,10 +387,6 @@ function addSettingEntry(thisSetting, parent, indent=0){
thisSetting.divContainer.prepend(thisSetting.inputElement); thisSetting.divContainer.prepend(thisSetting.inputElement);
} }
if(thisSetting.func){
thisSetting.func(thisSetting.state);
}
if(thisSetting.children){ if(thisSetting.children){
for(let child of thisSetting.children){ for(let child of thisSetting.children){
addSettingEntry(child, parent, indent+1); addSettingEntry(child, parent, indent+1);
@@ -337,6 +394,75 @@ function addSettingEntry(thisSetting, parent, indent=0){
} }
} }
function resetSettingEntry(entry){
resetSetting(entry.id);
entry.state = entry.default;
switch(entry.settingType){
case 'toggle':
entry.inputElement.checked = entry.state;
if(entry.children){
for(const child of entry.children){
document.getElementById(child.id).parentElement.style.display = entry.state ? '' : 'none';
}
}
break;
case 'dropdown':
case 'slider':
case 'field':
entry.inputElement.value = entry.state;
break;
}
switch(entry.settingType){
case 'toggle':
case 'dropdown':
case 'slider':
if(entry.func) entry.func(entry.state);
}
if(entry.children){
for(const child of entry.children){
resetSettingEntry(child);
}
}
}
function saveSetting(name, value){
//console.log(`saving 'setting_${name}=${encodeURIComponent(value)};'`);
if(value == null){
resetSetting(name);
}else{
document.cookie = `setting_${name}=${encodeURIComponent(value)};max-age=5000000`;
}
}
function loadSetting(name, defaultValue){
const cookies = document.cookie.split(/\s*;\s*/);
for(let cookie of cookies){
if(cookie.startsWith('setting_'+name+'=')){
let result = cookie.split('=');
//console.log(`Loading setting_${name}=${decodeURIComponent(result[1])}`);
return autocast(decodeURIComponent(result[1]));
}
}
//console.log(`Loading default setting_${name}=${defaultValue}`);
return defaultValue;
}
function resetSetting(name){
document.cookie = `setting_${name}=;expires=${new Date(0).toUTCString()};`;
}
function autocast(value){
if(value == 'true' || value == 'True'){
return true;
}else if(value == 'false' || value == 'False'){
return false;
}else if(!isNaN(value)){
return Number(value);
}else{
return value;
}
}
let pageLoadUpdateDate = null; let pageLoadUpdateDate = null;
async function setLastUpdateData(){ async function setLastUpdateData(){
if(!window.location.host.includes('github')) return; if(!window.location.host.includes('github')) return;