diff --git a/package-lock.json b/package-lock.json index 7bbaf9d4..9c191ad0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2587,9 +2587,9 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "arraybuffer.slice": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", - "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=" + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" }, "arrify": { "version": "1.0.1", @@ -3291,9 +3291,9 @@ } }, "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" }, "block-stream": { "version": "0.0.9", @@ -5688,21 +5688,20 @@ } }, "engine.io-client": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.5.tgz", - "integrity": "sha512-AYTgHyeVUPitsseqjoedjhYJapNVoSPShbZ+tEUX9/73jgZ/Z3sUlJf9oYgdEBBdVhupUpUqSxH0kBCXlQnmZg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.1.tgz", + "integrity": "sha512-RJNmA+A9Js+8Aoq815xpGAsgWH1VoSYM//2VgIiu9lNOaHFfLpTjH4tOzktBpjIs5lvOfiNY1dwf+NuU6D38Mw==", "requires": { "component-emitter": "1.2.1", "component-inherit": "0.0.3", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", "has-cors": "1.1.0", "indexof": "0.0.1", - "parsejson": "0.0.3", "parseqs": "0.0.5", "parseuri": "0.0.5", - "ws": "~1.1.5", - "xmlhttprequest-ssl": "1.5.3", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", "yeast": "0.1.2" }, "dependencies": { @@ -5711,41 +5710,26 @@ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" - }, "ws": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", - "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" + "async-limiter": "~1.0.0" } } } }, "engine.io-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", - "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", + "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", "requires": { "after": "0.8.2", - "arraybuffer.slice": "0.0.6", + "arraybuffer.slice": "~0.0.7", "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary": "0.1.7", - "wtf-8": "1.0.0" + "blob": "0.0.5", + "has-binary2": "~1.0.2" } }, "enhanced-resolve": { @@ -5763,6 +5747,11 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" }, + "err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" + }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -7879,6 +7868,21 @@ } } }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, "has-cors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", @@ -12996,6 +13000,22 @@ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" }, + "promise-retry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", + "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "dependencies": { + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" + } + } + }, "prompts": { "version": "0.1.14", "resolved": "https://registry.npmjs.org/prompts/-/prompts-0.1.14.tgz", @@ -13117,6 +13137,29 @@ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" }, + "queued-socket.io": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/queued-socket.io/-/queued-socket.io-1.0.5.tgz", + "integrity": "sha512-qcOE4ToFvLUpAMRYOq2f01lJdZ0pKyX2dpcsyKMl+p4ba+hGMbYG61egzPIyt7UNBIpSDBxxq8y2RfowdDLrFw==", + "requires": { + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "ramda": { "version": "0.24.1", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", @@ -14276,20 +14319,23 @@ } }, "socket.io-client": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.4.tgz", - "integrity": "sha1-7J+CA1btme9tNX8HVtZIcXvdQoE=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", + "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", "requires": { "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", "component-emitter": "1.2.1", - "debug": "2.3.3", - "engine.io-client": "~1.8.4", - "has-binary": "0.1.7", + "debug": "~4.1.0", + "engine.io-client": "~3.4.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", "indexof": "0.0.1", "object-component": "0.0.3", + "parseqs": "0.0.5", "parseuri": "0.0.5", - "socket.io-parser": "2.3.1", + "socket.io-parser": "~3.3.0", "to-array": "0.1.4" }, "dependencies": { @@ -14297,60 +14343,41 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" } } }, "socket.io-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", - "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", - "requires": { - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "3.3.2" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" }, "dependencies": { "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { - "ms": "0.7.1" + "ms": "2.0.0" } }, "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" }, "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -16129,6 +16156,141 @@ "integrity": "sha1-V8kEJoYJcCbvtfwEjFj8lu4mRjg=", "requires": { "socket.io-client": "^1.4.6" + }, + "dependencies": { + "arraybuffer.slice": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", + "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=" + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "requires": { + "ms": "0.7.2" + } + }, + "engine.io-client": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.5.tgz", + "integrity": "sha512-AYTgHyeVUPitsseqjoedjhYJapNVoSPShbZ+tEUX9/73jgZ/Z3sUlJf9oYgdEBBdVhupUpUqSxH0kBCXlQnmZg==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "2.3.3", + "engine.io-parser": "1.3.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parsejson": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~1.1.5", + "xmlhttprequest-ssl": "1.5.3", + "yeast": "0.1.2" + } + }, + "engine.io-parser": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", + "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "0.0.6", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary": "0.1.7", + "wtf-8": "1.0.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" + }, + "socket.io-client": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.4.tgz", + "integrity": "sha1-7J+CA1btme9tNX8HVtZIcXvdQoE=", + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "2.3.3", + "engine.io-client": "~1.8.4", + "has-binary": "0.1.7", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseuri": "0.0.5", + "socket.io-parser": "2.3.1", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", + "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", + "requires": { + "component-emitter": "1.1.2", + "debug": "2.2.0", + "isarray": "0.0.1", + "json3": "3.3.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", + "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=" + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + }, + "ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "requires": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + }, + "xmlhttprequest-ssl": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", + "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=" + } } }, "vue-star-rating": { @@ -16794,9 +16956,9 @@ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" }, "xmlhttprequest-ssl": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" }, "xtend": { "version": "4.0.2", diff --git a/package.json b/package.json index 6fedb845..8b1b7ee6 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,10 @@ "moment-timezone": "^0.5.26", "node-sass": "^4.13.1", "portal-gun": "git://github.com/claydotio/portal-gun.git", + "promise-retry": "^1.1.1", + "queued-socket.io": "^1.0.5", "sass-loader": "^7.1.0", + "socket.io-client": "^2.3.0", "style-resources-loader": "^1.2.1", "typeface-work-sans": "0.0.72", "validator": "^6.3.0", diff --git a/src/components/App/index.vue b/src/components/App/index.vue index f99e5f7f..ca18c9d7 100644 --- a/src/components/App/index.vue +++ b/src/components/App/index.vue @@ -20,8 +20,6 @@ + + diff --git a/src/views/SessionView/SessionChat/index.vue b/src/views/SessionView/SessionChat/index.vue index 27e8efb8..45d130e1 100644 --- a/src/views/SessionView/SessionChat/index.vue +++ b/src/views/SessionView/SessionChat/index.vue @@ -9,14 +9,25 @@ />
- -
+ +
Messages cannot contain personal information or profanity ×
+ +
+ +
+
@@ -63,7 +74,7 @@ import _ from "lodash"; import { mapState, mapGetters } from "vuex"; import ChatBot from "./ChatBot"; -import SessionService from "@/services/SessionService"; +import LoadingMessage from "@/components/LoadingMessage"; import ModerationService from "@/services/ModerationService"; import StudentAvatarUrl from "@/assets/defaultavatar3.png"; import VolunteerAvatarUrl from "@/assets/defaultavatar4.png"; @@ -75,12 +86,11 @@ import VolunteerAvatarUrl from "@/assets/defaultavatar4.png"; */ export default { name: "session-chat", - components: { ChatBot }, + components: { ChatBot, LoadingMessage }, data() { return { - currentSession: SessionService.currentSession, newMessage: "", - chatWarningIsShown: false, + moderationWarningIsShown: false, typingTimeout: null, typingIndicatorShown: false }; @@ -88,6 +98,7 @@ export default { computed: { ...mapState({ user: state => state.user.user, + currentSession: state => state.user.session, messages: state => (state.user.session.messages || []).map(message => { // compute avatar style from picture @@ -100,23 +111,28 @@ export default { message.avatarStyle = { backgroundImage: `url(${picture})` }; return message; - }) + }), + isSessionConnectionAlive: state => state.user.isSessionConnectionAlive }), ...mapGetters({ sessionPartner: "user/sessionPartner", - isSessionWaitingForVolunteer: "user/isSessionWaitingForVolunteer" - }) + isSessionWaitingForVolunteer: "user/isSessionWaitingForVolunteer", + isSessionAlive: "user/isSessionAlive" + }), + isSessionConnectionFailure: function() { + return !this.isSessionConnectionAlive && this.isSessionAlive; + } }, methods: { showModerationWarning() { - this.chatWarningIsShown = true; + this.moderationWarningIsShown = true; }, hideModerationWarning() { - this.chatWarningIsShown = false; + this.moderationWarningIsShown = false; }, showNewMessage(message) { this.$socket.emit("message", { - sessionId: this.currentSession.sessionId, + sessionId: this.currentSession._id, user: this.user, message }); @@ -127,7 +143,7 @@ export default { notTyping() { // Tell the server that the user is no longer typing this.$socket.emit("notTyping", { - sessionId: this.currentSession.sessionId + sessionId: this.currentSession._id }); }, handleMessage(event) { @@ -160,7 +176,7 @@ export default { // Typing handler for when non-Enter/Backspace keys are pressed this.$socket.emit("typing", { - sessionId: this.currentSession.sessionId + sessionId: this.currentSession._id }); /** Every time a key is pressed, set an inactive timer @@ -222,27 +238,35 @@ export default { position: absolute; left: 0; top: 0; - padding: 12px 52px 12px 12px; - transition: all 0.15s ease-in; + padding: 12px; z-index: 1; -} + transition: all 0.15s ease-in; -.chat-warning__close { - font-size: 3.5rem; - width: 40px; - padding: 10px; - margin-right: 5px; - cursor: pointer; - display: block; - position: absolute; - right: 0; - top: 50%; - transform: translateY(-50%); -} + &-enter, + &-leave-to { + top: -64px; + } + + &--moderation { + padding-right: 52px; + } -.chat-warning--slide-enter, -.chat-warning--slide-leave-to { - top: -64px; + &--connection { + background: rgba(110, 140, 171, 0.87); + } + + &__close { + font-size: 3.5rem; + width: 40px; + padding: 10px; + margin-right: 5px; + cursor: pointer; + display: block; + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); + } } .messages { @@ -250,7 +274,7 @@ export default { position: relative; height: 100%; overflow: auto; - padding-bottom: 20px; + padding-bottom: 35px; } .message { diff --git a/src/views/SessionView/SessionHeader.vue b/src/views/SessionView/SessionHeader.vue index 581a1455..d0023386 100644 --- a/src/views/SessionView/SessionHeader.vue +++ b/src/views/SessionView/SessionHeader.vue @@ -31,7 +31,7 @@ Report
-
+
Cancel @@ -74,7 +74,6 @@ import LoadingMessage from "@/components/LoadingMessage"; export default { data() { return { - currentSession: SessionService.currentSession, connectionMsg: "", connectionMsgType: "", reconnectAttemptMsg: "" @@ -85,7 +84,8 @@ export default { }, computed: { ...mapState({ - user: state => state.user.user + user: state => state.user.user, + session: state => state.user.session }), ...mapGetters({ sessionPartner: "user/sessionPartner", @@ -129,48 +129,34 @@ export default { } } - this.$store.dispatch("user/clearSession"); - let studentId = ""; let volunteerId = null; let subTopic = null; let topic = null; - let sessionId = SessionService.currentSession.sessionId; + let sessionId = this.session._id; - if ( - SessionService.currentSession && - SessionService.currentSession.data.student - ) { - studentId = SessionService.currentSession.data.student._id; + if (this.session.student) { + studentId = this.session.student._id; } - if ( - SessionService.currentSession && - SessionService.currentSession.data.volunteer - ) { - volunteerId = SessionService.currentSession.data.volunteer._id; + if (this.session.volunteer) { + volunteerId = this.session.volunteer._id; } - if ( - SessionService.currentSession && - SessionService.currentSession.data.type - ) { - topic = SessionService.currentSession.data.type; + if (this.session.type) { + topic = this.session.type; } - if ( - SessionService.currentSession && - SessionService.currentSession.data.subTopic - ) { - subTopic = SessionService.currentSession.data.subTopic; + if (this.session.subTopic) { + subTopic = this.session.subTopic; } - if (volunteerId) { - SessionService.endSession(this, sessionId) - .then(() => { - this.$socket.disconnect(); - const url = - "/feedback/" + + SessionService.endSession(this, sessionId) + .then(() => { + this.$socket.disconnect(); + this.$store.dispatch("user/sessionDisconnected"); + const url = volunteerId + ? "/feedback/" + sessionId + "/" + topic + @@ -181,18 +167,11 @@ export default { "/" + studentId + "/" + - volunteerId; - router.push(url); - }) - .catch(this.alertCouldNotEnd); - } else { - SessionService.endSession(this, sessionId) - .then(() => { - this.$socket.disconnect(); - router.push("/"); - }) - .catch(this.alertCouldNotEnd); - } + volunteerId + : "/"; + router.push(url); + }) + .catch(this.alertCouldNotEnd); }, reportSession() { this.$store.dispatch("app/modal/show", { diff --git a/src/views/SessionView/index.vue b/src/views/SessionView/index.vue index 31353251..b955d05f 100644 --- a/src/views/SessionView/index.vue +++ b/src/views/SessionView/index.vue @@ -55,6 +55,7 @@ import Whiteboard from "./Whiteboard"; import SessionChat from "./SessionChat"; import SessionFulfilledModal from "./SessionFulfilledModal"; +import ConnectionTroubleModal from "./ConnectionTroubleModal"; const headerData = { component: "SessionHeader" @@ -89,17 +90,18 @@ export default { return { whiteboardOpen: false, icon: "Pencil.png", - sessionReconnecting: false, isNewSession: false }; }, computed: { ...mapState({ user: state => state.user.user, - session: state => state.user.session + session: state => state.user.session, + isSessionConnectionAlive: state => state.user.isSessionConnectionAlive }), ...mapGetters({ - mobileMode: "app/mobileMode" + mobileMode: "app/mobileMode", + isAuthenticated: "user/isAuthenticated" }), shouldHideWhiteboardSection() { @@ -133,23 +135,43 @@ export default { promise = SessionService.newSession( this, type, - this.$route.params.subTopic + this.$route.params.subTopic, + { + onRetry: (res, abort) => { + this.showTroubleStartingModal(abort); + } + } ); this.isNewSession = true; } else { - promise = SessionService.useExistingSession(this, id); + promise = SessionService.useExistingSession(this, id, { + onRetry: (res, abort) => { + this.showTroubleJoiningModal(abort); + } + }); this.isNewSession = false; } promise .then(sessionId => { - this.$socket.connect(); - this.joinSession(sessionId); + // ensure we restore user when we get a successful response + if (!this.isAuthenticated) { + this.$store.dispatch("user/fetchUser"); + } + + if (this.$socket.connected) { + this.joinSession(sessionId); + this.$store.dispatch("user/sessionConnected"); + } else { + this.$socket.connect(); + } }) .catch(err => { - window.alert("Could not start new help session"); + if (err.status !== 0 && err.code !== "EUSERABORTED") { + window.alert("Could not start new help session"); + Sentry.captureException(err); + } this.$router.replace("/"); - Sentry.captureException(err); }); }, sockets: { @@ -167,16 +189,26 @@ export default { }); }, reconnect_attempt() { - this.sessionReconnecting = true; + this.$store.dispatch("user/sessionDisconnected"); + if (!this.session || !this.session._id) { + this.showTroubleStartingModal(); + } }, connect() { - if (this.sessionReconnecting) { - if (this.session && this.session._id) { - // we still need to re-join the room after Socket.IO re-establishes the connection + this.$store.dispatch("user/sessionConnected"); + + if (this.session && this.session._id) { + if ( + (!this.session.student || + this.session.student._id !== this.user._id) && + (!this.session.volunteer || + this.session.volunteer._id !== this.user._id) + ) { + // join the session if we haven't done so already this.joinSession(this.session._id); - } else { - location.reload(); } + } else if (this.$route.params.sessionId) { + this.joinSession(this.$route.params.sessionId); } } }, @@ -204,14 +236,52 @@ export default { } }, joinSession(sessionId) { - this.$socket.emit("join", { - sessionId, - user: this.user + this.$queuedSocket.emit( + "join", + { + sessionId, + user: this.user + }, + 1 + ); + }, + showTroubleStartingModal(abort) { + const TROUBLE_STARTING_MESSAGE = ` + The system seems to be having a problem starting your new session. + Please check your Internet connection. + `; + + this.showConnectionTroubleModal(abort, TROUBLE_STARTING_MESSAGE); + }, + showTroubleJoiningModal(abort) { + const TROUBLE_JOINING_MESSAGE = ` + The system seems to be having a problem joining your session. + Please check your Internet connection. + `; + + this.showConnectionTroubleModal(abort, TROUBLE_JOINING_MESSAGE); + }, + showConnectionTroubleModal(abort, message) { + this.$store.dispatch("app/modal/show", { + component: ConnectionTroubleModal, + data: { + message, + acceptText: "Abort Session", + alertModal: true, + abortFunction: abort + } }); }, tryClicked() { this.sessionReconnecting = true; } + }, + watch: { + isSessionConnectionAlive(newValue, oldValue) { + if (newValue && !oldValue) { + this.$store.dispatch("app/modal/hide"); + } + } } };