-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsettings.js
More file actions
125 lines (111 loc) · 2.98 KB
/
settings.js
File metadata and controls
125 lines (111 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { ModuleDir } from "./constants";
const settingsPath = `${ModuleDir}/local.json`;
export const settingsSchema = {
SpawnPlayersVisibility: {
type: 'bool',
default: true,
},
ClickOpenProfiles: {
type: 'bool',
default: true,
},
PageTimeout: {
type: 'int',
default: 120,
},
PageTransitionTime: {
type: 'int',
default: 120,
},
RemoveGlint: {
type: 'bool',
default: false,
},
DeveloperMode: {
type: 'bool',
default: false,
},
SimpleMysticDescription: {
type: 'bool',
default: false,
},
LoadLeaderboardPositions: {
type: 'bool',
default: true,
},
ShowHiddenLeaderboards: {
type: 'bool',
default: false,
},
}
/**
* @typedef {{
* type: 'bool',
* default: boolean
* } | {
* type: 'int',
* default: number,
* } | {
* type: 'string',
* default: string
* }} SettingData
*/
/**
* @typedef {{[T in keyof typeof settingsSchema]: (typeof settingsSchema)[T]['default']}} SettingsTypes
*/
/**
* @typedef {keyof SettingsTypes} SettingsKey
*/
const raw = FileLib.read(settingsPath);
/**
* @type {Partial<SettingsTypes>}
*/
const settings = raw ? JSON.parse(raw) : {}; // this looks weird, but its so that we dont modify settings object;
export const saveSettings = () => FileLib.write(settingsPath, JSON.stringify(settings))
register('gameUnload', saveSettings);
/**
* @type {Map<SettingsKey, ((state: SettingsTypes[SettingsKey])=>void)[]>}
*/
const settingSubs = new Map();
/**
* @template {SettingsKey} T
* @param {T} key
* @returns {SettingsTypes[T]}
*/
export const getSetting = key => settings[key] ?? settingsSchema[key].default;
/**
* @template {SettingsKey} T
* @param {T} key
* @param {((prev: SettingsTypes[T]) => SettingsTypes[T]) | SettingsTypes[T]} value the value, or a function that takes the current setting and returns the new one
* @returns {SettingsTypes[T]}
*/
export const setSetting = (key, value) => {
if(typeof value === 'function') value = value(getSetting(key));
if(JSON.stringify(getSetting(key)) === JSON.stringify(value)) return; //dont want to alert subs if there is no change
const listeners = settingSubs.get(key);
if(listeners) listeners.forEach(listener => listener(value)); //alert subs
if(JSON.stringify(settingsSchema[key].default) === JSON.stringify(value)) {
settings[key] = undefined; //revert to default, save filespace
return value;
}
settings[key] = value;
return value;
}
/**
* Returns a function that when called unsubscribes the listener
* @template {SettingsKey} T
* @param {T} key
* @param {(state: SettingsTypes[T]) => void} callback
* @returns {{unsubscribe: () => void}}
*/
export const subscribeToSetting = (key, callback) => {
if(!settingSubs.has(key)) settingSubs.set(key, []);
settingSubs.get(key).push(callback);
return {
unsubscribe() {
const newArr = settingSubs.get(key).filter(cb => cb !== callback);
if(!newArr.length) settingSubs.delete(key);
settingSubs.set(key, newArr);
}
}
}