Working room & client refactor
This commit is contained in:
207
client/package-lock.json
generated
207
client/package-lock.json
generated
@@ -1003,6 +1003,14 @@
|
|||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@chenfengyuan/vue-qrcode": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@chenfengyuan/vue-qrcode/-/vue-qrcode-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-hwy1d4YMJAyEh+V7dLPG8eAKACRvugzSB4ylwb6QNqo84KHTF50/5EJcBYdUhTRPfAqrxG0i6jDAXONWOGyQbQ==",
|
||||||
|
"requires": {
|
||||||
|
"qrcode": "^1.4.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@hapi/address": {
|
"@hapi/address": {
|
||||||
"version": "2.1.4",
|
"version": "2.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
|
||||||
@@ -1980,14 +1988,12 @@
|
|||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"color-convert": "^1.9.0"
|
"color-convert": "^1.9.0"
|
||||||
}
|
}
|
||||||
@@ -2389,8 +2395,7 @@
|
|||||||
"base64-js": {
|
"base64-js": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
|
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"batch": {
|
"batch": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
@@ -2688,11 +2693,29 @@
|
|||||||
"isarray": "^1.0.0"
|
"isarray": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"buffer-alloc": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
|
||||||
|
"requires": {
|
||||||
|
"buffer-alloc-unsafe": "^1.1.0",
|
||||||
|
"buffer-fill": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buffer-alloc-unsafe": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg=="
|
||||||
|
},
|
||||||
|
"buffer-fill": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw="
|
||||||
|
},
|
||||||
"buffer-from": {
|
"buffer-from": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"buffer-indexof": {
|
"buffer-indexof": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@@ -2878,6 +2901,11 @@
|
|||||||
"caller-callsite": "^2.0.0"
|
"caller-callsite": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"callforth": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/callforth/-/callforth-0.3.1.tgz",
|
||||||
|
"integrity": "sha512-Q2zPfqnwoKsb1DTVCr4lmhe49wKNBsMmNlbudjleu3/co+Nw1pOqFHYJHrW3VZ253ou9AAr+xauQR0C55NPdzA=="
|
||||||
|
},
|
||||||
"callsites": {
|
"callsites": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
|
||||||
@@ -2897,8 +2925,7 @@
|
|||||||
"camelcase": {
|
"camelcase": {
|
||||||
"version": "5.3.1",
|
"version": "5.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"caniuse-api": {
|
"caniuse-api": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
@@ -3253,7 +3280,6 @@
|
|||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"color-name": "1.1.3"
|
"color-name": "1.1.3"
|
||||||
}
|
}
|
||||||
@@ -3261,8 +3287,7 @@
|
|||||||
"color-name": {
|
"color-name": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"color-string": {
|
"color-string": {
|
||||||
"version": "1.5.3",
|
"version": "1.5.3",
|
||||||
@@ -3925,8 +3950,7 @@
|
|||||||
"decamelize": {
|
"decamelize": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"decode-uri-component": {
|
"decode-uri-component": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
@@ -4231,6 +4255,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dijkstrajs": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs="
|
||||||
|
},
|
||||||
"dir-glob": {
|
"dir-glob": {
|
||||||
"version": "2.2.2",
|
"version": "2.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
|
||||||
@@ -5534,7 +5563,6 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
||||||
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"locate-path": "^3.0.0"
|
"locate-path": "^3.0.0"
|
||||||
}
|
}
|
||||||
@@ -5703,8 +5731,7 @@
|
|||||||
"get-caller-file": {
|
"get-caller-file": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"get-own-enumerable-property-symbols": {
|
"get-own-enumerable-property-symbols": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
@@ -6236,8 +6263,7 @@
|
|||||||
"ieee754": {
|
"ieee754": {
|
||||||
"version": "1.1.13",
|
"version": "1.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
|
||||||
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
|
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"iferr": {
|
"iferr": {
|
||||||
"version": "0.1.5",
|
"version": "0.1.5",
|
||||||
@@ -7151,7 +7177,6 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"p-locate": "^3.0.0",
|
"p-locate": "^3.0.0",
|
||||||
"path-exists": "^3.0.0"
|
"path-exists": "^3.0.0"
|
||||||
@@ -8061,7 +8086,6 @@
|
|||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"p-try": "^2.0.0"
|
"p-try": "^2.0.0"
|
||||||
}
|
}
|
||||||
@@ -8070,7 +8094,6 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"p-limit": "^2.0.0"
|
"p-limit": "^2.0.0"
|
||||||
}
|
}
|
||||||
@@ -8096,8 +8119,7 @@
|
|||||||
"p-try": {
|
"p-try": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"pako": {
|
"pako": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
@@ -8210,8 +8232,7 @@
|
|||||||
"path-exists": {
|
"path-exists": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"path-is-absolute": {
|
"path-is-absolute": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
@@ -8315,6 +8336,11 @@
|
|||||||
"find-up": "^3.0.0"
|
"find-up": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pngjs": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="
|
||||||
|
},
|
||||||
"pnp-webpack-plugin": {
|
"pnp-webpack-plugin": {
|
||||||
"version": "1.6.4",
|
"version": "1.6.4",
|
||||||
"resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz",
|
||||||
@@ -9090,6 +9116,110 @@
|
|||||||
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
|
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"qrcode": {
|
||||||
|
"version": "1.4.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz",
|
||||||
|
"integrity": "sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==",
|
||||||
|
"requires": {
|
||||||
|
"buffer": "^5.4.3",
|
||||||
|
"buffer-alloc": "^1.2.0",
|
||||||
|
"buffer-from": "^1.1.1",
|
||||||
|
"dijkstrajs": "^1.0.1",
|
||||||
|
"isarray": "^2.0.1",
|
||||||
|
"pngjs": "^3.3.0",
|
||||||
|
"yargs": "^13.2.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"buffer": {
|
||||||
|
"version": "5.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
|
||||||
|
"integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
|
||||||
|
"requires": {
|
||||||
|
"base64-js": "^1.0.2",
|
||||||
|
"ieee754": "^1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cliui": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||||
|
"requires": {
|
||||||
|
"string-width": "^3.1.0",
|
||||||
|
"strip-ansi": "^5.2.0",
|
||||||
|
"wrap-ansi": "^5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"emoji-regex": {
|
||||||
|
"version": "7.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||||
|
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
|
||||||
|
},
|
||||||
|
"is-fullwidth-code-point": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
|
||||||
|
},
|
||||||
|
"isarray": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
|
||||||
|
},
|
||||||
|
"string-width": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||||
|
"requires": {
|
||||||
|
"emoji-regex": "^7.0.1",
|
||||||
|
"is-fullwidth-code-point": "^2.0.0",
|
||||||
|
"strip-ansi": "^5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "^4.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wrap-ansi": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "^3.2.0",
|
||||||
|
"string-width": "^3.0.0",
|
||||||
|
"strip-ansi": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yargs": {
|
||||||
|
"version": "13.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
|
||||||
|
"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
|
||||||
|
"requires": {
|
||||||
|
"cliui": "^5.0.0",
|
||||||
|
"find-up": "^3.0.0",
|
||||||
|
"get-caller-file": "^2.0.1",
|
||||||
|
"require-directory": "^2.1.1",
|
||||||
|
"require-main-filename": "^2.0.0",
|
||||||
|
"set-blocking": "^2.0.0",
|
||||||
|
"string-width": "^3.0.0",
|
||||||
|
"which-module": "^2.0.0",
|
||||||
|
"y18n": "^4.0.0",
|
||||||
|
"yargs-parser": "^13.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yargs-parser": {
|
||||||
|
"version": "13.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
|
||||||
|
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
|
||||||
|
"requires": {
|
||||||
|
"camelcase": "^5.0.0",
|
||||||
|
"decamelize": "^1.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"qs": {
|
"qs": {
|
||||||
"version": "6.5.2",
|
"version": "6.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||||
@@ -9489,14 +9619,12 @@
|
|||||||
"require-directory": {
|
"require-directory": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
|
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"require-main-filename": {
|
"require-main-filename": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"requires-port": {
|
"requires-port": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@@ -9832,8 +9960,7 @@
|
|||||||
"set-blocking": {
|
"set-blocking": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"set-value": {
|
"set-value": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
@@ -11290,6 +11417,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vue-qrcode-reader": {
|
||||||
|
"version": "2.3.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-qrcode-reader/-/vue-qrcode-reader-2.3.11.tgz",
|
||||||
|
"integrity": "sha512-5A/zeGpIG8ky1GHIv+L6QTlvyugilRmskQEOppa4+lQ4MVKLVeL55EYnnBw+YQ0N45LBVcUwBLr//AHjdfkmZA==",
|
||||||
|
"requires": {
|
||||||
|
"callforth": "^0.3.1",
|
||||||
|
"core-js": "^3.6.5",
|
||||||
|
"vue": "^2.6.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
"vue-router": {
|
"vue-router": {
|
||||||
"version": "3.3.4",
|
"version": "3.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.3.4.tgz",
|
||||||
@@ -11957,8 +12094,7 @@
|
|||||||
"which-module": {
|
"which-module": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
||||||
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
|
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"word-wrap": {
|
"word-wrap": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
@@ -12211,8 +12347,7 @@
|
|||||||
"y18n": {
|
"y18n": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
|
|||||||
@@ -8,10 +8,12 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@chenfengyuan/vue-qrcode": "^1.0.2",
|
||||||
"buefy": "^0.8.20",
|
"buefy": "^0.8.20",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"register-service-worker": "^1.7.1",
|
"register-service-worker": "^1.7.1",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
|
"vue-qrcode-reader": "^2.3.11",
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vue-youtube": "^1.4.0",
|
"vue-youtube": "^1.4.0",
|
||||||
"vuex": "^3.4.0"
|
"vuex": "^3.4.0"
|
||||||
|
|||||||
43
client/src/components/Admin.vue
Normal file
43
client/src/components/Admin.vue
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<b-button @click="broadcastStatus">Force status update</b-button>
|
||||||
|
<b-table :data="usersList" striped hoverable>
|
||||||
|
<template slot-scope="props">
|
||||||
|
<b-table-column field="name" label="Name">
|
||||||
|
{{props.row.name}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="connection" label="Connection">
|
||||||
|
{{props.row.connection.signalingState}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="data" label="DataChannel">
|
||||||
|
{{props.row.dataChannel.readyState}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column>
|
||||||
|
<b-button @click="kickUser" icon-left="karate" type="is-dark"/>
|
||||||
|
</b-table-column>
|
||||||
|
</template>
|
||||||
|
</b-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Admin',
|
||||||
|
computed: {
|
||||||
|
usersList () {
|
||||||
|
return this.$store.state.rtc.peers
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
broadcastStatus () {
|
||||||
|
this.$store.dispatch('rtc/broadcast', { message: this.$store.state.room.roomStatus, type: 'status' })
|
||||||
|
},
|
||||||
|
kickUser () {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
23
client/src/components/Invite.vue
Normal file
23
client/src/components/Invite.vue
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1 class="subtitle">{{roomCode}}</h1>
|
||||||
|
<qrcode :value="roomCode" :options="{ width: 200 }"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import qrcode from '@chenfengyuan/vue-qrcode'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Invite',
|
||||||
|
components: {
|
||||||
|
qrcode
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
roomCode: {
|
||||||
|
type: String,
|
||||||
|
default: 'abc'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,13 +1,102 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="player"></div>
|
<div>
|
||||||
|
<youtube
|
||||||
|
ref="youtube"
|
||||||
|
:video-id="roomStatus.current.linkID"
|
||||||
|
:player-vars="playerVars"
|
||||||
|
@playing="roomStatus.player.playing">
|
||||||
|
</youtube>
|
||||||
|
<b-field position="is-centered">
|
||||||
|
<p class="control">
|
||||||
|
<b-button @click="play" icon-right="play"/>
|
||||||
|
<b-button @click="mute" icon-right="volume-mute"/>
|
||||||
|
<b-button @click="skip" icon-right="skip-next"/>
|
||||||
|
<b-slider :min="0" :max="100" @change="volume"/>
|
||||||
|
</p>
|
||||||
|
</b-field>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
|
name: 'Player',
|
||||||
|
props: ['settings'],
|
||||||
|
computed: {
|
||||||
|
isAdmin () {
|
||||||
|
return this.$store.state.room.admin
|
||||||
|
},
|
||||||
|
roomStatus () {
|
||||||
|
return this.$store.state.room.roomStatus
|
||||||
|
},
|
||||||
|
player () {
|
||||||
|
return this.$refs.youtube.player
|
||||||
|
},
|
||||||
|
playerVars () {
|
||||||
|
const adminVars = {
|
||||||
|
autoplay: 1,
|
||||||
|
controls: 1,
|
||||||
|
disablekb: 0,
|
||||||
|
modestbranding: 1,
|
||||||
|
rel: 0
|
||||||
|
}
|
||||||
|
const userVars = {
|
||||||
|
autoplay: 1,
|
||||||
|
controls: 1,
|
||||||
|
disablekb: 1,
|
||||||
|
modestbranding: 1,
|
||||||
|
rel: 0
|
||||||
|
}
|
||||||
|
return this.isAdmin ? adminVars : userVars
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.player.addEventListener('onStateChange', this.playerStateChange)
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
roomStatus: function (status) {
|
||||||
|
if (!this.settings.playLink) {
|
||||||
|
this.player.pauseVideo()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.player.seekTo(status.player.timeCode, true)
|
||||||
|
if (status.player.playing) this.player.playVideo()
|
||||||
|
else this.player.pauseVideo()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async playerStateChange (event) {
|
||||||
|
console.log('[PLAYER] Status change ' + event.data)
|
||||||
|
console.log(await event.target.getVideoData())
|
||||||
|
if (this.isAdmin) {
|
||||||
|
this.$store.dispatch('room/setCurrent', {
|
||||||
|
playerStatus: event.data,
|
||||||
|
timeCode: await this.player.getCurrentTime(),
|
||||||
|
title: await event.target.getVideoData().title
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
play () {
|
||||||
|
if (this.roomStatus.player.playing) this.player.pauseVideo()
|
||||||
|
else this.player.playVideo()
|
||||||
|
},
|
||||||
|
mute () {
|
||||||
|
if (this.player.isMuted()) this.player.unMute()
|
||||||
|
else this.player.mute()
|
||||||
|
},
|
||||||
|
volume (volume) {
|
||||||
|
this.player.setVolume(volume)
|
||||||
|
},
|
||||||
|
skip () {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style local>
|
||||||
|
.controls {
|
||||||
|
text-align: center;
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
86
client/src/components/Playlist.vue
Normal file
86
client/src/components/Playlist.vue
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<b-button icon-left="plus" @click="addLinkPrompt">Add link</b-button>
|
||||||
|
<b-table :data="roomStatus.playlist" striped hoverable default-sort="vote">
|
||||||
|
<template slot-scope="props">
|
||||||
|
<b-table-column field="title" label="Title">
|
||||||
|
{{props.row.title}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="link" label="Link">
|
||||||
|
{{props.row.link}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="vote" label="Votes">
|
||||||
|
{{props.row.votes}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="voters" label="Voters" :visible="isAdmin">
|
||||||
|
{{props.row.voters}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column>
|
||||||
|
<b-button v-if="hasVoted(props.row)" icon-left="arrow-down-bold-outline" type="is-dark" @click="vote (props.row.link, props.row.linkID, false)"/>
|
||||||
|
<b-button v-else icon-left="arrow-up-bold-outline" type="is-dark" @click="vote (props.row.link, props.row.linkID, true)"/>
|
||||||
|
</b-table-column>
|
||||||
|
</template>
|
||||||
|
</b-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Palylist',
|
||||||
|
computed: {
|
||||||
|
isAdmin () {
|
||||||
|
return this.$store.state.room.admin
|
||||||
|
},
|
||||||
|
roomStatus () {
|
||||||
|
return this.$store.state.room.roomStatus
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addLinkPrompt () {
|
||||||
|
this.$buefy.dialog.prompt({
|
||||||
|
message: 'Add a youtube link',
|
||||||
|
trapFocus: true,
|
||||||
|
inputAttrs: {
|
||||||
|
placeholder: 'https://www.youtube.com/watch?v=YItIK09bpKk',
|
||||||
|
minlength: 10
|
||||||
|
},
|
||||||
|
cancelText: 'Nah',
|
||||||
|
confirmText: 'Add',
|
||||||
|
onConfirm: (link) => this.addLink(link)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addLink (link) {
|
||||||
|
const linkID = this.$youtube.getIdFromUrl(link)
|
||||||
|
if (linkID === null) {
|
||||||
|
this.$buefy.toast.open('Invalid youtube link')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.vote(link, linkID, true)
|
||||||
|
},
|
||||||
|
vote (link, linkID, isPositive) {
|
||||||
|
if (this.isAdmin) {
|
||||||
|
this.$store.dispatch('room/vote', { link: link, linkID: linkID, isPositive: isPositive, voterName: this.$store.state.rtc.name })
|
||||||
|
} else {
|
||||||
|
this.sendVote(link, linkID, isPositive)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sendVote (link, linkID, isPositive) {
|
||||||
|
const message = {
|
||||||
|
type: 'vote',
|
||||||
|
link: link,
|
||||||
|
linkID: linkID,
|
||||||
|
isPositive: isPositive,
|
||||||
|
voterName: this.$store.state.rtc.name
|
||||||
|
}
|
||||||
|
this.$store.dispatch('rtc/broadcast', { message: message, type: 'vote' })
|
||||||
|
},
|
||||||
|
hasVoted (play) {
|
||||||
|
return play.voters.includes(this.$store.state.rtc.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
67
client/src/components/QRReader.vue
Normal file
67
client/src/components/QRReader.vue
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<p class="error">{{ error }}</p>
|
||||||
|
<qrcode-stream @decode="onDecode" @init="onInit" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { QrcodeStream } from 'vue-qrcode-reader'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'QRReader',
|
||||||
|
components: {
|
||||||
|
QrcodeStream
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
result: '',
|
||||||
|
error: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onDecode (result) {
|
||||||
|
this.result = result
|
||||||
|
this.$emit('get-code', this.result)
|
||||||
|
},
|
||||||
|
async onInit (promise) {
|
||||||
|
try {
|
||||||
|
await promise
|
||||||
|
} catch (error) {
|
||||||
|
if (error.name === 'NotAllowedError') {
|
||||||
|
this.error = 'Missing camera permissions'
|
||||||
|
} else if (error.name === 'NotFoundError') {
|
||||||
|
this.error = 'No camera'
|
||||||
|
} else if (error.name === 'NotSupportedError') {
|
||||||
|
this.error = 'https ?'
|
||||||
|
} else if (error.name === 'NotReadableError') {
|
||||||
|
this.error = 'Camera in use'
|
||||||
|
} else if (error.name === 'OverconstrainedError') {
|
||||||
|
this.error = 'Shitty camera'
|
||||||
|
} else if (error.name === 'StreamApiNotSupportedError') {
|
||||||
|
this.error = 'Shitty browser'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showAlert (message) {
|
||||||
|
this.$buefy.dialog.alert({
|
||||||
|
title: 'Erreur',
|
||||||
|
message: message,
|
||||||
|
type: 'is-danger',
|
||||||
|
hasIcon: true,
|
||||||
|
icon: 'alert-circle-outline',
|
||||||
|
iconPack: 'mdi',
|
||||||
|
ariaRole: 'alertdialog',
|
||||||
|
ariaModal: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.error {
|
||||||
|
font-weight: bold;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -5,10 +5,12 @@ const state = {
|
|||||||
roomCode: '',
|
roomCode: '',
|
||||||
player: {
|
player: {
|
||||||
timeCode: 0,
|
timeCode: 0,
|
||||||
|
timeLength: 0,
|
||||||
playing: true
|
playing: true
|
||||||
},
|
},
|
||||||
current: {
|
current: {
|
||||||
link: '',
|
link: '',
|
||||||
|
linkID: '',
|
||||||
title: '',
|
title: '',
|
||||||
votes: 0,
|
votes: 0,
|
||||||
voters: []
|
voters: []
|
||||||
@@ -33,28 +35,30 @@ const actions = {
|
|||||||
setAdmin ({ commit }) {
|
setAdmin ({ commit }) {
|
||||||
commit('SET_ADMIN')
|
commit('SET_ADMIN')
|
||||||
},
|
},
|
||||||
vote ({ commit, dispatch, state }, { link, isPositive, voterName }) {
|
vote ({ commit, dispatch, state }, { link, linkID, isPositive, voterName }) {
|
||||||
console.log('vote on ' + link + ' (' + isPositive + ') by ' + voterName)
|
console.log('vote on ' + link + ' | ' + linkID + ' (' + isPositive + ') by ' + voterName)
|
||||||
if (isPositive) {
|
if (isPositive) {
|
||||||
commit('ADD_VOTE', {
|
commit('ADD_VOTE', {
|
||||||
|
linkID: linkID,
|
||||||
link: link,
|
link: link,
|
||||||
voterName: voterName
|
voterName: voterName
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
commit('REMOVE_VOTE', {
|
commit('REMOVE_VOTE', {
|
||||||
link: link,
|
linkID: linkID,
|
||||||
voterName: voterName
|
voterName: voterName
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true })
|
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true })
|
||||||
},
|
},
|
||||||
setCurrent ({ commit, dispatch }, { playerStatus, timeCode }) {
|
setCurrent ({ commit, dispatch }, { playerStatus, timeCode, title }) {
|
||||||
switch (playerStatus) {
|
switch (playerStatus) {
|
||||||
case 0:
|
case 0:
|
||||||
commit('CURRENT_END')
|
commit('CURRENT_END')
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
commit('CURRENT_PLAY', timeCode)
|
commit('CURRENT_PLAY', timeCode)
|
||||||
|
commit('SET_CURRENTTITLE', title)
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
commit('CURRENT_PAUSE', timeCode)
|
commit('CURRENT_PAUSE', timeCode)
|
||||||
@@ -77,11 +81,15 @@ const mutations = {
|
|||||||
SET_ADMIN (state) {
|
SET_ADMIN (state) {
|
||||||
state.admin = true
|
state.admin = true
|
||||||
},
|
},
|
||||||
ADD_VOTE (state, { link, voterName }) {
|
SET_CURRENTTITLE (state, title) {
|
||||||
var play = state.roomStatus.playlist.find(play => play.link === link)
|
state.roomStatus.current.title = title
|
||||||
|
},
|
||||||
|
ADD_VOTE (state, { link, linkID, voterName }) {
|
||||||
|
var play = state.roomStatus.playlist.find(play => play.linkID === linkID)
|
||||||
if (play === undefined) {
|
if (play === undefined) {
|
||||||
play = {
|
play = {
|
||||||
link: link,
|
link: link,
|
||||||
|
linkID: linkID,
|
||||||
votes: 1,
|
votes: 1,
|
||||||
voters: [
|
voters: [
|
||||||
voterName
|
voterName
|
||||||
@@ -94,8 +102,8 @@ const mutations = {
|
|||||||
play.voters.push(voterName)
|
play.voters.push(voterName)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
REMOVE_VOTE (state, { link, voterName }) {
|
REMOVE_VOTE (state, { linkID, voterName }) {
|
||||||
var play = state.roomStatus.playlist.find(play => play.link === link)
|
var play = state.roomStatus.playlist.find(play => play.linkID === linkID)
|
||||||
play.votes--
|
play.votes--
|
||||||
const index = play.voters.indexOf(voterName)
|
const index = play.voters.indexOf(voterName)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
@@ -111,10 +119,13 @@ const mutations = {
|
|||||||
},
|
},
|
||||||
CURRENT_END (state) {
|
CURRENT_END (state) {
|
||||||
if (state.roomStatus.playlist.length === 0) {
|
if (state.roomStatus.playlist.length === 0) {
|
||||||
state.roomStatus.current.link = ''
|
state.roomStatus.current = {
|
||||||
state.roomStatus.current.title = ''
|
link: '',
|
||||||
state.roomStatus.current.votes = 0
|
linkID: '',
|
||||||
state.roomStatus.current.voters = []
|
title: '',
|
||||||
|
votes: 0,
|
||||||
|
voters: []
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
state.roomStatus.playlist.sort((a, b) => {
|
state.roomStatus.playlist.sort((a, b) => {
|
||||||
return b.votes - a.votes
|
return b.votes - a.votes
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ function handleDataChannelStateChangeEvent () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleDataChannelCallback (event) {
|
function handleDataChannelCallback (event) {
|
||||||
console.log('[RTC] data channel callback ' + event)
|
console.log('[RTC] data channel callback ' + event + ' target ' + event.target)
|
||||||
var peer = lastPeer
|
var peer = lastPeer
|
||||||
peer.dataChannel = event.channel
|
peer.dataChannel = event.channel
|
||||||
peer.dataChannel.onmessage = handleDataChannelMessage
|
peer.dataChannel.onmessage = handleDataChannelMessage
|
||||||
@@ -185,7 +185,7 @@ function handleDataChannelMessage (event) {
|
|||||||
store.dispatch('room/setRoomStatus', data.message)
|
store.dispatch('room/setRoomStatus', data.message)
|
||||||
break
|
break
|
||||||
case 'vote':
|
case 'vote':
|
||||||
store.dispatch('room/vote', { link: data.message.link, isPositive: data.message.isPositive, voterName: data.message.voterName })
|
store.dispatch('room/vote', { link: data.message.link, linkID: data.message.linkID, isPositive: data.message.isPositive, voterName: data.message.voterName })
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,34 @@
|
|||||||
</div>
|
</div>
|
||||||
<h1 v-else class="title has-text-danger">Server offline</h1>
|
<h1 v-else class="title has-text-danger">Server offline</h1>
|
||||||
<hr>
|
<hr>
|
||||||
|
<b-field position="is-centered">
|
||||||
<b-button type="is-primary" @click="connectToRoomPrompt">Join a room</b-button>
|
<b-button type="is-primary" @click="connectToRoomPrompt">Join a room</b-button>
|
||||||
|
</b-field>
|
||||||
|
<b-field position="is-centered">
|
||||||
|
<b-button @click="isQRModalActive = true" icon-right="qrcode"/>
|
||||||
|
</b-field>
|
||||||
<hr>
|
<hr>
|
||||||
<b-button type="is-primary" @click="makeRoomPrompt">Make a room</b-button>
|
<b-button type="is-primary" @click="makeRoomPrompt">Make a room</b-button>
|
||||||
|
<b-modal :active.sync="isQRModalActive" has-modal-card trap-focus>
|
||||||
|
<QRReader v-on:get-code="connectToRoom"/>
|
||||||
|
</b-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { send } from '../store/signalPlugin'
|
import { send } from '../store/signalPlugin'
|
||||||
|
import QRReader from './../components/QRReader'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
|
components: {
|
||||||
|
QRReader
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
isQRModalActive: false
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
serverStatus () {
|
serverStatus () {
|
||||||
return this.$store.state.app.serverStatus
|
return this.$store.state.app.serverStatus
|
||||||
|
|||||||
@@ -4,70 +4,20 @@
|
|||||||
<h2 class="subtitle">{{roomStatus.current.title}}</h2>
|
<h2 class="subtitle">{{roomStatus.current.title}}</h2>
|
||||||
|
|
||||||
<b-tabs>
|
<b-tabs>
|
||||||
<b-tab-item label="Player" :visible="settings.showPlayer">
|
<b-tab-item label="Playlist">
|
||||||
<div class="playerDiv">
|
<Playlist />
|
||||||
<youtube
|
|
||||||
:video-id="roomStatus.current.link"
|
|
||||||
nocookie="true"
|
|
||||||
ref="youtube"
|
|
||||||
@playing="roomStatus.player.playing"
|
|
||||||
></youtube>
|
|
||||||
</div>
|
|
||||||
</b-tab-item>
|
</b-tab-item>
|
||||||
|
|
||||||
<b-tab-item label="Playlist">
|
<b-tab-item label="Player" :visible="settings.showPlayer && settings.playLink">
|
||||||
<b-button icon-left="plus" @click="addLinkPrompt">Add link</b-button>
|
<Player />
|
||||||
<b-table :data="roomStatus.playlist" striped hoverable default-sort="vote">
|
|
||||||
<template slot-scope="props">
|
|
||||||
<b-table-column field="title" label="Title">
|
|
||||||
{{props.row.title}}
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column field="link" label="Link">
|
|
||||||
{{props.row.link}}
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column field="vote" label="Votes">
|
|
||||||
{{props.row.votes}}
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column field="voters" label="Voters" :visible="isAdmin">
|
|
||||||
{{props.row.voters}}
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column>
|
|
||||||
<b-button v-if="hasVoted(props.row)" icon-left="arrow-down-bold-outline" type="is-dark" @click="vote (props.row.link, false)"/>
|
|
||||||
<b-button v-else icon-left="arrow-up-bold-outline" type="is-dark" @click="vote (props.row.link, true)"/>
|
|
||||||
</b-table-column>
|
|
||||||
</template>
|
|
||||||
</b-table>
|
|
||||||
</b-tab-item>
|
</b-tab-item>
|
||||||
|
|
||||||
<b-tab-item label="Admin" :visible="isAdmin">
|
<b-tab-item label="Admin" :visible="isAdmin">
|
||||||
<b-button @click="broadcastStatus">Force status update</b-button>
|
<Admin />
|
||||||
<b-table :data="usersList" striped hoverable>
|
|
||||||
<template slot-scope="props">
|
|
||||||
<b-table-column field="name" label="Name">
|
|
||||||
{{props.row.name}}
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column field="connection" label="Connection">
|
|
||||||
{{props.row.connection.signalingState}}
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column field="data" label="DataChannel">
|
|
||||||
{{props.row.dataChannel.readyState}}
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column>
|
|
||||||
<b-button icon-left="karate" type="is-dark"/>
|
|
||||||
</b-table-column>
|
|
||||||
</template>
|
|
||||||
</b-table>
|
|
||||||
</b-tab-item>
|
</b-tab-item>
|
||||||
|
|
||||||
<b-tab-item label="Invite">
|
<b-tab-item label="Invite">
|
||||||
<h1 class="subtitle">{{roomStatus.roomCode}}</h1>
|
<Invite v-bind:roomCode="roomStatus.roomCode"/>
|
||||||
</b-tab-item>
|
</b-tab-item>
|
||||||
|
|
||||||
<b-tab-item label="Settings">
|
<b-tab-item label="Settings">
|
||||||
@@ -85,22 +35,26 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Invite from './../components/Invite'
|
||||||
|
import Admin from './../components/Admin'
|
||||||
|
import Playlist from './../components/Playlist'
|
||||||
|
import Player from './../components/Player'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Room',
|
name: 'Room',
|
||||||
computed: {
|
components: {
|
||||||
player () {
|
Invite,
|
||||||
return this.$refs.youtube.player
|
Admin,
|
||||||
|
Playlist,
|
||||||
|
Player
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
roomStatus () {
|
roomStatus () {
|
||||||
return this.$store.state.room.roomStatus
|
return this.$store.state.room.roomStatus
|
||||||
},
|
},
|
||||||
isAdmin () {
|
isAdmin () {
|
||||||
return this.$store.state.room.admin
|
return this.$store.state.room.admin
|
||||||
},
|
},
|
||||||
usersList () {
|
|
||||||
console.log('USER LIST ' + this.$store.state.rtc.peers)
|
|
||||||
return this.$store.state.rtc.peers
|
|
||||||
},
|
|
||||||
isLoggedIn () {
|
isLoggedIn () {
|
||||||
return this.$store.state.app.loginSuccess
|
return this.$store.state.app.loginSuccess
|
||||||
},
|
},
|
||||||
@@ -111,67 +65,16 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
settings: {
|
settings: {
|
||||||
playLink: true,
|
playLink: false,
|
||||||
showPlayer: true
|
showPlayer: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
if (!this.isLoggedIn) this.$router.push({ name: 'Home' })
|
if (!this.isLoggedIn) this.$router.push({ name: 'Home' })
|
||||||
this.player.addEventListener('onStateChange', this.playerStateChange)
|
|
||||||
this.player.playVideo()
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
roomStatus: function (status) {
|
|
||||||
this.player.seekTo(status.player.timeCode, true)
|
|
||||||
if (status.player.playing) this.player.playVideo()
|
|
||||||
else this.player.pauseVideo()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
broadcastStatus () {
|
|
||||||
this.$store.dispatch('rtc/broadcast', { message: this.$store.state.room.roomStatus, type: 'status' })
|
|
||||||
},
|
|
||||||
addLinkPrompt () {
|
|
||||||
this.$buefy.dialog.prompt({
|
|
||||||
message: 'Add a youtube link',
|
|
||||||
trapFocus: true,
|
|
||||||
inputAttrs: {
|
|
||||||
placeholder: 'https://www.youtube.com/watch?v=YItIK09bpKk',
|
|
||||||
minlength: 10
|
|
||||||
},
|
|
||||||
cancelText: 'Nah',
|
|
||||||
confirmText: 'Add',
|
|
||||||
onConfirm: (link) => this.addLink(link)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
addLink (link) {
|
|
||||||
const linkID = this.$youtube.getIdFromUrl(link)
|
|
||||||
if (linkID === null) {
|
|
||||||
this.$buefy.toast.open('Invalid youtube link')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.isAdmin) {
|
if (this.isAdmin) {
|
||||||
this.$store.dispatch('room/vote', { link: linkID, isPositive: true, voterName: this.$store.state.rtc.name })
|
this.settings.playLink = true
|
||||||
} else {
|
this.settings.showPlayer = true
|
||||||
this.vote(linkID, true)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
vote (link, isPositive) {
|
|
||||||
const message = {
|
|
||||||
type: 'vote',
|
|
||||||
link: link,
|
|
||||||
isPositive: isPositive,
|
|
||||||
voterName: this.$store.state.rtc.name
|
|
||||||
}
|
|
||||||
this.$store.dispatch('rtc/broadcast', { message: message, type: 'vote' })
|
|
||||||
},
|
|
||||||
hasVoted (play) {
|
|
||||||
return play.voters.includes(this.$store.state.rtc.name)
|
|
||||||
},
|
|
||||||
async playerStateChange (event) {
|
|
||||||
console.log('[PLAYER] Status change ' + event.data)
|
|
||||||
if (this.isAdmin) this.$store.dispatch('room/setCurrent', { playerStatus: event.data, timeCode: await this.$refs.youtube.player.getCurrentTime() })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,8 +84,4 @@ export default {
|
|||||||
.room {
|
.room {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playerDiv {
|
|
||||||
height: 500px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user