diff --git a/easytier-web/frontend/src/components/ConfigGenerator.vue b/easytier-web/frontend/src/components/ConfigGenerator.vue index 2b79884..e9a8f7c 100644 --- a/easytier-web/frontend/src/components/ConfigGenerator.vue +++ b/easytier-web/frontend/src/components/ConfigGenerator.vue @@ -1,16 +1,32 @@ diff --git a/easytier-web/frontend/src/modules/api-host.ts b/easytier-web/frontend/src/modules/api-host.ts new file mode 100644 index 0000000..0b58d32 --- /dev/null +++ b/easytier-web/frontend/src/modules/api-host.ts @@ -0,0 +1,64 @@ +const defaultApiHost = 'https://config-server.easytier.cn'; + +interface ApiHost { + value: string; + usedAt: number; +} + +const isValidHttpUrl = (s: string): boolean => { + let url; + + try { + url = new URL(s); + } catch (_) { + return false; + } + + return url.protocol === "http:" || url.protocol === "https:"; +}; + +const cleanAndLoadApiHosts = (): Array => { + const maxHosts = 10; + const apiHosts = localStorage.getItem('apiHosts'); + if (apiHosts) { + const hosts: Array = JSON.parse(apiHosts); + // sort by usedAt + hosts.sort((a, b) => b.usedAt - a.usedAt); + + // only keep the first 10 + if (hosts.length > maxHosts) { + hosts.splice(maxHosts); + } + + localStorage.setItem('apiHosts', JSON.stringify(hosts)); + return hosts; + } else { + return []; + } +}; + +const saveApiHost = (host: string) => { + console.log('Save API Host:', host); + if (!isValidHttpUrl(host)) { + console.error('Invalid API Host:', host); + return; + } + + let hosts = cleanAndLoadApiHosts(); + const newHost: ApiHost = {value: host, usedAt: Date.now()}; + hosts = hosts.filter((h) => h.value !== host); + hosts.push(newHost); + localStorage.setItem('apiHosts', JSON.stringify(hosts)); +}; + +const getInitialApiHost = (): string => { + const hosts = cleanAndLoadApiHosts(); + if (hosts.length > 0) { + return hosts[0].value; + } else { + saveApiHost(defaultApiHost) + return defaultApiHost; + } +}; + +export {getInitialApiHost, cleanAndLoadApiHosts, saveApiHost} \ No newline at end of file