diff --git a/.eslintrc.js b/.eslintrc.js index ea91bf980..a4fd5f17b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -85,11 +85,10 @@ module.exports = { findFirstCharacters: 'writable', tilesets: 'writable', layers: 'writable', - peer: 'writable', settings: 'writable', meet: 'writable', - meetLowLevel: 'writable', meetHighLevel: 'writable', + jitsiMeetJS: 'writable', zoneManager: 'writable', notificationMessage: 'writable', nippleManager: 'writable', @@ -99,7 +98,6 @@ module.exports = { charactersParts: 'writable', characterPopIns: 'writable', capitalize: 'writable', - generateTURNCredentials: 'writable', isModalOpen: 'writable', closeModal: 'writable', toggleModal: 'writable', @@ -130,8 +128,6 @@ module.exports = { relativePositionToCamera: 'writable', updateViewport: 'writable', - sendDataToUsers: 'writable', - sendDataToUsersInZone: 'writable', BootScene: 'writable', EditorScene: 'writable', diff --git a/.vscode/cspell.json b/.vscode/cspell.json index a5a8e859e..8b1c94bbd 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -49,7 +49,6 @@ "ondataavailable", "overscroll", "passwordless", - "peerjs", "Phaser's", "pickable", "plusplus", diff --git a/app/package-lock.json b/app/package-lock.json index 04bef9ef6..64c69f222 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -121,103 +121,11 @@ } } }, - "@swc/helpers": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.3.17.tgz", - "integrity": "sha512-tb7Iu+oZ+zWJZ3HJqwx8oNwSDIU440hmVMDPhpACWQWnrZHK99Bxs70gT1L2dnr5Hg50ZRWEFkQCAnOVVV0z1Q==", - "requires": { - "tslib": "^2.4.0" - } - }, "@tokenizer/token": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, - "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.33", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", - "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" - }, - "@types/node": { - "version": "18.15.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", - "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", - "requires": { - "@types/mime": "*", - "@types/node": "*" - } - }, - "@types/ws": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", - "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", - "requires": { - "@types/node": "*" - } - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -256,29 +164,11 @@ "uuid": "^8.3.2" } }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, "append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, "array-parallel": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/array-parallel/-/array-parallel-0.1.3.tgz", @@ -455,16 +345,6 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, "color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -549,43 +429,16 @@ } } }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, "content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, "crisp-sdk-web": { "version": "1.0.18", "resolved": "https://registry.npmjs.org/crisp-sdk-web/-/crisp-sdk-web-1.0.18.tgz", @@ -621,11 +474,6 @@ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" }, - "data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -696,16 +544,6 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -767,11 +605,6 @@ "is-symbol": "^1.0.2" } }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -782,11 +615,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -802,76 +630,6 @@ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" }, - "express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - } - } - }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -903,15 +661,6 @@ } } }, - "fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "requires": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - } - }, "file-type": { "version": "16.5.4", "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", @@ -922,20 +671,6 @@ "token-types": "^4.1.1" } }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - } - }, "follow-redirects": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", @@ -959,24 +694,6 @@ "mime-types": "^2.1.12" } }, - "formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "requires": { - "fetch-blob": "^3.1.2" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -1003,11 +720,6 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, "get-intrinsic": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", @@ -1161,11 +873,6 @@ "side-channel": "^1.0.4" } }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, "is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -1215,11 +922,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, "is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -1392,11 +1094,6 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, "meteor-node-stubs": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-1.2.5.tgz", @@ -2280,16 +1977,6 @@ } } }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -2350,11 +2037,6 @@ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, "nipplejs": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/nipplejs/-/nipplejs-0.10.0.tgz", @@ -2381,21 +2063,6 @@ "uuid": "8.3.2" } }, - "node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" - }, - "node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", - "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - } - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -2438,11 +2105,6 @@ "wrappy": "1" } }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, "path": { "version": "0.12.7", "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", @@ -2452,46 +2114,11 @@ "util": "^0.10.3" } }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, "peek-readable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==" }, - "peer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/peer/-/peer-1.0.0.tgz", - "integrity": "sha512-fPVtyCKZWVfjbf7XnY7MskhTlu+pBpMvQV81sngT8aXIuT5YF9y9bwIw8y5BlI98DV0NsDpLjow/oemFNvcKkg==", - "requires": { - "@types/express": "^4.17.3", - "@types/ws": "^7.2.3 || ^8.0.0", - "cors": "^2.8.5", - "express": "^4.17.1", - "node-fetch": "^3.3.0", - "ws": "^7.2.3 || ^8.0.0", - "yargs": "^17.6.2" - } - }, - "peerjs": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/peerjs/-/peerjs-1.4.7.tgz", - "integrity": "sha512-dWE2HIGvJO0Hm8lYHJiO/5OWl8xYtGcAuU08To1HMIfhh76ULzkCS3NIQO/PZm4noO1RhaGTkQaQ6sbAss6/Tg==", - "requires": { - "@swc/helpers": "^0.3.13", - "eventemitter3": "^4.0.7", - "peerjs-js-binarypack": "1.0.1", - "webrtc-adapter": "^7.7.1" - } - }, - "peerjs-js-binarypack": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/peerjs-js-binarypack/-/peerjs-js-binarypack-1.0.1.tgz", - "integrity": "sha512-N6aeia3NhdpV7kiGxJV5xQiZZCVEEVjRz2T2C6UZQiBkHWHzUv/oWA4myQLcwBwO8LUoR1KWW5oStvwVesmfCg==" - }, "phaser": { "version": "3.55.2", "resolved": "https://registry.npmjs.org/phaser/-/phaser-3.55.2.tgz", @@ -2530,15 +2157,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -2571,11 +2189,6 @@ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, "raw-body": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", @@ -2636,19 +2249,6 @@ "resolved": "https://registry.npmjs.org/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz", "integrity": "sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==" }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" - }, - "rtcpeerconnection-shim": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz", - "integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==", - "requires": { - "sdp": "^2.6.0" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2686,11 +2286,6 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" }, - "sdp": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz", - "integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw==" - }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -2699,37 +2294,6 @@ "lru-cache": "^6.0.0" } }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -2793,16 +2357,6 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "string.prototype.trimend": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", @@ -2831,14 +2385,6 @@ "safe-buffer": "~5.2.0" } }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -2890,11 +2436,6 @@ "ieee754": "^1.2.1" } }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -2962,35 +2503,11 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" - }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" - }, - "webrtc-adapter": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.7.1.tgz", - "integrity": "sha512-TbrbBmiQBL9n0/5bvDdORc6ZfRY/Z7JnEj+EYOD1ghseZdpJ+nF2yx14k3LgQKc7JZnG7HAcL+zHnY25So9d7A==", - "requires": { - "rtcpeerconnection-shim": "^1.2.15", - "sdp": "^2.12.0" - } - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -3024,26 +2541,11 @@ "is-typed-array": "^1.1.9" } }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==" - }, "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", @@ -3063,34 +2565,10 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" } } } diff --git a/app/package.json b/app/package.json index 668057fed..bffe63282 100644 --- a/app/package.json +++ b/app/package.json @@ -30,8 +30,6 @@ "multer": "1.4.5-lts.1", "nipplejs": "^0.10.0", "node-cron": "^3.0.2", - "peer": "^1.0.0", - "peerjs": "^1.4.7", "phaser": "^3.55.2" } } diff --git a/app/settings-dev.json b/app/settings-dev.json index 6760801d1..efbdd3138 100644 --- a/app/settings-dev.json +++ b/app/settings-dev.json @@ -33,27 +33,10 @@ "pinchDelta": 4 }, - "peer": { - "answerMaxAttempt": 5, - "answerDelayBetweenAttempt": 750, - "avatarAPI": "https://source.unsplash.com/320x240/?[user_avatar]&sig=[user_id]", - "callDelay": 250, - "delayBeforeClosingCall": 1000, - "sounds": { - "hangUp": { - "file": "webrtc-out.mp3", - "volume": 1 - }, - "incomingCall": { - "file": "webrtc-in.mp3", - "volume": 1 - } - } - }, - "meet": { "serverURL": "meet.jit.si", "roomDefaultName": "lemverse-test", + "avatarAPI": "https://source.unsplash.com/320x240/?[user_avatar]&sig=[user_id]", "configOverwrite": {} }, @@ -241,34 +224,8 @@ "identifier": "", "iss": "", "keyid": "", - "sub": "" - }, - - "peer": { - "path": "/peer", - "client": { - "url": "localhost", - "port": 7010, - "credentialDuration": 86400, - "secret": "", - "config": { - "iceServers": [ - { - "urls": "stun:stun.l.google.com:19302" - } - ], - "iceTransportPolicy": "all", - "sdpSemantics": "unified-plan" - } - }, - "server": { - "start": true, - "port": 7010, - "key": "peerjs", - "alive_timeout": 5000, - "expire_timeout": 5000, - "allow_discovery": true - } + "sub": "", + "salt": "" }, "s3": {}, diff --git a/core/client/helpers.js b/core/client/helpers.js index 81b266f51..fd619648e 100644 --- a/core/client/helpers.js +++ b/core/client/helpers.js @@ -29,7 +29,6 @@ eventTypes = Object.freeze({ onMeetEnded: 'onMeetEnded', onMenuOptionSelected: 'onMenuOptionSelected', onMenuOptionUnselected: 'onMenuOptionUnselected', - onPeerDataReceived: 'onPeerDataReceived', onMediaStreamStateChanged: 'onMediaStreamStateChanged', onTileAdded: 'onTileAdded', onTileChanged: 'onTileChanged', @@ -47,6 +46,7 @@ eventTypes = Object.freeze({ beforeSendingMessage: 'beforeSendingMessage', afterSendingMessage: 'afterSendingMessage', consoleClosed: 'consoleClosed', + onUserPropertyUpdated: 'onUserPropertyUpdated', }) toggleUserProperty = (propertyName, value) => { @@ -79,14 +79,16 @@ toggleUserProperty = (propertyName, value) => { } } - if (typeof value === 'boolean') - Meteor.users.update(user._id, { - $set: { [`profile.${propertyName}`]: !!value }, - }) - else - Meteor.users.update(user._id, { - $set: { [`profile.${propertyName}`]: !user.profile[propertyName] }, + const propertyValue = typeof value === 'boolean' ? !!value : !user.profile[propertyName] + + Meteor.users.update(user._id, { + $set: { [`profile.${propertyName}`]: propertyValue }, + }) + window.dispatchEvent( + new CustomEvent(eventTypes.onUserPropertyUpdated, { + detail: { propertyName, propertyValue }, }) + ) } relativePositionToCamera = (position, camera) => { @@ -193,27 +195,6 @@ const formatURLs = (text, shortName = false) => return `${linkName}` }) -sendDataToUsers = (type, data, emitterId, userIds = []) => { - let targets = [...new Set(userIds)] - targets = targets.filter((target) => target !== Meteor.userId()) - if (!targets.length) throw new Error('no-targets') - - return networkManager.sendData(targets, { type, emitter: emitterId, data }) -} - -sendDataToUsersInZone = (type, data, emitterId) => { - const user = Meteor.user() - const usersInZone = zoneManager.usersInZone(zoneManager.currentZone(user)) - const userInZoneIds = usersInZone.map((u) => u._id) - if (!userInZoneIds.length) throw new Error('no-targets') - - return networkManager.sendData(userInZoneIds, { - type, - emitter: emitterId, - data, - }) -} - kebabCase = (string) => string .replace(/([a-z])([A-Z])/g, '$1-$2') @@ -265,7 +246,7 @@ const replaceTextVars = (text) => }) generateRandomAvatarURLForUser = (user) => - Meteor.settings.public.peer.avatarAPI + Meteor.settings.public.meet.avatarAPI .replace('[user_id]', encodeURI(user._id || 'guest')) .replace('[user_name]', encodeURI(user.profile.name || 'guest')) .replace('[user_avatar]', encodeURI(user.profile.avatar || 'cat')) diff --git a/core/client/lemverse.hbs.html b/core/client/lemverse.hbs.html index 2302da45e..cc964617c 100644 --- a/core/client/lemverse.hbs.html +++ b/core/client/lemverse.hbs.html @@ -20,9 +20,9 @@ {{#if and (and guest (not onboarding)) allowFormLogin}} {{> formAccount visible=loading}} {{else if onboarding}} - {{> userOnboarding}} {{else if and (not guest not onboarding)}} {{> editToolbox}} {{/if}} {{ > stream }} {{> - messagesPopup}} {{#each mainModule in mainModules}} {{> Template.dynamic template=mainModule}} {{/each}} {{> - modalContainer }} + {{> userOnboarding}} {{else if and (not guest not onboarding)}} {{> editToolbox}} {{/if}} {{> messagesPopup}} + {{#each mainModule in mainModules}} {{> Template.dynamic template=mainModule}} {{/each}} {{> modalContainer }} + {{> meetLowLevel}}
{{#each module in modules}} {{> Template.dynamic template=module}} {{/each}}
diff --git a/core/client/lemverse.js b/core/client/lemverse.js index 1c58c4f11..259699090 100644 --- a/core/client/lemverse.js +++ b/core/client/lemverse.js @@ -103,7 +103,6 @@ Template.lemverse.onCreated(function () { window.addEventListener('beforeunload', () => { toggleUserProperty('shareScreen', false) - peer.destroy() }) initAppColor() @@ -159,8 +158,6 @@ Template.lemverse.onCreated(function () { const user = Meteor.user() if (!user) return if (user.profile.guest && !guestAllowed(permissionTypes.talkToUsers)) return - - peer.createMyPeer() }) }) @@ -170,9 +167,6 @@ Template.lemverse.onCreated(function () { const user = Meteor.user() if (!user) return if (user.profile.guest && !guestAllowed(permissionTypes.talkToUsers)) return - - if (status === 'connected') peer.createMyPeer() - else peer.peerInstance?.disconnect() }) }) @@ -235,10 +229,6 @@ Template.lemverse.onCreated(function () { const meetingRoomService = meetingRoom.getMeetingRoomService() if (user.profile.shareScreen) meetingRoomService.shareScreen() else meetingRoomService.unshareScreen() - } else if (user.profile.shareScreen) { - await userStreams.createScreenStream() - userStreams.screen(true) - userProximitySensor.callProximityStartedForAllNearUsers() } else { userStreams.screen(false) } @@ -418,7 +408,6 @@ Template.lemverse.onCreated(function () { removed: (user) => { userManager.onDocumentRemoved(user) userProximitySensor.removeNearUser(user) - lp.defer(() => peer.close(user._id, 0, 'user-disconnected')) }, }) if (onLoaded) onLoaded() @@ -429,7 +418,6 @@ Template.lemverse.onCreated(function () { loadUsers(() => { log('loading level: all users loaded') - peer.init() // Load entities log(`loading level: loading entities`) diff --git a/core/client/network-manager.js b/core/client/network-manager.js index c4a88f26a..609d8fa6a 100644 --- a/core/client/network-manager.js +++ b/core/client/network-manager.js @@ -72,11 +72,6 @@ const networkManager = { this.lastUserUpdate = character.lwOriginDate }, - // A simple wrapper: later we will use something else than peerjs - async sendData(userIds, data) { - return peer.sendData(userIds, data) - }, - sendPlayerNewState(state) { this.throttledSendPlayerState(state) }, diff --git a/core/client/peer.js b/core/client/peer.js deleted file mode 100644 index 2a78e43be..000000000 --- a/core/client/peer.js +++ /dev/null @@ -1,758 +0,0 @@ -import Peer from 'peerjs' -import audioManager from './audio-manager' -import meetingRoom from './meeting-room' -import { canAnswerCall, meteorCallWithPromise } from './helpers' -import { guestAllowed, permissionTypes } from '../lib/misc' - -const debug = (text, meta) => { - if (!Meteor.user({ fields: { 'options.debug': 1 } })?.options?.debug) return - log(text, meta) -} - -const callAction = Object.freeze({ - open: 0, - close: 1, -}) - -peer = { - calls: {}, - waitingCallActions: {}, - callStartDates: {}, - remoteCalls: {}, - peerInstance: undefined, - peerLoading: false, - remoteStreamsByUsers: new ReactiveVar([]), - sensorEnabled: true, - enabled: true, - lockedCalls: {}, - reconnect: { - autoReconnectOnClose: true, - delayBetweenAttempt: 250, - }, - securityCheckInterval: 2000, - - init() { - window.addEventListener(eventTypes.onUsersComeCloser, (e) => { - const { users } = e.detail - peer.onProximityStarted(users) - }) - - window.addEventListener(eventTypes.onUsersMovedAway, (e) => { - const { users } = e.detail - peer.onProximityEnded(users) - }) - this.enable() - - Tracker.autorun(() => { - const user = Meteor.user({ fields: { 'status.idle': 1 } }) - if (!user) return - - this.enableSensor(!user.status.idle) - }) - - // For security reasons we periodically check that the users in discussion are still close to the calling users - window.setInterval(() => { - const callEntries = Object.entries(this.remoteCalls) - if (!callEntries.length) return - - callEntries.forEach((entry) => { - // Keep the call if user is near or in follow mode - const _id = entry[1].metadata.userId - if (userProximitySensor.isUserNear({ _id }) || this.lockedCalls[_id]) return - this.closeCall(_id, 0, 'security-user-far') - }) - }, this.securityCheckInterval) - - // Listen device connection/disconnection to update peers - navigator.mediaDevices.addEventListener('devicechange', async () => { - if (!this.hasActiveStreams()) return - - const constraints = userStreams.getStreamConstraints(streamTypes.main) - constraints.forceNew = true - - const stream = await userStreams.requestUserMedia(constraints) - if (!stream) { - lp.notif.error(`unable to get a valid stream`) - return - } - - peer.updatePeersStream(stream, streamTypes.main) - }) - }, - - enable() { - this.enabled = true - }, - - disable() { - this.enabled = false - this.closeAll() - }, - - closeAll() { - debug('peer.closeAll: start') - _.each(this.calls, (call) => - this.close(call.peer, Meteor.settings.public.peer.delayBeforeClosingCall, 'close-all') - ) - }, - - closeCall(userId, origin) { - debug(`closeCall: start (${origin})`, { userId }) - - let activeCallsCount = 0 - const _close = (remote, user, type) => { - const callsSource = remote ? this.remoteCalls : this.calls - const call = callsSource[`${user}-${type}`] - if (call) { - activeCallsCount++ - call.close() - } - - delete callsSource[`${user}-${type}`] - } - - this.unlockCall(userId, true) - _close(false, userId, streamTypes.main) - _close(false, userId, streamTypes.screen) - _close(true, userId, streamTypes.main) - _close(true, userId, streamTypes.screen) - this.cancelWaitingCallAction(userId) - - const debutText = activeCallsCount ? 'closeCall: call was active' : 'closeCall: call was inactive' - debug(debutText, { sourceAmount: activeCallsCount }) - - let streamsByUsers = this.remoteStreamsByUsers.get() - streamsByUsers.map((usr) => { - if (usr._id === userId) { - delete usr.main.srcObject - delete usr.screen.srcObject - delete usr.waitingCallAnswer - } - - return usr - }) - - // We clean up remoteStreamsByUsers table by deleting all the users who have neither webcam or screen sharing active - streamsByUsers = streamsByUsers.filter( - (usr) => usr.main.srcObject !== undefined || usr.screen.srcObject !== undefined || usr.waitingCallAnswer - ) - this.remoteStreamsByUsers.set(streamsByUsers) - - if (!this.hasActiveStreams()) { - userStreams.destroyStream(streamTypes.main) - } - - if (this.callStartDates[userId]) { - const duration = (Date.now() - this.callStartDates[userId]) / 1000 - Meteor.call('analyticsDiscussionEnd', { - peerUserId: userId, - duration, - usersAttendingCount: this.getCallCount(), - }) - delete this.callStartDates[userId] - } - - $(`.js-video-${userId}-user`).remove() - debug('closeCall: call closed successfully', { userId }) - - if (!activeCallsCount) return - - const { file, volume } = Meteor.settings.public.peer.sounds.hangUp - audioManager.play(file, volume) - }, - - close(userId, timeout = 0, origin = null) { - debug(`close: start (${origin})`, { userId }) - if (this.isCallInState(userId, callAction.close)) { - debug(`close: call already closing (action ignored)`, { userId }) - return - } - - this.cancelWaitingCallAction(userId) - this.waitingCallActions[userId] = { - timer: setTimeout(() => { - this.cancelWaitingCallAction(userId) - this.closeCall(userId, origin) - }, timeout), - action: callAction.close, - } - }, - - createPeerCall(peer, user, stream, streamType) { - debug(`createPeerCall: calling remote user`, { - user: user._id, - streamType, - }) - if (!stream) { - error(`createPeerCall: stream is undefined`, { user, stream }) - return - } - - if (this.calls[`${user._id}-${streamType}`]) { - debug(`createPeerCall: creation cancelled (call already started)`) - return - } - - if (!canAnswerCall(user)) { - debug(`createPeerCall: creation cancelled (user is too far)`) - this.close(user._id, 0, 'far-user') - return - } - - const call = peer.call(user._id, stream, { - metadata: { userId: Meteor.userId(), type: streamType }, - }) - if (!call) { - error(`createPeerCall: an error occured during call creation (peerjs error)`) - this.close(user._id, 0, 'peer-error') - return - } - - // update html element with the last stream instance - this.calls[`${user._id}-${streamType}`] = call - this.createOrUpdateRemoteStream(user, streamType) - - // ensures peers are using last stream & tracks available - this.updatePeersStream(stream, streamType) - - debug(`createPeerCall: call in progress`, { - user: user._id, - streamType, - }) - }, - - async createPeerCalls(user) { - const { shareAudio, shareScreen, shareVideo } = Meteor.user().profile - - if (!this.calls[`${user._id}-${streamTypes.main}`] && !this.calls[`${user._id}-${streamTypes.screen}`]) { - const { file, volume } = Meteor.settings.public.peer.sounds.incomingCall - audioManager.play(file, volume) - - if (!this.callStartDates[user._id]) { - this.callStartDates[user._id] = Date.now() - Meteor.call('analyticsDiscussionAttend', { - peerUserId: user._id, - usersAttendingCount: this.getCallCount(), - }) - if (this.expiration && parseInt(Date.now() / 1000, 10) > this.expiration) { - Meteor.call('analyticsCredentialsExpired') - debug('TURN credentials expired') - } - } - } - - const peer = await this.getPeer() - if (!peer) { - debug(`createPeerCalls: peer not created`) - return - } - - if (shareAudio || shareVideo) - userStreams.createStream().then((stream) => this.createPeerCall(peer, user, stream, streamTypes.main)) - if (shareScreen) - userStreams - .createScreenStream() - .then((stream) => this.createPeerCall(peer, user, stream, streamTypes.screen)) - }, - - destroy() { - this.closeAll() - userStreams.destroyStream(streamTypes.main) - this.peerInstance?.destroy() - this.remoteStreamsByUsers.set([]) - delete this.peerInstance - }, - - updatePeersStream(stream, type) { - debug('updatePeersStream: start', { stream, type }) - - const callEntries = Object.entries(this.calls) - - if (type === streamTypes.main) { - debug(`updatePeersStream: main stream ${stream.id}`, { stream }) - const audioTrack = stream.getAudioTracks()[0] - const videoTrack = stream.getVideoTracks()[0] - - // note: to add a track it is necessary to renegotiate the connection with the remote user (https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack) - callEntries.forEach(([key, call]) => { - if (key.indexOf('-screen') !== -1) return - const senders = call.peerConnection.getSenders() - - const existingSenderAudioTrack = senders.find((sender) => sender.track.kind === 'audio') - if (existingSenderAudioTrack) { - if (audioTrack) existingSenderAudioTrack.replaceTrack(audioTrack) - else call.peerConnection.removeTrack(existingSenderAudioTrack) - } else if (audioTrack) call.peerConnection.addTrack(audioTrack) - - const existingSenderVideoTrack = senders.find((sender) => sender.track.kind === 'video') - if (existingSenderVideoTrack) { - if (videoTrack) existingSenderVideoTrack.replaceTrack(videoTrack) - else call.peerConnection.removeTrack(existingSenderVideoTrack) - } else if (videoTrack) call.peerConnection.addTrack(videoTrack) - - if (!existingSenderAudioTrack || !existingSenderVideoTrack) - debug(`updatePeersStream: stream main track added for user`, { key }) - else debug(`updatePeersStream: stream main track updated for user`, { key }) - }) - } else if (type === streamTypes.screen) { - debug(`updatePeersStream: screen share stream ${stream.id}`, { - stream, - }) - const screenTrack = stream.getVideoTracks()[0] - - callEntries.forEach(([key, call]) => { - if (key.indexOf('-screen') === -1) return - const senders = call.peerConnection.getSenders() - let trackUpdated = false - - senders.forEach((sender) => { - if (sender.track.id === screenTrack.id || sender.track.kind !== 'video') return - sender.replaceTrack(screenTrack) - trackUpdated = true - }) - - if (trackUpdated) debug(`updatePeersStream: stream main track updated for user ${key}`) - }) - } - }, - - onProximityStarted(nearUsers) { - if (!this.isEnabled() && this.sensorEnabled) return - - nearUsers.forEach((nearUser) => { - if (nearUser.profile.guest && !guestAllowed(permissionTypes.talkToUsers)) return - if (this.isCallInState(nearUser._id, callAction.open)) return - this.cancelWaitingCallAction(nearUser._id) - - const zone = zoneManager.currentZone(nearUser) - if (zone?.disableCommunications) { - lp.notif.warning( - `${nearUser.profile.name} isn't available at the moment.
Leave him a voice message by pressing "P"` - ) - return - } - - this.waitingCallActions[nearUser._id] = { - timer: setTimeout(() => { - this.cancelWaitingCallAction(nearUser._id) - this.createPeerCalls(nearUser) - }, Meteor.settings.public.peer.callDelay), - action: callAction.open, - } - }) - }, - - onProximityEnded(users) { - users.forEach((user) => { - if (this.lockedCalls[user._id]) return - this.close(user._id, Meteor.settings.public.peer.delayBeforeClosingCall, 'proximity-ended') - }) - }, - - isCallInState(userId, state) { - return this.waitingCallActions[userId]?.action === state - }, - - cancelWaitingCallAction(userId) { - if (!this.waitingCallActions[userId]) return - clearTimeout(this.waitingCallActions[userId].timer) - delete this.waitingCallActions[userId] - }, - - async sendData(userIds, data) { - userIds = userIds.filter(Boolean) // remove falsy values - if (!userIds.length) throw new Error(`no users targeted`) - - const peer = await this.getPeer() - userIds.forEach((userId) => { - try { - const connection = peer.connect(userId) - - connection.on('open', () => { - connection.send(data) - - // Not sure if we must close the connection for now - setTimeout(() => connection.close(), 500) - }) - - connection.on('error', () => { - const user = Meteor.users.findOne(userId) - if (user) lp.notif.warning(`${user.profile.name} was unavailable`) - else lp.notif.warning(`${userId} is offline`) - }) - } catch (err) { - const user = Meteor.users.findOne(userId) - lp.notif.error(`An error has occured during connection with ${user?.profile.name || userId}`) - } - }) - - return userIds.length - }, - - onStreamSettingsChanged(changedUser) { - const streamsByUsers = this.remoteStreamsByUsers.get() - const streamsCurrentUser = streamsByUsers.find((user) => user._id === changedUser._id) - if (!streamsCurrentUser || !streamsCurrentUser.screen.srcObject) return - - if (!changedUser.profile.shareScreen) { - delete streamsCurrentUser.screen.srcObject - this.remoteStreamsByUsers.set(streamsByUsers) - } - }, - - initStreamMonitoring(remoteUserId, streamType) { - const streamsByUsers = this.remoteStreamsByUsers.get() - const stream = streamsByUsers.find((usr) => usr._id === remoteUserId) - if (streamType === 'main' && !stream.videoStartedAt) { - stream.videoStartedAt = Date.now() - debug(`Video stream ${stream.streamId} starting...`) - Meteor.call('analyticsStreamStarted', { - streamId: stream.streamId, - peerUserId: remoteUserId, - kind: 'video', - }) - } - if (streamType === 'main' && !stream.audioStartedAt) { - stream.audioStartedAt = Date.now() - debug(`Audio stream ${stream.streamId} starting...`) - Meteor.call('analyticsStreamStarted', { - streamId: stream.streamId, - peerUserId: remoteUserId, - kind: 'audio', - }) - } - if (streamType === 'screen' && !stream.screenStartedAt) { - stream.screenStartedAt = Date.now() - debug(`Screen stream ${stream.streamId} starting...`) - Meteor.call('analyticsStreamStarted', { - streamId: stream.streamId, - peerUserId: remoteUserId, - kind: 'screen', - }) - } - }, - - monitorStreams(userStream, remoteStream, streamType) { - if (streamType === 'main') { - const videoTrack = remoteStream.getVideoTracks()[0] - const audioTrack = remoteStream.getAudioTracks()[0] - if (videoTrack) { - videoTrack.onunmute = () => { - if (!userStream.videoEstablished) { - const elapsed = Date.now() - userStream.videoStartedAt - debug(`Video stream ${userStream.streamId} established in ${elapsed} ms`) - Meteor.call('analyticsStreamEstablished', { - streamId: userStream.streamId, - peerUserId: userStream._id, - kind: 'video', - elapsed, - }) - userStream.videoEstablished = true - } - } - } else { - debug('Video track is missing!') - Meteor.call('analyticsMissingTrack', { - streamId: userStream.streamId, - peerUserId: userStream._id, - kind: 'video', - }) - } - if (audioTrack) { - audioTrack.onunmute = () => { - if (!userStream.audioEstablished) { - const elapsed = Date.now() - userStream.audioStartedAt - debug(`Audio stream ${userStream.streamId} established in ${elapsed} ms`) - Meteor.call('analyticsStreamEstablished', { - streamId: userStream.streamId, - peerUserId: userStream._id, - kind: 'audio', - elapsed, - }) - userStream.audioEstablished = true - } - } - } else { - debug('Audio track is missing!') - Meteor.call('analyticsMissingTrack', { - streamId: userStream.streamId, - peerUserId: userStream._id, - kind: 'audio', - }) - } - } else if (streamType === 'screen') { - const videoTrack = remoteStream.getVideoTracks()[0] - if (videoTrack) { - videoTrack.onunmute = () => { - if (!userStream.screenEstablished) { - const elapsed = Date.now() - userStream.screenStartedAt - debug(`Screen sharing stream ${userStream.streamId} established in ${elapsed} ms`) - Meteor.call('analyticsStreamEstablished', { - streamId: userStream.streamId, - peerUserId: userStream._id, - kind: 'screen', - elapsed, - }) - userStream.screenEstablished = true - } - } - } else { - debug('Screen sharing video track is missing!') - Meteor.call('analyticsMissingTrack', { - streamId: userStream.streamId, - peerUserId: userStream._id, - kind: 'screen', - }) - } - } - }, - - createOrUpdateRemoteStream(user, streamType, remoteStream = null) { - const streamsByUsers = this.remoteStreamsByUsers.get() - - if (!streamsByUsers.find((usr) => usr._id === user._id)) { - streamsByUsers.push({ - _id: user._id, - main: {}, - screen: {}, - waitingCallAnswer: true, - streamId: Random.id(), - videoEstablished: false, - audioEstablished: false, - screenEstablished: false, - }) - } - - if (remoteStream) { - streamsByUsers.map((usr) => { - if (usr._id === user._id) { - delete usr.waitingCallAnswer - usr[streamType] = {} - usr[streamType].srcObject = remoteStream - this.monitorStreams(usr, remoteStream, streamType) - } - - return usr - }) - } - - this.remoteStreamsByUsers.set(streamsByUsers) - }, - - answerCall(remoteCall) { - const remoteUserId = remoteCall.metadata?.userId - debug(`answerCall: start`, { - userId: remoteUserId, - type: remoteCall.metadata.type, - }) - if (!this.enabled) { - debug(`answerCall: peer is disabled`) - return false - } - - if (!remoteUserId) { - debug(`answerCall: incomplete metadata for the remote call`) - return false - } - const remoteUser = Meteor.users.findOne({ _id: remoteUserId }) - if (!remoteUser) { - debug(`answerCall: user not found "${remoteUserId}"`) - return false - } - - // Send global notification - sendEvent('proximity-started', { user: remoteUser }) - - // answer the call - remoteCall.answer() - - const callIdentifier = `${remoteUserId}-${remoteCall.metadata.type}` - this.remoteCalls[callIdentifier] = remoteCall - - // show the remote call with an empty stream - this.createOrUpdateRemoteStream(remoteUser, remoteCall.metadata.type, null, true) - this.initStreamMonitoring(remoteUserId, remoteCall.metadata.type) - - // update call's with stream received - remoteCall.on('stream', (stream) => { - debug(`remoteCall: received stream`, { - userId: remoteUserId, - type: remoteCall.metadata.type, - stream: stream.id, - }) - this.createOrUpdateRemoteStream(remoteUser, remoteCall.metadata.type, stream) - }) - - remoteCall.on('close', () => { - debug(`remoteCall: closed`, { - userId: remoteUserId, - type: remoteCall.metadata.type, - }) - this.close(remoteUserId, 0, 'peerjs-event') - }) - - return true - }, - - async getPeer() { - debug('getPeer: start') - if (this.isPeerValid(this.peerInstance)) { - debug('getPeer: return peer instance…', { - instance: this.peerInstance, - }) - return this.peerInstance - } - - if (this.peerInstance?.disconnected) { - let reconnected = true - try { - debug('getPeer: peer disconnected, reconnecting…') - this.peerInstance.reconnect() - } catch (err) { - reconnected = false - } - - // peerjs reconnect doesn't offer a promise or callback so we have to wait a certain time until the reconnection is done - if (reconnected) { - try { - debug('getPeer: reconnected, waiting for instance') - await waitFor(() => this.isPeerValid(this.peerInstance), 5, 250) - } catch { - this.destroy() - lp.notif.error('Unable to reconnect to the peer server') - } - - return this.peerInstance - } - } - - if (!this.peerInstance && this.peerLoading) { - try { - debug('getPeer: loading, waiting for instance') - await waitFor(() => this.peerInstance !== undefined, 5, 250) - } catch { - this.destroy() - lp.notif.error('Unable to get a valid peer instance') - } - - return this.peerInstance - } - - debug('getPeer: peer invalid, creating new peer…') - this.peerInstance = undefined - this.peerLoading = false - - return this.createMyPeer().catch((error) => lp.notif.error(error.message)) - }, - - async createMyPeer(skipConfig = false) { - if (this.isPeerValid(this.peerInstance)) return this.peerInstance - - const user = Meteor.user() - if (!user) throw new Error(`an user is required to create a peer`) - if (user.profile.guest && !guestAllowed(permissionTypes.talkToUsers)) - throw new Error(`You need an account to talk to other users`) - - this.peerLoading = true - const result = await meteorCallWithPromise('getPeerConfig') - - const { port, url: host, path, config, expiration } = result - - const peerConfig = { - debug: user.options?.debug ? 2 : 0, - host, - port, - path, - config, - } - - if (skipConfig) delete peerConfig.config - if (this.peerInstance) this.destroy() - this.peerInstance = new Peer(user._id, peerConfig) - this.expiration = expiration - this.peerLoading = false - - debug(`createMyPeer: created`, { peerInstanceId: this.peerInstance.id }) - - // force reconnect - this.peerInstance.on('disconnected', () => this.getPeer()) - - this.peerInstance.on('connection', (connection) => - connection.on('data', (data) => userManager.onPeerDataReceived(data)) - ) - - this.peerInstance.on('close', () => { - debug('createMyPeer: peer closed') - this.peerInstance = undefined - }) - - this.peerInstance.on('error', (peerErr) => { - if (['server-error', 'network'].includes(peerErr.type) && this.peerInstance.disconnected) - this.peerInstance.reconnect() - else if (peerErr.type === 'unavailable-id') - lp.notif.error( - `It seems that ${Meteor.settings.public.lp.product} is already open in another tab (unavailable-id)` - ) - else if (peerErr.type === 'peer-unavailable') { - const userId = peerErr.message.split(' ').pop() - const userUnavailable = Meteor.users.findOne(userId) - lp.notif.warning(`User ${userUnavailable?.profile.name || userId} was unavailable`) - } else debug(`peer error ${peerErr.type}`, peerErr) - }) - - this.peerInstance.on('call', (remoteCall) => { - debug(`Incoming call`, { userId: remoteCall.metadata.userId }) - if (meetingRoom.isOpen()) { - debug(`Call ignored (meet is open)`, { - userId: remoteCall.metadata.userId, - type: remoteCall.metadata.type, - }) - return - } - - this.answerCall(remoteCall) - }) - - return this.peerInstance - }, - - lockCall(userId, notify = false) { - if (notify && !this.lockedCalls[userId]) - this.sendData([userId], { - type: 'followed', - emitter: Meteor.userId(), - }) - this.lockedCalls[userId] = true - }, - - unlockCall(userId, notify = false) { - if (notify && this.lockedCalls[userId]) - this.sendData([userId], { - type: 'unfollowed', - emitter: Meteor.userId(), - }) - delete this.lockedCalls[userId] - }, - - getCallCount() { - return Object.keys(this.callStartDates).length - }, - - hasActiveStreams() { - return this.remoteStreamsByUsers.get().length - }, - - isPeerValid(peer) { - return peer?.id && !peer.disconnected - }, - - enableSensor(value) { - if (value === this.sensorEnabled) return - this.sensorEnabled = value - if (this.sensorEnabled) userProximitySensor.callProximityStartedForAllNearUsers() - }, - - isEnabled() { - return this.enabled && !meetingRoom.isOpen() - }, -} diff --git a/core/client/scenes/scene-world.js b/core/client/scenes/scene-world.js index 56235bf95..f69113342 100644 --- a/core/client/scenes/scene-world.js +++ b/core/client/scenes/scene-world.js @@ -255,7 +255,6 @@ WorldScene = new Phaser.Class({ userManager.destroy() zoneManager.destroy() userProximitySensor.callProximityEndedForAllNearUsers() - peer.closeAll() Session.set('sceneWorldReady', false) }, diff --git a/core/client/ui/remote-stream.hbs.html b/core/client/ui/remote-stream.hbs.html deleted file mode 100644 index 97ef5d58c..000000000 --- a/core/client/ui/remote-stream.hbs.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - diff --git a/core/client/ui/remote-stream.js b/core/client/ui/remote-stream.js deleted file mode 100644 index d0c0a5e28..000000000 --- a/core/client/ui/remote-stream.js +++ /dev/null @@ -1,134 +0,0 @@ -const maxAttempt = 10 -const delayBetweenAttempt = 2000 // in ms - -const checkMediaAvailable = (template, type) => { - const { remoteUser } = template.data - if (!remoteUser._id) { - log(`Missing user id in template data`) - return - } - - const remoteUserStream = peer.remoteStreamsByUsers.get().find((usr) => usr._id === remoteUser._id) - if (!remoteUserStream) { - log(`Stop retry to get ${remoteUser.name}'s ${type}, ${remoteUser.name} is too far`) - return - } - - const source = type === streamTypes.screen ? remoteUserStream.screen?.srcObject : remoteUserStream.main?.srcObject - if (source) { - template.firstNode.srcObject = source - template.firstNode.play().catch(() => { - error( - `unable to player remote user's media: playback interrupted (${remoteUserStream._id}) : ${template.attempt}` - ) - setTimeout(() => checkMediaAvailable(template, type), delayBetweenAttempt) - }) - } else if (template.attempt < maxAttempt) { - template.attempt++ - log(`Tried to get ${remoteUserStream.name}'s ${type} and failed, attempt : ${template.attempt}`) - setTimeout(() => checkMediaAvailable(template, type), delayBetweenAttempt) - } else { - error(`unable to get user's ${type}`) - } -} - -Template.webcam.onRendered(function () { - this.attempt = 1 - checkMediaAvailable(this, 'video-audio') -}) - -Template.webcam.onDestroyed(function () { - destroyVideoSource(this.find('video')) -}) - -Template.screenshare.onRendered(function () { - this.attempt = 1 - checkMediaAvailable(this, 'screen') -}) - -Template.screenshare.onDestroyed(function () { - destroyVideoSource(this.find('video')) -}) - -Template.remoteStream.onDestroyed(() => { - if (!isModalOpen()) game.scene.getScene('WorldScene')?.enableMouse(true) - Session.set('modal', null) -}) - -Template.remoteStream.onRendered(function () { - const avatarDomElement = this.firstNode.querySelector('.avatar') - if (!avatarDomElement) return - - avatarDomElement.onerror = (event) => { - event.target.src = Meteor.settings.public.avatarFallback - } -}) - -Template.remoteStream.helpers({ - mediaState() { - const fields = { 'profile.shareAudio': 1, 'profile.shareVideo': 1 } - const user = Meteor.users.findOne(this.remoteUser._id, { fields }) - - return user?.profile || { shareAudio: false, shareVideo: false } - }, - hasMainStream() { - return this.remoteUser.main?.srcObject - }, - hasScreenStream() { - return this.remoteUser.screen?.srcObject - }, - isWebcamFullScreen: () => { - const modal = Session.get('modal') - - return modal?.template === 'fullScreenModal' && modal?.data?.template === 'webcam' - }, - state() { - const fields = { 'profile.userMediaError': 1 } - const user = Meteor.users.findOne(this.remoteUser._id, { fields }) - if (!user) return 'user-error' - if (user.profile.userMediaError) return 'media-error' - - return this.remoteUser.waitingCallAnswer ? 'calling' : 'connected' - }, - name() { - const fields = { 'profile.username': 1, 'profile.name': 1 } - const user = Meteor.users.findOne(this.remoteUser._id, { fields }) - if (!user) return 'Guest' - - return user.profile.name || user.username || 'Guest' - }, - avatar() { - const fields = { 'profile.avatar': 1, 'profile.name': 1 } - const user = Meteor.users.findOne(this.remoteUser._id, { fields }) - if (!user) - return generateRandomAvatarURLForUser({ - _id: 'usr_a', - profile: { name: 'Guest', avatar: 'cat' }, - }) - - return generateRandomAvatarURLForUser(user) - }, -}) - -Template.remoteStream.events({ - 'click .js-webcam': function (event) { - event.preventDefault() - - Session.set('modal', { - template: 'fullScreenModal', - classes: 'modal-fit fullscreen-modal', - screenType: 'webcam', - remoteUser: this.remoteUser, - }) - }, - 'click .js-screenshare': function (event) { - event.preventDefault() - - Session.set('modal', { - template: 'fullScreenModal', - classes: 'modal-fit fullscreen-modal', - screenType: 'screenshare', - remoteUser: this.remoteUser, - }) - }, -}) diff --git a/core/client/ui/settings-medias.js b/core/client/ui/settings-medias.js index 9eac5ac57..3550bbc47 100644 --- a/core/client/ui/settings-medias.js +++ b/core/client/ui/settings-medias.js @@ -20,8 +20,6 @@ const updateSettingsStream = async (template) => { video.srcObject = stream video.onloadedmetadata = () => video.play() - peer.updatePeersStream(stream, streamTypes.main) - if (interval) clearInterval(interval) interval = userStreams.trackSound(stream, (audioMeter) => template.audioMeter.set(audioMeter)) } diff --git a/core/client/ui/stream.hbs.html b/core/client/ui/stream.hbs.html deleted file mode 100644 index 15bc031a8..000000000 --- a/core/client/ui/stream.hbs.html +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/core/client/ui/stream.js b/core/client/ui/stream.js deleted file mode 100644 index 5abc22114..000000000 --- a/core/client/ui/stream.js +++ /dev/null @@ -1,59 +0,0 @@ -const talking = () => !!peer.remoteStreamsByUsers.get().length - -const onMediaStreamStateChanged = (event) => { - const { stream, type } = event.detail - - if (type === streamTypes.screen) { - if (!this.videoScreenShareElement) - this.videoScreenShareElement = document.querySelector('.js-stream-screen-me video') - if (!stream) destroyVideoSource(this.videoScreenShareElement) - else this.videoScreenShareElement.srcObject = stream - - const user = Meteor.user({ fields: { 'profile.shareScreen': 1 } }) - if (user) this.videoScreenShareElement.classList.toggle('active', user.profile.shareScreen) - } else if (type === streamTypes.main) { - if (!this.videoElement) this.videoElement = document.querySelector('.js-stream-me video') - if (!stream) destroyVideoSource(this.videoElement) - else this.videoElement.srcObject = stream - } -} - -Template.stream.onCreated(function () { - this.avatarURL = new ReactiveVar() - window.addEventListener(eventTypes.onMediaStreamStateChanged, onMediaStreamStateChanged) - - this.autorun(() => { - if (!Meteor.userId()) return - - const user = Meteor.user({ fields: { 'profile.avatar': 1 } }) - if (user) this.avatarURL.set(generateRandomAvatarURLForUser(user)) - }) -}) - -Template.stream.onDestroyed(() => { - window.removeEventListener(eventTypes.onMediaStreamStateChanged, onMediaStreamStateChanged) -}) - -Template.stream.helpers({ - allRemoteStreamsByUsers: () => peer.remoteStreamsByUsers.get(), - active() { - return talking() - }, - avatarURL() { - return talking() && Template.instance().avatarURL.get() - }, - screenSharing() { - return Meteor.user({ fields: { 'profile.shareScreen': 1 } })?.profile.shareScreen - }, - videoActive() { - return talking() && Meteor.user({ fields: { 'profile.shareVideo': 1 } })?.profile.shareVideo - }, -}) - -Template.stream.events({ - 'click .js-stream-me': function (event) { - event.preventDefault() - event.stopPropagation() - document.querySelector('.stream-me').focus() - }, -}) diff --git a/core/client/ui/stream.scss b/core/client/ui/stream.scss deleted file mode 100644 index 10e226b6f..000000000 --- a/core/client/ui/stream.scss +++ /dev/null @@ -1,115 +0,0 @@ -@import '../_variables'; - -.remote-user { - max-height: calc(100vh - 210px); - position: fixed; - top: 10px; - right: 10px; - z-index: 50; - width: 280px; - transform: translateX(110%); - transition: transform 0.5s ease-out; - overflow-y: scroll; - - video:not(.fullscreen) { - object-fit: cover; - } - - &.active { - transform: translateX(0); - } -} - -.remote-user::-webkit-scrollbar { - display: none; -} - -.stream-me { - transform: translateX(110%); - transition: transform 0.5s ease-out; - position: fixed; - z-index: 50; - bottom: 10px; - right: 10px; - - @include media-max('phone-down') { - transform: translate(300px); - transition: transform 0.5s; - - &.visible { - transform: translate(0); - } - - &.videoActive { - transform: translate(240px); - - &.visible { - transform: translate(0); - } - } - } - - &.active { - background-color: rgba($main-color, 1); - border-radius: 15px; - transform: translateX(0); - } - - .js-stream-me { - position: relative; - width: 280px; - height: 180px; - background-color: rgba($main-color, 0.9); - border-radius: 15px; - z-index: 30; - background-size: cover; - background-repeat: no-repeat; - background-position: 50% 50%; - overflow: hidden; - - video { - width: 100%; - height: 180px; - border-radius: 10px; - display: none; - object-fit: cover; - transform: scale(-1, 1); - } - - &.active-video video { - display: block; - } - } - - .js-stream-screen-me { - display: none; - position: absolute; - bottom: 25px; - right: 16px; - width: 340px; - height: 200px; - background-color: #292929; - background-image: url('loader-white.gif'); - background-size: 30%; - background-position: 50%; - background-repeat: no-repeat; - border-radius: 15px; - overflow: hidden; - z-index: 28; - - &.active { - display: block; - } - - video { - width: 100%; - object-fit: fill; - height: 100%; - display: none; - - &.active { - display: block; - } - } - } -} diff --git a/core/client/ui/user-onboarding.js b/core/client/ui/user-onboarding.js index 326a09fc0..c5326e673 100644 --- a/core/client/ui/user-onboarding.js +++ b/core/client/ui/user-onboarding.js @@ -43,8 +43,6 @@ const updateSettingsStream = async (template) => { video.srcObject = stream video.onloadedmetadata = () => video.play() - peer.updatePeersStream(stream, streamTypes.main) - if (interval) clearInterval(interval) interval = userStreams.trackSound(stream, (audioMeter) => template.audioMeter.set(audioMeter)) } diff --git a/core/client/ui/user-panel.js b/core/client/ui/user-panel.js index 955f23124..8a06ffadd 100644 --- a/core/client/ui/user-panel.js +++ b/core/client/ui/user-panel.js @@ -1,6 +1,6 @@ import { guestAllowed, permissionTypes } from '../../lib/misc' -const talking = () => !!peer.remoteStreamsByUsers.get().length +const talking = () => Session.get('isLowLevelActive') Template.userPanel.onCreated(function () { if (Meteor.settings.public.features?.userPanel?.enabled === false) return diff --git a/core/client/user-manager.js b/core/client/user-manager.js index d70f5deb3..44a453de3 100644 --- a/core/client/user-manager.js +++ b/core/client/user-manager.js @@ -180,7 +180,6 @@ userManager = { } } else { if (shouldCheckDistance) userProximitySensor.checkDistance(loggedUser, user) - if (user.profile.shareScreen !== oldUser?.profile.shareScreen) peer.onStreamSettingsChanged(user) } }, @@ -269,11 +268,11 @@ userManager = { this.controlledCharacter.running = hotkeys.isPressed('shift') this.controlledCharacter.moveDirection = this.inputVector - if (peer.isEnabled() && !Session.get('menu')) { + if (jitsiMeetJS && !Session.get('menu')) { const nearUsersCount = guestAllowed(permissionTypes.talkToUsers) ? userProximitySensor.nearUsersCount() : userProximitySensor.nearNonGuestUsers().length - this.controlledCharacter.enableChatCircle(nearUsersCount > 0) + this.controlledCharacter.enableChatCircle(!Session.get('isJitsiMeetOpen') && nearUsersCount > 0) } else this.controlledCharacter.enableChatCircle(false) const newVelocity = this.controlledCharacter.physicsStep() @@ -290,7 +289,6 @@ userManager = { this.stopInteracting() } - if (!peer.hasActiveStreams()) peer.enableSensor(!(this.controlledCharacter.running && moving)) this.controlledCharacter.wasMoving = moving this.controlledCharacter?.postUpdateStep() }, @@ -321,18 +319,15 @@ userManager = { if (!user || (user && this.controlledCharacter.followedGameObject)) { if (this.controlledCharacter.followedGameObject) { lp.notif.success(`You no longer follow anyone`) - peer.unlockCall(this.controlledCharacter.followedGameObject.getData('userId'), true) } this.controlledCharacter.stopFollow() - return } this.controlledCharacter.follow(this.getCharacter(user._id)) lp.notif.success(`You are following ${user.profile.name}`) - peer.lockCall(user._id, true) }, setUserInDoNotDisturbMode(enable) { @@ -381,54 +376,6 @@ userManager = { this.userMediaStates = undefined }, - onPeerDataReceived(dataReceived) { - const { emitter: emitterUserId, type, data } = dataReceived - - const userEmitter = Meteor.users.findOne(emitterUserId) - if (!userEmitter) return - - const meta = {} - - if (type === 'audio') audioManager.playFromChunks(data) - else if (type === 'followed') { - peer.lockCall(emitterUserId) - lp.notif.warning(`${userEmitter.profile.name} is following you πŸ‘€`) - } else if (type === 'unfollowed') { - peer.unlockCall(emitterUserId) - - const followedUserId = this.controlledCharacter.followedGameObject?.getData('userId') - if (followedUserId === emitterUserId) this.controlledCharacter.stopFollow() - else lp.notif.warning(`${userEmitter.profile.name} has finally stopped following you πŸŽ‰`) - } else if (type === 'text') { - const emitterPlayer = this.getCharacter(emitterUserId) - if (!emitterPlayer) return - if (!data.content) return - - const { zoneLastSeenDates = [], zoneMuted = [] } = Meteor.user({ - fields: { zoneMuted: 1, zoneLastSeenDates: 1 }, - }) - const userEmitterZoneId = zoneManager.currentZone(userEmitter)?._id - if (zoneLastSeenDates[userEmitterZoneId] && !zoneMuted[userEmitterZoneId]) - audioManager.play('text-sound.wav', 0.5) - - const popInIdentifier = `${emitterUserId}-pop-in` - meta['pop-in'] = characterPopIns.createOrUpdate(popInIdentifier, data.content, { - target: emitterPlayer, - className: messageReceived.style, - autoClose: messageReceived.duration, - parseURL: true, - classList: 'copy', - offset: characterPopInOffset, - }) - } - - window.dispatchEvent( - new CustomEvent(eventTypes.onPeerDataReceived, { - detail: { data: dataReceived, userEmitter, meta }, - }) - ) - }, - getCharacter(userId) { return this.characters[userId] }, diff --git a/core/client/user-streams.js b/core/client/user-streams.js index 60e79abe0..409b06e46 100644 --- a/core/client/user-streams.js +++ b/core/client/user-streams.js @@ -49,12 +49,6 @@ userStreams = { this.stopTracks(screenStream) this.streams.screen.instance = undefined - Object.entries(peer.calls).forEach(([key, call]) => { - if (key.indexOf('-screen') === -1) return - debug('me -> you screen ****** I stop sharing screen, call closing', key) - call.close() - delete peer.calls[key] - }) }, destroyStream(type) { diff --git a/core/client/user-voice-recorder-ability.js b/core/client/user-voice-recorder-ability.js index 1d24ed471..38474d269 100644 --- a/core/client/user-voice-recorder-ability.js +++ b/core/client/user-voice-recorder-ability.js @@ -149,23 +149,6 @@ const sendAudioChunksToTargets = (chunks, userIds) => { uploadInstance.start() } -sendAudioChunksToUsersInZone = async (chunks) => { - const user = Meteor.user() - const usersInZone = zoneManager.usersInZone(zoneManager.currentZone(user)) - const userInZoneIds = usersInZone.map((u) => u._id) - - try { - await networkManager.sendData(userInZoneIds, { - type: 'audio', - emitter: user._id, - data: chunks, - }) - lp.notif.success(`πŸ“£ Everyone has heard your powerful voice`) - } catch { - lp.notif.warning('❌ No one is there to hear you') - } -} - sendAudioChunksToNearUsers = (chunks) => { const { nearUsers } = userProximitySensor const userIds = [...new Set(_.keys(nearUsers))].filter((target) => target !== Meteor.userId()) diff --git a/core/modules/meet/client/meet-low-level.hbs.html b/core/modules/meet/client/meet-low-level.hbs.html index 2f4ada5db..adc60d2d5 100644 --- a/core/modules/meet/client/meet-low-level.hbs.html +++ b/core/modules/meet/client/meet-low-level.hbs.html @@ -1,26 +1,25 @@ - - - - -