Allow share QR Code

This commit is contained in:
Peng-YM 2020-09-06 20:53:11 +08:00
parent 82fd8cd02c
commit 77ee48366e
4 changed files with 112 additions and 42 deletions

View File

@ -666,16 +666,17 @@ function ProxyParser(targetPlatform) {
raw = raw.replace(/ -\n.*name/g, " - name").replace(/\$|\`/g, "").split("proxy-providers:")[0].split("proxy-groups:")[0].replace(/\"(name|type|server|port|cipher|password|)\"/g, "$1")
const proxies = YAML.eval(raw).proxies;
output = proxies.map((p) => JSON.stringify(p));
} else if (raw.indexOf("ssd://") == 0) {
} else if (raw.indexOf("ssd://") === 0) {
// preprocessing for SSD subscription format
output = [];
const Base64 = new Base64Code();
let ssdinfo = JSON.parse(Base64.safeDecode(raw.split("ssd://")[1]));
// options (traffic_used, traffic_total, expiry, url)
var traffic_used = ssdinfo.traffic_used; // GB
var traffic_total = ssdinfo.traffic_total; // GB, -1 means unlimited
var expiry = ssdinfo.expiry; // YYYY-MM-DD HH:mm:ss
const traffic_used = ssdinfo.traffic_used; // GB
const traffic_total = ssdinfo.traffic_total; // GB, -1 means unlimited
const expiry = ssdinfo.expiry; // YYYY-MM-DD HH:mm:ss
// default setting
var name = ssdinfo.airport; // name of the airport
let name = ssdinfo.airport; // name of the airport
let port = ssdinfo.port;
let method = ssdinfo.encryption;
let password = ssdinfo.password;

50
web/package-lock.json generated
View File

@ -3716,9 +3716,9 @@
"dev": true
},
"copy-webpack-plugin": {
"version": "5.1.1",
"resolved": "https://registry.npm.taobao.org/copy-webpack-plugin/download/copy-webpack-plugin-5.1.1.tgz",
"integrity": "sha1-VIGgPeoRI9iKmIxv+LeCRyFPC4g=",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz",
"integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==",
"dev": true,
"requires": {
"cacache": "^12.0.3",
@ -3731,7 +3731,7 @@
"normalize-path": "^3.0.0",
"p-limit": "^2.2.1",
"schema-utils": "^1.0.0",
"serialize-javascript": "^2.1.2",
"serialize-javascript": "^4.0.0",
"webpack-log": "^2.0.0"
},
"dependencies": {
@ -3772,8 +3772,8 @@
},
"ignore": {
"version": "3.3.10",
"resolved": "https://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz",
"integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
"integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
"dev": true
},
"pify": {
@ -3784,8 +3784,8 @@
},
"schema-utils": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-1.0.0.tgz?cache=0&sync_timestamp=1590789322916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-1.0.0.tgz",
"integrity": "sha1-C3mpMgTXtgDUsoUNH2bCo0lRx3A=",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
"dev": true,
"requires": {
"ajv": "^6.1.0",
@ -3793,12 +3793,6 @@
"ajv-keywords": "^3.1.0"
}
},
"serialize-javascript": {
"version": "2.1.2",
"resolved": "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-2.1.2.tgz",
"integrity": "sha1-7OxTsOAxe9yV73arcHS3OEeF+mE=",
"dev": true
},
"slash": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz?cache=0&sync_timestamp=1589682715547&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fslash%2Fdownload%2Fslash-1.0.0.tgz",
@ -4163,7 +4157,7 @@
},
"de-indent": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
"resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
"integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=",
"dev": true
},
@ -8939,6 +8933,11 @@
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
"dev": true
},
"qrcode-js-package": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/qrcode-js-package/-/qrcode-js-package-1.0.4.tgz",
"integrity": "sha1-uhH39nK1NwE8OA0DPjuqhl0Htb0="
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz",
@ -10966,9 +10965,9 @@
"dev": true
},
"vue": {
"version": "2.6.11",
"resolved": "https://registry.npm.taobao.org/vue/download/vue-2.6.11.tgz?cache=0&sync_timestamp=1595983987853&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue%2Fdownload%2Fvue-2.6.11.tgz",
"integrity": "sha1-dllNh31LEiNEBuhONSdcbVFBJcU="
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.12.tgz",
"integrity": "sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg=="
},
"vue-cli-plugin-vuetify": {
"version": "2.0.7",
@ -11122,6 +11121,15 @@
}
}
},
"vue-qrcode-component": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/vue-qrcode-component/-/vue-qrcode-component-2.1.1.tgz",
"integrity": "sha1-csN1Z62QvKKpNyRWvSiE8PQ+3zg=",
"requires": {
"qrcode-js-package": "^1.0.4",
"vue": "^2.0.1"
}
},
"vue-router": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz",
@ -11146,9 +11154,9 @@
}
},
"vue-template-compiler": {
"version": "2.6.11",
"resolved": "https://registry.npm.taobao.org/vue-template-compiler/download/vue-template-compiler-2.6.11.tgz",
"integrity": "sha1-wEcE749JixUxMAGJk+VjCdRpgIA=",
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz",
"integrity": "sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg==",
"dev": true,
"requires": {
"de-indent": "^1.0.2",

View File

@ -16,7 +16,8 @@
"material-design-icons-iconfont": "^5.0.1",
"monaco-editor-vue": "^1.0.10",
"v-clipboard": "^2.2.3",
"vue": "^2.6.11",
"vue": "^2.6.12",
"vue-qrcode-component": "^2.1.1",
"vue-router": "^3.4.3",
"vuetify": "^2.2.11",
"vuex": "^3.5.1"
@ -31,7 +32,7 @@
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"vue-cli-plugin-vuetify": "~2.0.7",
"vue-template-compiler": "^2.6.11",
"vue-template-compiler": "^2.6.12",
"vuetify-loader": "^1.3.0"
},
"eslintConfig": {

View File

@ -23,25 +23,56 @@
</v-chip-group>
</v-list-item-content>
<v-list-item-action>
<v-btn icon @click="showInfo(idx)">
<v-icon color="grey lighten-1">mdi-information</v-icon>
</v-btn>
<v-row>
<v-col>
<v-btn
icon
@click="showQRCode(idx)"
v-if="proxy.type !== 'http'"
>
<v-icon small color="grey lighten-1">mdi-qrcode</v-icon>
</v-btn>
</v-col>
<v-col>
<v-btn icon @click="showInfo(idx)">
<v-icon small color="grey lighten-1">mdi-information</v-icon>
</v-btn>
</v-col>
</v-row>
</v-list-item-action>
</v-list-item>
<v-dialog
v-model="dialog"
>
<v-card>
<v-card
color="primary darken-1"
>
<v-card-title>
{{info.name}}
{{ info.name }}
</v-card-title>
<v-card-text>
{{info.isp}}
{{ info.isp }}
<br/>
{{info.region}}
{{ info.region }}
<br/>
{{info.ip}}
{{ info.ip }}
</v-card-text>
</v-card>
</v-dialog>
<v-dialog
v-model="showQR"
>
<v-card
color="primary darken-1"
>
<v-card-title>
{{ info.name }}
</v-card-title>
<v-card-text>
<vue-q-r-code-component
:text="qr"
/>
</v-card-text>
</v-card>
</v-dialog>
@ -50,22 +81,27 @@
<script>
import {axios} from "@/utils";
import VueQRCodeComponent from 'vue-qrcode-component';
const flags = new Map([[ "AC" , "🇦🇨" ] , [ "AF" , "🇦🇫" ] , [ "AI" , "🇦🇮" ] , [ "AL" , "🇦🇱" ] , [ "AM" , "🇦🇲" ] , [ "AQ" , "🇦🇶" ] , [ "AR" , "🇦🇷" ] , [ "AS" , "🇦🇸" ] , [ "AT" , "🇦🇹" ] , [ "AU" , "🇦🇺" ] , [ "AW" , "🇦🇼" ] , [ "AX" , "🇦🇽" ] , [ "AZ" , "🇦🇿" ] , [ "BB" , "🇧🇧" ] , [ "BD" , "🇧🇩" ] , [ "BE" , "🇧🇪" ] , [ "BF" , "🇧🇫" ] , [ "BG" , "🇧🇬" ] , [ "BH" , "🇧🇭" ] , [ "BI" , "🇧🇮" ] , [ "BJ" , "🇧🇯" ] , [ "BM" , "🇧🇲" ] , [ "BN" , "🇧🇳" ] , [ "BO" , "🇧🇴" ] , [ "BR" , "🇧🇷" ] , [ "BS" , "🇧🇸" ] , [ "BT" , "🇧🇹" ] , [ "BV" , "🇧🇻" ] , [ "BW" , "🇧🇼" ] , [ "BY" , "🇧🇾" ] , [ "BZ" , "🇧🇿" ] , [ "CA" , "🇨🇦" ] , [ "CF" , "🇨🇫" ] , [ "CH" , "🇨🇭" ] , [ "CK" , "🇨🇰" ] , [ "CL" , "🇨🇱" ] , [ "CM" , "🇨🇲" ] , [ "CN" , "🇨🇳" ] , [ "CO" , "🇨🇴" ] , [ "CP" , "🇨🇵" ] , [ "CR" , "🇨🇷" ] , [ "CU" , "🇨🇺" ] , [ "CV" , "🇨🇻" ] , [ "CW" , "🇨🇼" ] , [ "CX" , "🇨🇽" ] , [ "CY" , "🇨🇾" ] , [ "CZ" , "🇨🇿" ] , [ "DE" , "🇩🇪" ] , [ "DG" , "🇩🇬" ] , [ "DJ" , "🇩🇯" ] , [ "DK" , "🇩🇰" ] , [ "DM" , "🇩🇲" ] , [ "DO" , "🇩🇴" ] , [ "DZ" , "🇩🇿" ] , [ "EA" , "🇪🇦" ] , [ "EC" , "🇪🇨" ] , [ "EE" , "🇪🇪" ] , [ "EG" , "🇪🇬" ] , [ "EH" , "🇪🇭" ] , [ "ER" , "🇪🇷" ] , [ "ES" , "🇪🇸" ] , [ "ET" , "🇪🇹" ] , [ "EU" , "🇪🇺" ] , [ "FI" , "🇫🇮" ] , [ "FJ" , "🇫🇯" ] , [ "FK" , "🇫🇰" ] , [ "FM" , "🇫🇲" ] , [ "FO" , "🇫🇴" ] , [ "FR" , "🇫🇷" ] , [ "GA" , "🇬🇦" ] , [ "GB" , "🇬🇧" ] , [ "HK" , "🇭🇰" ] ,["HU","🇭🇺"], [ "ID" , "🇮🇩" ] , [ "IE" , "🇮🇪" ] , [ "IL" , "🇮🇱" ] , [ "IM" , "🇮🇲" ] , [ "IN" , "🇮🇳" ] , [ "IS" , "🇮🇸" ] , [ "IT" , "🇮🇹" ] , [ "JP" , "🇯🇵" ] , [ "KR" , "🇰🇷" ] , [ "LU" , "🇱🇺" ] , [ "MO" , "🇲🇴" ] , [ "MX" , "🇲🇽" ] , [ "MY" , "🇲🇾" ] , [ "NL" , "🇳🇱" ] , [ "PH" , "🇵🇭" ] , [ "RO" , "🇷🇴" ] , [ "RS" , "🇷🇸" ] , [ "RU" , "🇷🇺" ] , [ "RW" , "🇷🇼" ] , [ "SA" , "🇸🇦" ] , [ "SB" , "🇸🇧" ] , [ "SC" , "🇸🇨" ] , [ "SD" , "🇸🇩" ] , [ "SE" , "🇸🇪" ] , [ "SG" , "🇸🇬" ] , [ "TH" , "🇹🇭" ] , [ "TN" , "🇹🇳" ] , [ "TO" , "🇹🇴" ] , [ "TR" , "🇹🇷" ] , [ "TV" , "🇹🇻" ] , [ "TW" , "🇨🇳" ] , [ "UK" , "🇬🇧" ] , [ "UM" , "🇺🇲" ] , [ "US" , "🇺🇸" ] , [ "UY" , "🇺🇾" ] , [ "UZ" , "🇺🇿" ] , [ "VA" , "🇻🇦" ] , [ "VE" , "🇻🇪" ] , [ "VG" , "🇻🇬" ] , [ "VI" , "🇻🇮" ] , [ "VN" , "🇻🇳" ] , [ "ZA" , "🇿🇦"]])
const flags = new Map([["AC", "🇦🇨"], ["AF", "🇦🇫"], ["AI", "🇦🇮"], ["AL", "🇦🇱"], ["AM", "🇦🇲"], ["AQ", "🇦🇶"], ["AR", "🇦🇷"], ["AS", "🇦🇸"], ["AT", "🇦🇹"], ["AU", "🇦🇺"], ["AW", "🇦🇼"], ["AX", "🇦🇽"], ["AZ", "🇦🇿"], ["BB", "🇧🇧"], ["BD", "🇧🇩"], ["BE", "🇧🇪"], ["BF", "🇧🇫"], ["BG", "🇧🇬"], ["BH", "🇧🇭"], ["BI", "🇧🇮"], ["BJ", "🇧🇯"], ["BM", "🇧🇲"], ["BN", "🇧🇳"], ["BO", "🇧🇴"], ["BR", "🇧🇷"], ["BS", "🇧🇸"], ["BT", "🇧🇹"], ["BV", "🇧🇻"], ["BW", "🇧🇼"], ["BY", "🇧🇾"], ["BZ", "🇧🇿"], ["CA", "🇨🇦"], ["CF", "🇨🇫"], ["CH", "🇨🇭"], ["CK", "🇨🇰"], ["CL", "🇨🇱"], ["CM", "🇨🇲"], ["CN", "🇨🇳"], ["CO", "🇨🇴"], ["CP", "🇨🇵"], ["CR", "🇨🇷"], ["CU", "🇨🇺"], ["CV", "🇨🇻"], ["CW", "🇨🇼"], ["CX", "🇨🇽"], ["CY", "🇨🇾"], ["CZ", "🇨🇿"], ["DE", "🇩🇪"], ["DG", "🇩🇬"], ["DJ", "🇩🇯"], ["DK", "🇩🇰"], ["DM", "🇩🇲"], ["DO", "🇩🇴"], ["DZ", "🇩🇿"], ["EA", "🇪🇦"], ["EC", "🇪🇨"], ["EE", "🇪🇪"], ["EG", "🇪🇬"], ["EH", "🇪🇭"], ["ER", "🇪🇷"], ["ES", "🇪🇸"], ["ET", "🇪🇹"], ["EU", "🇪🇺"], ["FI", "🇫🇮"], ["FJ", "🇫🇯"], ["FK", "🇫🇰"], ["FM", "🇫🇲"], ["FO", "🇫🇴"], ["FR", "🇫🇷"], ["GA", "🇬🇦"], ["GB", "🇬🇧"], ["HK", "🇭🇰"], ["HU", "🇭🇺"], ["ID", "🇮🇩"], ["IE", "🇮🇪"], ["IL", "🇮🇱"], ["IM", "🇮🇲"], ["IN", "🇮🇳"], ["IS", "🇮🇸"], ["IT", "🇮🇹"], ["JP", "🇯🇵"], ["KR", "🇰🇷"], ["LU", "🇱🇺"], ["MO", "🇲🇴"], ["MX", "🇲🇽"], ["MY", "🇲🇾"], ["NL", "🇳🇱"], ["PH", "🇵🇭"], ["RO", "🇷🇴"], ["RS", "🇷🇸"], ["RU", "🇷🇺"], ["RW", "🇷🇼"], ["SA", "🇸🇦"], ["SB", "🇸🇧"], ["SC", "🇸🇨"], ["SD", "🇸🇩"], ["SE", "🇸🇪"], ["SG", "🇸🇬"], ["TH", "🇹🇭"], ["TN", "🇹🇳"], ["TO", "🇹🇴"], ["TR", "🇹🇷"], ["TV", "🇹🇻"], ["TW", "🇨🇳"], ["UK", "🇬🇧"], ["UM", "🇺🇲"], ["US", "🇺🇸"], ["UY", "🇺🇾"], ["UZ", "🇺🇿"], ["VA", "🇻🇦"], ["VE", "🇻🇪"], ["VG", "🇻🇬"], ["VI", "🇻🇮"], ["VN", "🇻🇳"], ["ZA", "🇿🇦"]])
export default {
name: "ProxyList",
props: ['url', 'sub'],
components: {VueQRCodeComponent},
data: function () {
return {
proxies: [],
uris: [],
dialog: false,
showQR: false,
info: {
name: "",
isp: "",
region: "",
ip: ""
}
},
qr: ""
}
},
methods: {
@ -75,24 +111,48 @@ export default {
})
},
fetch() {
axios.get(this.url).then(resp => {
async fetch() {
await axios.get(this.url).then(resp => {
const {data} = resp;
this.proxies = data.split("\n").map(p => JSON.parse(p));
if (data.indexOf("\n") !== -1)
this.proxies = data.split("\n").map(p => JSON.parse(p));
else
this.proxies = [data];
}).catch(err => {
this.$store.commit("SET_ERROR_MESSAGE", err);
});
await axios.get(`${this.url}?target=URI`).then(resp => {
const {data} = resp;
if (data.indexOf("\n") !== -1)
this.uris = data.split("\n");
else
this.uris = [data];
});
// fix http offset
this.proxies.forEach((p, idx) => {
if (p.type === 'http') {
this.uris.splice(idx, 0, null);
}
})
},
async showInfo(idx) {
const {server, name} = this.proxies[idx];
const res = await axios.get(`/IP_API/${encodeURIComponent(server)}`).then(resp => resp.data);
this.info.name = name;
this.info.isp = `ISP${res.org}`;
this.info.isp = `ISP${res.isp}`;
this.info.region = `地区:${flags.get(res.countryCode)} ${res.regionName} ${res.city}`;
this.info.ip = `IP${res.query}`
this.dialog = true
},
async showQRCode(idx) {
this.qr = this.uris[idx];
this.info.name = this.proxies[idx].name;
this.showQR = true;
}
},
created() {
this.fetch();