diff --git a/easytier-gui/src/components/Config.vue b/easytier-gui/src/components/Config.vue index 3ac06f1..7e1e38f 100644 --- a/easytier-gui/src/components/Config.vue +++ b/easytier-gui/src/components/Config.vue @@ -15,9 +15,9 @@ const props = defineProps<{ defineEmits(['runNetwork']) const networking_methods = ref([ - { value: NetworkingMethod.PublicServer, label: t('public_server') }, - { value: NetworkingMethod.Manual, label: t('manual') }, - { value: NetworkingMethod.Standalone, label: t('standalone') }, + { value: NetworkingMethod.PublicServer, label: () => t('public_server') }, + { value: NetworkingMethod.Manual, label: () => t('manual') }, + { value: NetworkingMethod.Standalone, label: () => t('standalone') }, ]) const networkStore = useNetworkStore() @@ -32,9 +32,78 @@ const curNetwork = computed(() => { return networkStore.curNetwork }) -const presetPublicServers = [ - 'tcp://easytier.public.kkrainbow.top:11010', -] +const protos:{ [proto: string] : number; } = {'tcp': 11010, 'udp': 11010, 'wg':11011, 'ws': 11011, 'wss': 11012} + +function searchUrlSuggestions(e: { query: string }): string[] { + const query = e.query + let ret = [] + // if query match "^\w+:.*", then no proto prefix + if (query.match(/^\w+:.*/)) { + // if query is a valid url, then add to suggestions + try { + new URL(query) + ret.push(query) + } catch (e) {} + } else { + for (let proto in protos) { + let item = proto + '://' + query + // if query match ":\d+$", then no port suffix + if (!query.match(/:\d+$/)) { + item += ':' + protos[proto] + } + ret.push(item) + } + } + + return ret +} + + +const publicServerSuggestions = ref(['']) + +const searchPresetPublicServers = (e: { query: string }) => { + const presetPublicServers = [ + 'tcp://easytier.public.kkrainbow.top:11010', + ] + + let query = e.query + // if query is sub string of presetPublicServers, add to suggestions + let ret = presetPublicServers.filter((item) => item.includes(query)) + // add additional suggestions + if (query.length > 0) { + ret = ret.concat(searchUrlSuggestions(e)) + } + + publicServerSuggestions.value = ret +} + +const peerSuggestions = ref(['']) + +const searchPeerSuggestions = (e: { query: string }) => { + peerSuggestions.value = searchUrlSuggestions(e) +} + +const listenerSuggestions = ref(['']) + +const searchListenerSuggestiong = (e: { query: string }) => { + let ret = [] + + for (let proto in protos) { + let item = proto + '://0.0.0.0:'; + // if query is a number, use it as port + if (e.query.match(/^\d+$/)) { + item += e.query + } else { + item += protos[proto] + } + + if (item.includes(e.query)) { + ret.push(item) + } + } + + listenerSuggestions.value = ret +} function validateHostname() { if (curNetwork.value.hostname) { @@ -102,16 +171,15 @@ onMounted(async () => {
+
- - + class="grow" multiple fluid :suggestions="peerSuggestions" @complete="searchPeerSuggestions"/> - +
@@ -141,29 +209,32 @@ onMounted(async () => {
-
-
- - - - /{{ curNetwork.vpn_portal_client_network_len }} - - + :on-label="t('off_text')" :off-label="t('on_text')" class="w-48"/> +
+
+ + + + /{{ curNetwork.vpn_portal_client_network_len }} + + + + +
- -
- +
diff --git a/easytier-gui/src/components/Status.vue b/easytier-gui/src/components/Status.vue index cb1d6a5..64d9ae7 100644 --- a/easytier-gui/src/components/Status.vue +++ b/easytier-gui/src/components/Status.vue @@ -343,10 +343,10 @@ function showEventLogs() {
-
+
diff --git a/easytier-gui/src/pages/index.vue b/easytier-gui/src/pages/index.vue index 696f854..7d3bf52 100644 --- a/easytier-gui/src/pages/index.vue +++ b/easytier-gui/src/pages/index.vue @@ -256,14 +256,8 @@ function isRunning(id: string) { :placeholder="t('select_network')" class="w-full">