mirror of
https://github.com/wassname/talk.git
synced 2026-07-02 08:13:45 +08:00
Merge pull request #1793 from coralproject/auth-views
[next] Auth views
This commit is contained in:
@@ -19,6 +19,9 @@ const config: Config = {
|
||||
"core/client/stream/**/*.ts",
|
||||
"core/client/stream/**/*.tsx",
|
||||
"core/client/stream/**/*.graphql",
|
||||
"core/client/auth/**/*.ts",
|
||||
"core/client/auth/**/*.tsx",
|
||||
"core/client/auth/**/*.graphql",
|
||||
"core/server/**/*.graphql",
|
||||
],
|
||||
ignore: [
|
||||
|
||||
Generated
+86
-73
@@ -5681,6 +5681,12 @@
|
||||
"ylru": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"cached-iterable": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/cached-iterable/-/cached-iterable-0.2.1.tgz",
|
||||
"integrity": "sha512-8zAVjMjdn/S/QXJaOnqsko0+ZJzXT2Dum2u9TMGg5YR9fxONPrUjuO9VYqnb1AoldXeYVAcNJLgT5Q8WaIJSgA==",
|
||||
"dev": true
|
||||
},
|
||||
"call-me-maybe": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
|
||||
@@ -9943,9 +9949,9 @@
|
||||
"integrity": "sha1-A5/fI/iCPkQMOPMnfm/vEXQhWzA="
|
||||
},
|
||||
"fluent": {
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/fluent/-/fluent-0.6.4.tgz",
|
||||
"integrity": "sha512-EXfMJmnGbUgaIC1myIzDk5akAF6+1JrI7KVnNCba2ou7WCKc/2CWa8QshfhImVtettOvEs0z0UVdMrS6zX7pxA==",
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/fluent/-/fluent-0.8.0.tgz",
|
||||
"integrity": "sha512-bZfthhubEH1lKgGIi0fIDeNkZrfEOu3MrLbi284LdxNG+9Q5gq2KsuoocumqNPStVtWo3S3/1p8RIqd34u3Mzw==",
|
||||
"dev": true
|
||||
},
|
||||
"fluent-intl-polyfill": {
|
||||
@@ -9964,15 +9970,22 @@
|
||||
"dev": true
|
||||
},
|
||||
"fluent-react": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/fluent-react/-/fluent-react-0.7.0.tgz",
|
||||
"integrity": "sha512-XgAG06hcVW6oQu3NqLB4KACFBDC9broXG4XDP2xqmj+/DPmZlhHMMD73tFz1mBxCs1pLeojmsYdgyl8l6fF4SA==",
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/fluent-react/-/fluent-react-0.8.0.tgz",
|
||||
"integrity": "sha512-mO8iPb+muWopEDcbNgb66kr6Tl9tPjRpguDaez9W0xU1hiJ9fQ6EfdCxCUQOYsnVnbruLJqxaRsExSRrCamLCg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fluent": "^0.4.0 || ^0.6.0",
|
||||
"cached-iterable": "^0.2.1",
|
||||
"fluent-sequence": "^0.2.0",
|
||||
"prop-types": "^15.6.0"
|
||||
}
|
||||
},
|
||||
"fluent-sequence": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fluent-sequence/-/fluent-sequence-0.2.0.tgz",
|
||||
"integrity": "sha512-t8fc4rHvzO9Yk8otP8LkTqWo6mzjdemooQcnHlDrNzrYAnwsSbVFIlthnkzK2pLsRnO9Ybmw4lXOYUx+fAIyJw==",
|
||||
"dev": true
|
||||
},
|
||||
"flush-write-stream": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
|
||||
@@ -10167,24 +10180,24 @@
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"optional": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"optional": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
|
||||
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10194,12 +10207,12 @@
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
@@ -10208,34 +10221,34 @@
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
|
||||
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
|
||||
"optional": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"optional": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10244,25 +10257,25 @@
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.5.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz",
|
||||
"integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==",
|
||||
"optional": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||
"optional": true
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
|
||||
"optional": true
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.5",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
|
||||
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10271,13 +10284,13 @@
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"optional": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10293,7 +10306,7 @@
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10307,13 +10320,13 @@
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||
"optional": true
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.21",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz",
|
||||
"integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10322,7 +10335,7 @@
|
||||
},
|
||||
"ignore-walk": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
|
||||
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10331,7 +10344,7 @@
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10341,18 +10354,18 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
@@ -10360,13 +10373,13 @@
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"optional": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
@@ -10374,12 +10387,12 @@
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
|
||||
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
@@ -10388,7 +10401,7 @@
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz",
|
||||
"integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10397,7 +10410,7 @@
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
@@ -10405,13 +10418,13 @@
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"optional": true
|
||||
},
|
||||
"needle": {
|
||||
"version": "2.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz",
|
||||
"integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10422,7 +10435,7 @@
|
||||
},
|
||||
"node-pre-gyp": {
|
||||
"version": "0.10.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz",
|
||||
"integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10440,7 +10453,7 @@
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
|
||||
"integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10450,13 +10463,13 @@
|
||||
},
|
||||
"npm-bundled": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz",
|
||||
"integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==",
|
||||
"optional": true
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.1.10",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz",
|
||||
"integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10466,7 +10479,7 @@
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10478,18 +10491,18 @@
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"optional": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
@@ -10497,19 +10510,19 @@
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
|
||||
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
||||
"optional": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"optional": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
|
||||
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10519,19 +10532,19 @@
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"optional": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
||||
"optional": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.7",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz",
|
||||
"integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10543,7 +10556,7 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"optional": true
|
||||
}
|
||||
@@ -10551,7 +10564,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10566,7 +10579,7 @@
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
||||
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10575,42 +10588,42 @@
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"optional": true
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
||||
"optional": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"optional": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"optional": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
@@ -10620,7 +10633,7 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10629,7 +10642,7 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
@@ -10637,13 +10650,13 @@
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz",
|
||||
"integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10658,13 +10671,13 @@
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"optional": true
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
|
||||
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -10673,12 +10686,12 @@
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
|
||||
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k="
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -151,10 +151,10 @@
|
||||
"eventemitter2": "^5.0.1",
|
||||
"final-form": "^4.8.1",
|
||||
"flat": "^4.1.0",
|
||||
"fluent": "^0.6.4",
|
||||
"fluent": "^0.8.0",
|
||||
"fluent-intl-polyfill": "^0.1.0",
|
||||
"fluent-langneg": "^0.1.0",
|
||||
"fluent-react": "^0.7.0",
|
||||
"fluent-react": "^0.8.0",
|
||||
"graphql-playground-middleware-express": "^1.7.2",
|
||||
"graphql-schema-typescript": "^1.2.1",
|
||||
"gulp": "^4.0.0",
|
||||
|
||||
@@ -20,12 +20,15 @@ export default {
|
||||
appLocales: resolveSrc("locales"),
|
||||
appThemeVariables: resolveSrc("core/client/ui/theme/variables.ts"),
|
||||
appThemeVariablesCSS: resolveSrc("core/client/ui/theme/variables.css"),
|
||||
|
||||
appStreamHTML: resolveSrc("core/client/stream/index.html"),
|
||||
appStreamLocalesTemplate: resolveSrc("core/client/stream/locales.ts"),
|
||||
appStreamIndex: resolveSrc("core/client/stream/index.tsx"),
|
||||
|
||||
appAuthHTML: resolveSrc("core/client/auth/index.html"),
|
||||
appAuthLocalesTemplate: resolveSrc("core/client/auth/locales.ts"),
|
||||
appAuthIndex: resolveSrc("core/client/auth/index.tsx"),
|
||||
|
||||
appEmbedIndex: resolveSrc("core/client/embed/index.ts"),
|
||||
appEmbedHTML: resolveSrc("core/client/embed/index.html"),
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Here we add global stylings for body and document */
|
||||
:global {
|
||||
body {
|
||||
margin: "0";
|
||||
margin: 0;
|
||||
|
||||
/* Support for all WebKit browsers. */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
@@ -12,4 +12,7 @@
|
||||
|
||||
.root {
|
||||
width: 100%;
|
||||
padding: var(--spacing-unit) var(--spacing-unit) calc(2 * var(--spacing-unit))
|
||||
var(--spacing-unit);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { shallow } from "enzyme";
|
||||
import React from "react";
|
||||
|
||||
import { PropTypesOf } from "talk-framework/types";
|
||||
|
||||
import App from "./App";
|
||||
|
||||
it("renders sign in", () => {
|
||||
const props: PropTypesOf<typeof App> = {
|
||||
view: "SIGN_IN",
|
||||
};
|
||||
const wrapper = shallow(<App {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
@@ -1,22 +1,41 @@
|
||||
import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { Flex } from "talk-ui/components";
|
||||
|
||||
import React, { StatelessComponent } from "react";
|
||||
import * as styles from "./App.css";
|
||||
|
||||
import ForgotPasswordContainer from "../containers/ForgotPasswordContainer";
|
||||
import ResetPasswordContainer from "../containers/ResetPasswordContainer";
|
||||
import SignInContainer from "../containers/SignInContainer";
|
||||
import SignUpContainer from "../containers/SignUpContainer";
|
||||
|
||||
// TODO: (cvle) Remove %future added value when we have Relay 1.6
|
||||
// https://github.com/facebook/relay/commit/1e87e43add7667a494f7ff4cfa7f03f1ab8d81a2
|
||||
export type View =
|
||||
| "SIGN_UP"
|
||||
| "SIGN_IN"
|
||||
| "FORGOT_PASSWORD"
|
||||
| "RESET_PASSWORD"
|
||||
| "%future added value";
|
||||
|
||||
export interface AppProps {
|
||||
// TODO: (cvle) Remove %future added value when we have Relay 1.6
|
||||
// https://github.com/facebook/relay/commit/1e87e43add7667a494f7ff4cfa7f03f1ab8d81a2
|
||||
view: "SIGN_UP" | "SIGN_IN" | "FORGOT_PASSWORD" | "%future added value";
|
||||
view: View;
|
||||
}
|
||||
|
||||
const App: StatelessComponent<AppProps> = props => {
|
||||
return (
|
||||
<Flex justifyContent="center" className={styles.root}>
|
||||
Current View: {props.view}
|
||||
</Flex>
|
||||
);
|
||||
const renderView = (view: View) => {
|
||||
switch (view) {
|
||||
case "SIGN_UP":
|
||||
return <SignUpContainer />;
|
||||
case "SIGN_IN":
|
||||
return <SignInContainer />;
|
||||
case "FORGOT_PASSWORD":
|
||||
return <ForgotPasswordContainer />;
|
||||
case "RESET_PASSWORD":
|
||||
return <ResetPasswordContainer />;
|
||||
default:
|
||||
throw new Error(`Unknown view ${view}`);
|
||||
}
|
||||
};
|
||||
|
||||
const App: StatelessComponent<AppProps> = ({ view }) => (
|
||||
<div className={styles.root}>{renderView(view)}</div>
|
||||
);
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { Field, Form } from "react-final-form";
|
||||
import { OnSubmit } from "talk-framework/lib/form";
|
||||
|
||||
import {
|
||||
composeValidators,
|
||||
required,
|
||||
validateEmail,
|
||||
} from "talk-framework/lib/validation";
|
||||
|
||||
import {
|
||||
Button,
|
||||
CallOut,
|
||||
FormField,
|
||||
HorizontalGutter,
|
||||
InputLabel,
|
||||
TextField,
|
||||
Typography,
|
||||
ValidationMessage,
|
||||
} from "talk-ui/components";
|
||||
|
||||
import AutoHeightContainer from "../containers/AutoHeightContainer";
|
||||
|
||||
interface FormProps {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface ForgotPasswordForm {
|
||||
onSubmit: OnSubmit<FormProps>;
|
||||
}
|
||||
|
||||
const ForgotPassword: StatelessComponent<ForgotPasswordForm> = props => {
|
||||
return (
|
||||
<Form onSubmit={props.onSubmit}>
|
||||
{({ handleSubmit, submitting, submitError }) => (
|
||||
<form autoComplete="off" onSubmit={handleSubmit}>
|
||||
<AutoHeightContainer />
|
||||
<HorizontalGutter size="double">
|
||||
<Localized id="forgotPassword-forgotPasswordHeader">
|
||||
<Typography variant="heading1" align="center">
|
||||
Forgot Password
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Localized id="forgotPassword-enterEmailAndGetALink">
|
||||
<Typography variant="bodyCopy">
|
||||
Enter your email address below and we will send you a link to
|
||||
reset your password.
|
||||
</Typography>
|
||||
</Localized>
|
||||
{submitError && (
|
||||
<CallOut color="error" fullWidth>
|
||||
{submitError}
|
||||
</CallOut>
|
||||
)}
|
||||
<Field
|
||||
name="email"
|
||||
validate={composeValidators(required, validateEmail)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="forgotPassword-emailAddressLabel">
|
||||
<InputLabel>Email Address</InputLabel>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="forgotPassword-emailAddressTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Email Address"
|
||||
color={
|
||||
meta.touched && (meta.error || meta.submitError)
|
||||
? "error"
|
||||
: "regular"
|
||||
}
|
||||
fullWidth
|
||||
disabled={submitting}
|
||||
/>
|
||||
</Localized>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
<Localized id="forgotPassword-sendEmailButton">
|
||||
<Button
|
||||
variant="filled"
|
||||
color="primary"
|
||||
size="large"
|
||||
fullWidth
|
||||
disabled={submitting}
|
||||
>
|
||||
Send Email
|
||||
</Button>
|
||||
</Localized>
|
||||
</HorizontalGutter>
|
||||
</form>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForgotPassword;
|
||||
@@ -0,0 +1,154 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { Field, Form } from "react-final-form";
|
||||
import { OnSubmit } from "talk-framework/lib/form";
|
||||
|
||||
import {
|
||||
composeValidators,
|
||||
required,
|
||||
validateEqualPasswords,
|
||||
validatePassword,
|
||||
} from "talk-framework/lib/validation";
|
||||
|
||||
import {
|
||||
Button,
|
||||
CallOut,
|
||||
FormField,
|
||||
HorizontalGutter,
|
||||
InputDescription,
|
||||
InputLabel,
|
||||
TextField,
|
||||
Typography,
|
||||
ValidationMessage,
|
||||
} from "talk-ui/components";
|
||||
|
||||
import AutoHeightContainer from "../containers/AutoHeightContainer";
|
||||
|
||||
interface FormProps {
|
||||
password: string;
|
||||
confirmPassword: string;
|
||||
}
|
||||
|
||||
export interface ResetPasswordForm {
|
||||
onSubmit: OnSubmit<FormProps>;
|
||||
}
|
||||
|
||||
const ResetPassword: StatelessComponent<ResetPasswordForm> = props => {
|
||||
return (
|
||||
<Form onSubmit={props.onSubmit}>
|
||||
{({ handleSubmit, submitting, submitError }) => (
|
||||
<form autoComplete="off" onSubmit={handleSubmit}>
|
||||
<AutoHeightContainer />
|
||||
<HorizontalGutter size="double">
|
||||
<Localized id="resetPassword-resetPasswordHeader">
|
||||
<Typography variant="heading1" align="center">
|
||||
Reset Password
|
||||
</Typography>
|
||||
</Localized>
|
||||
{submitError && (
|
||||
<CallOut color="error" fullWidth>
|
||||
{submitError}
|
||||
</CallOut>
|
||||
)}
|
||||
<Field
|
||||
name="password"
|
||||
validate={composeValidators(required, validatePassword)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="resetPassword-passwordLabel">
|
||||
<InputLabel>Password</InputLabel>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="resetPassword-passwordDescription"
|
||||
$minLength={8}
|
||||
>
|
||||
<InputDescription>
|
||||
{"Must be at least {$minLength} characters"}
|
||||
</InputDescription>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="resetPassword-passwordTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
color={
|
||||
meta.touched && (meta.error || meta.submitError)
|
||||
? "error"
|
||||
: "regular"
|
||||
}
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
/>
|
||||
</Localized>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
<Field
|
||||
name="confirmPassword"
|
||||
validate={composeValidators(required, validateEqualPasswords)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="resetPassword-confirmPasswordLabel">
|
||||
<InputLabel>Confirm Password</InputLabel>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="resetPassword-confirmPasswordTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Confirm Password"
|
||||
type="password"
|
||||
color={
|
||||
meta.touched && (meta.error || meta.submitError)
|
||||
? "error"
|
||||
: "regular"
|
||||
}
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
/>
|
||||
</Localized>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
<Localized id="resetPassword-resetPasswordButton">
|
||||
<Button
|
||||
variant="filled"
|
||||
color="primary"
|
||||
size="large"
|
||||
fullWidth
|
||||
disabled={submitting}
|
||||
>
|
||||
Reset Password
|
||||
</Button>
|
||||
</Localized>
|
||||
</HorizontalGutter>
|
||||
</form>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResetPassword;
|
||||
@@ -0,0 +1,179 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { Field, Form } from "react-final-form";
|
||||
import { OnSubmit } from "talk-framework/lib/form";
|
||||
|
||||
import {
|
||||
composeValidators,
|
||||
required,
|
||||
validateEmail,
|
||||
} from "talk-framework/lib/validation";
|
||||
|
||||
import {
|
||||
Button,
|
||||
CallOut,
|
||||
Flex,
|
||||
FormField,
|
||||
HorizontalGutter,
|
||||
InputLabel,
|
||||
TextField,
|
||||
Typography,
|
||||
ValidationMessage,
|
||||
} from "talk-ui/components";
|
||||
|
||||
import AutoHeightContainer from "../containers/AutoHeightContainer";
|
||||
|
||||
interface FormProps {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface SignInForm {
|
||||
onSubmit: OnSubmit<FormProps>;
|
||||
onGotoSignUp: () => void;
|
||||
onGotoForgotPassword: () => void;
|
||||
}
|
||||
|
||||
const SignIn: StatelessComponent<SignInForm> = props => {
|
||||
return (
|
||||
<Form onSubmit={props.onSubmit}>
|
||||
{({ handleSubmit, submitting, submitError }) => (
|
||||
<form autoComplete="off" onSubmit={handleSubmit}>
|
||||
<AutoHeightContainer />
|
||||
<HorizontalGutter size="double">
|
||||
<Localized id="signIn-signInToJoinHeader">
|
||||
<Typography variant="heading1" align="center">
|
||||
Sign in to join the conversation
|
||||
</Typography>
|
||||
</Localized>
|
||||
|
||||
{submitError && (
|
||||
<CallOut color="error" fullWidth>
|
||||
{submitError}
|
||||
</CallOut>
|
||||
)}
|
||||
|
||||
<Field
|
||||
name="email"
|
||||
validate={composeValidators(required, validateEmail)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="signIn-emailAddressLabel">
|
||||
<InputLabel>Email Address</InputLabel>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="signIn-emailAddressTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Email Address"
|
||||
color={
|
||||
meta.touched && (meta.error || meta.submitError)
|
||||
? "error"
|
||||
: "regular"
|
||||
}
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
/>
|
||||
</Localized>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage fullWidth>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
<Field name="password" validate={composeValidators(required)}>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="signIn-passwordLabel">
|
||||
<InputLabel>Password</InputLabel>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="signIn-passwordTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
color={
|
||||
meta.touched && (meta.error || meta.submitError)
|
||||
? "error"
|
||||
: "regular"
|
||||
}
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
/>
|
||||
</Localized>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage fullWidth>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
<Flex justifyContent="flex-end">
|
||||
<Localized id="signIn-forgotYourPassword">
|
||||
<Button
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
variant="underlined"
|
||||
color="primary"
|
||||
size="small"
|
||||
disabled={submitting}
|
||||
onClick={props.onGotoForgotPassword}
|
||||
>
|
||||
Forgot your password?
|
||||
</Button>
|
||||
</Localized>
|
||||
</Flex>
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
<Localized id="signIn-signInAndJoinButton">
|
||||
<Button
|
||||
variant="filled"
|
||||
color="primary"
|
||||
size="large"
|
||||
type="submit"
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</Button>
|
||||
</Localized>
|
||||
<Flex justifyContent="center">
|
||||
<Localized
|
||||
id="signIn-noAccountSignUp"
|
||||
button={
|
||||
<Button
|
||||
id="signIn-gotoSignUpButton"
|
||||
variant="underlined"
|
||||
size="small"
|
||||
color="primary"
|
||||
disabled={submitting}
|
||||
onClick={props.onGotoSignUp}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Typography variant="bodyCopy" container={Flex}>
|
||||
{"Don't have an account? <button>Sign Up</button>"}
|
||||
</Typography>
|
||||
</Localized>
|
||||
</Flex>
|
||||
</HorizontalGutter>
|
||||
</form>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignIn;
|
||||
@@ -0,0 +1,253 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
import { Field, Form } from "react-final-form";
|
||||
import { OnSubmit } from "talk-framework/lib/form";
|
||||
import {
|
||||
composeValidators,
|
||||
required,
|
||||
validateEmail,
|
||||
validateEqualPasswords,
|
||||
validatePassword,
|
||||
validateUsername,
|
||||
} from "talk-framework/lib/validation";
|
||||
import {
|
||||
Button,
|
||||
CallOut,
|
||||
Flex,
|
||||
FormField,
|
||||
HorizontalGutter,
|
||||
InputDescription,
|
||||
InputLabel,
|
||||
TextField,
|
||||
Typography,
|
||||
ValidationMessage,
|
||||
} from "talk-ui/components";
|
||||
|
||||
import AutoHeightContainer from "../containers/AutoHeightContainer";
|
||||
|
||||
interface FormProps {
|
||||
email: string;
|
||||
username: string;
|
||||
password: string;
|
||||
confirmPassword: string;
|
||||
}
|
||||
|
||||
export interface SignUpForm {
|
||||
onSubmit: OnSubmit<FormProps>;
|
||||
onGotoSignIn: () => void;
|
||||
}
|
||||
|
||||
const SignUp: StatelessComponent<SignUpForm> = props => {
|
||||
return (
|
||||
<Form onSubmit={props.onSubmit}>
|
||||
{({ handleSubmit, submitting, submitError }) => (
|
||||
<form autoComplete="off" onSubmit={handleSubmit}>
|
||||
<AutoHeightContainer />
|
||||
<HorizontalGutter size="double">
|
||||
<Localized id="signUp-signUpToJoinHeader">
|
||||
<Typography variant="heading1" align="center">
|
||||
Sign up to join the conversation
|
||||
</Typography>
|
||||
</Localized>
|
||||
{submitError && (
|
||||
<CallOut color="error" fullWidth>
|
||||
{submitError}
|
||||
</CallOut>
|
||||
)}
|
||||
<Field
|
||||
name="email"
|
||||
validate={composeValidators(required, validateEmail)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="signUp-emailAddressLabel">
|
||||
<InputLabel>Email Address</InputLabel>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="signUp-emailAddressTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Email Address"
|
||||
color={
|
||||
meta.touched && (meta.error || meta.submitError)
|
||||
? "error"
|
||||
: "regular"
|
||||
}
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
/>
|
||||
</Localized>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage fullWidth>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
<Field
|
||||
name="username"
|
||||
validate={composeValidators(required, validateUsername)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="signUp-usernameLabel">
|
||||
<InputLabel>Username</InputLabel>
|
||||
</Localized>
|
||||
<Localized id="signUp-usernameDescription">
|
||||
<InputDescription>
|
||||
A unique identifier displayed on your comments. You may
|
||||
use “_” and “.”
|
||||
</InputDescription>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="signUp-usernameTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Username"
|
||||
color={
|
||||
meta.touched && (meta.error || meta.submitError)
|
||||
? "error"
|
||||
: "regular"
|
||||
}
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
/>
|
||||
</Localized>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage fullWidth>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
<Field
|
||||
name="password"
|
||||
validate={composeValidators(required, validatePassword)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="signUp-passwordLabel">
|
||||
<InputLabel>Password</InputLabel>
|
||||
</Localized>
|
||||
<Localized id="signUp-passwordDescription" $minLength={8}>
|
||||
<InputDescription>
|
||||
{"Must be at least {$minLength} characters"}
|
||||
</InputDescription>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="signUp-passwordTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
color={
|
||||
meta.touched && (meta.error || meta.submitError)
|
||||
? "error"
|
||||
: "regular"
|
||||
}
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
/>
|
||||
</Localized>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage fullWidth>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
<Field
|
||||
name="confirmPassword"
|
||||
validate={composeValidators(required, validateEqualPasswords)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="signUp-confirmPasswordLabel">
|
||||
<InputLabel>Confirm Password</InputLabel>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="signUp-confirmPasswordTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Confirm Password"
|
||||
type="password"
|
||||
color={
|
||||
meta.touched && (meta.error || meta.submitError)
|
||||
? "error"
|
||||
: "regular"
|
||||
}
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
/>
|
||||
</Localized>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<ValidationMessage fullWidth>
|
||||
{meta.error || meta.submitError}
|
||||
</ValidationMessage>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
<Localized id="signUp-signUpAndJoinButton">
|
||||
<Button
|
||||
variant="filled"
|
||||
color="primary"
|
||||
size="large"
|
||||
type="submit"
|
||||
disabled={submitting}
|
||||
fullWidth
|
||||
>
|
||||
Sign up and join the conversation
|
||||
</Button>
|
||||
</Localized>
|
||||
<Flex justifyContent="center">
|
||||
<Localized
|
||||
id="signUp-accountAvailableSignIn"
|
||||
button={
|
||||
<Button
|
||||
id="signUp-gotoSignInButton"
|
||||
variant="underlined"
|
||||
size="small"
|
||||
color="primary"
|
||||
onClick={props.onGotoSignIn}
|
||||
disabled={submitting}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Typography variant="bodyCopy" container={Flex}>
|
||||
{"Already have an account? <button>Sign In </button>"}
|
||||
</Typography>
|
||||
</Localized>
|
||||
</Flex>
|
||||
</HorizontalGutter>
|
||||
</form>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignUp;
|
||||
@@ -0,0 +1,9 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders sign in 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(SignInContainer)))) />
|
||||
</div>
|
||||
`;
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Component } from "react";
|
||||
|
||||
import resizePopup from "../dom/resizePopup";
|
||||
|
||||
/**
|
||||
* A container that adapts the window height to the current body size
|
||||
* when this is mounted or updated.
|
||||
*/
|
||||
export default class AutoHeightContainer extends Component {
|
||||
private updateWindowSize() {
|
||||
window.requestAnimationFrame(() => setTimeout(resizePopup, 0));
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
this.updateWindowSize();
|
||||
}
|
||||
|
||||
public componentDidUpdate() {
|
||||
this.updateWindowSize();
|
||||
}
|
||||
|
||||
public render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import React, { Component } from "react";
|
||||
import ForgotPassword from "../components/ForgotPassword";
|
||||
|
||||
class ForgotPasswordContainer extends Component {
|
||||
public render() {
|
||||
// tslint:disable-next-line:no-empty
|
||||
return <ForgotPassword onSubmit={() => {}} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default ForgotPasswordContainer;
|
||||
@@ -0,0 +1,11 @@
|
||||
import React, { Component } from "react";
|
||||
import ResetPassword from "../components/ResetPassword";
|
||||
|
||||
class ResetPasswordContainer extends Component {
|
||||
public render() {
|
||||
// tslint:disable-next-line:no-empty
|
||||
return <ResetPassword onSubmit={() => {}} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default ResetPasswordContainer;
|
||||
@@ -0,0 +1,40 @@
|
||||
import { FORM_ERROR } from "final-form";
|
||||
import React, { Component } from "react";
|
||||
import SignIn, { SignInForm } from "../components/SignIn";
|
||||
import {
|
||||
SetViewMutation,
|
||||
SignInMutation,
|
||||
withSetViewMutation,
|
||||
withSignInMutation,
|
||||
} from "../mutations";
|
||||
|
||||
interface SignInContainerProps {
|
||||
signIn: SignInMutation;
|
||||
setView: SetViewMutation;
|
||||
}
|
||||
|
||||
class SignInContainer extends Component<SignInContainerProps> {
|
||||
private onSubmit: SignInForm["onSubmit"] = async (input, form) => {
|
||||
try {
|
||||
await this.props.signIn(input);
|
||||
return form.reset();
|
||||
} catch (error) {
|
||||
return { [FORM_ERROR]: error.message };
|
||||
}
|
||||
};
|
||||
private goToForgotPassword = () =>
|
||||
this.props.setView({ view: "FORGOT_PASSWORD" });
|
||||
private goToSignUp = () => this.props.setView({ view: "SIGN_UP" });
|
||||
public render() {
|
||||
return (
|
||||
<SignIn
|
||||
onSubmit={this.onSubmit}
|
||||
onGotoForgotPassword={this.goToForgotPassword}
|
||||
onGotoSignUp={this.goToSignUp}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withSetViewMutation(withSignInMutation(SignInContainer));
|
||||
export default enhanced;
|
||||
@@ -0,0 +1,33 @@
|
||||
import { FORM_ERROR } from "final-form";
|
||||
import React, { Component } from "react";
|
||||
import SignUp, { SignUpForm } from "../components/SignUp";
|
||||
|
||||
import {
|
||||
SetViewMutation,
|
||||
SignUpMutation,
|
||||
withSetViewMutation,
|
||||
withSignUpMutation,
|
||||
} from "../mutations";
|
||||
|
||||
interface SignUpContainerProps {
|
||||
signUp: SignUpMutation;
|
||||
setView: SetViewMutation;
|
||||
}
|
||||
|
||||
class SignUpContainer extends Component<SignUpContainerProps> {
|
||||
private onSubmit: SignUpForm["onSubmit"] = async (input, form) => {
|
||||
try {
|
||||
return await this.props.signUp(input);
|
||||
form.reset();
|
||||
} catch (error) {
|
||||
return { [FORM_ERROR]: error.message };
|
||||
}
|
||||
};
|
||||
private goToSignIn = () => this.props.setView({ view: "SIGN_IN" });
|
||||
public render() {
|
||||
return <SignUp onSubmit={this.onSubmit} onGotoSignIn={this.goToSignIn} />;
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withSetViewMutation(withSignUpMutation(SignUpContainer));
|
||||
export default enhanced;
|
||||
@@ -0,0 +1,17 @@
|
||||
function resizePopup() {
|
||||
const innerHeight = window.document.body.offsetHeight;
|
||||
window.resizeTo(
|
||||
window.outerWidth,
|
||||
innerHeight + window.outerHeight - window.innerHeight
|
||||
);
|
||||
}
|
||||
|
||||
let resizedAlready = false;
|
||||
export default function resizeOncePerFrame() {
|
||||
if (resizedAlready) {
|
||||
return;
|
||||
}
|
||||
resizedAlready = true;
|
||||
requestAnimationFrame(() => setTimeout(() => (resizedAlready = false), 0));
|
||||
resizePopup();
|
||||
}
|
||||
@@ -9,9 +9,29 @@ import {
|
||||
} from "talk-framework/lib/bootstrap";
|
||||
|
||||
import AppContainer from "./containers/AppContainer";
|
||||
import resizePopup from "./dom/resizePopup";
|
||||
import { initLocalState } from "./local";
|
||||
import localesData from "./locales";
|
||||
|
||||
/**
|
||||
* Adapt popup height to current content every 100ms.
|
||||
*
|
||||
* The goal is to smooth out height inconsistensies e.g. when fonts
|
||||
* are switched out or other resources being loaded that React has no influence
|
||||
* over.
|
||||
*
|
||||
* This works in addition to <AutoHeightContainer /> which
|
||||
* adapt popup height when React does an update.
|
||||
*/
|
||||
function pollPopupHeight(interval: number = 100) {
|
||||
setTimeout(() => {
|
||||
window.requestAnimationFrame(() => {
|
||||
resizePopup();
|
||||
pollPopupHeight(interval);
|
||||
});
|
||||
}, interval);
|
||||
}
|
||||
|
||||
// This is called when the context is first initialized.
|
||||
async function init({ relayEnvironment }: TalkContext) {
|
||||
await initLocalState(relayEnvironment);
|
||||
@@ -32,6 +52,7 @@ async function main() {
|
||||
);
|
||||
|
||||
ReactDOM.render(<Index />, document.getElementById("app"));
|
||||
pollPopupHeight();
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
@@ -2,6 +2,7 @@ enum View {
|
||||
SIGN_UP
|
||||
SIGN_IN
|
||||
FORGOT_PASSWORD
|
||||
RESET_PASSWORD
|
||||
}
|
||||
|
||||
type Local {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { LOCAL_ID } from "talk-framework/lib/relay/withLocalStateContainer";
|
||||
|
||||
export interface SetViewInput {
|
||||
// TODO: replace with generated typescript types.
|
||||
view: "SIGN_IN" | "SIGN_UP" | "FORGOT_PASSWORD";
|
||||
view: "SIGN_IN" | "SIGN_UP" | "FORGOT_PASSWORD" | "RESET_PASSWORD";
|
||||
}
|
||||
|
||||
export type SetViewMutation = (input: SetViewInput) => Promise<void>;
|
||||
|
||||
@@ -17,6 +17,7 @@ export async function commit(
|
||||
window.close();
|
||||
} catch (err) {
|
||||
postMessage.send("authError", err.toString(), window.opener);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { pick } from "lodash";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
@@ -12,11 +13,15 @@ export async function commit(
|
||||
{ rest, postMessage }: TalkContext
|
||||
) {
|
||||
try {
|
||||
const result = await signUp(rest, input);
|
||||
const result = await signUp(
|
||||
rest,
|
||||
pick(input, "email", "password", "username")
|
||||
);
|
||||
postMessage.send("setAuthToken", result.token, window.opener);
|
||||
window.close();
|
||||
} catch (err) {
|
||||
postMessage.send("authError", err.toString(), window.opener);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,971 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`accepts correct password 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value="testtest"
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`accepts valid email 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`checks for invalid email 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="invalid-email"
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
Please enter a valid email address.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders sign in form 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`shows error when submitting empty form 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorError TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="ValidationMessage-root ValidationMessage-colorError ValidationMessage-fullWidth"
|
||||
>
|
||||
<span
|
||||
className="Icon-root ValidationMessage-icon Icon-sm"
|
||||
>
|
||||
warning
|
||||
</span>
|
||||
<span>
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`shows server error 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={true}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={true}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value="testtest"
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined Button-disabled"
|
||||
disabled={true}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`shows server error 2`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="CallOut-root CallOut-colorError CallOut-fullWidth"
|
||||
>
|
||||
Server Error
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value="testtest"
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`submits form successfully 1`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="CallOut-root CallOut-colorError CallOut-fullWidth"
|
||||
>
|
||||
Server Error
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={true}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value="hans@test.com"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={true}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value="testtest"
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined Button-disabled"
|
||||
disabled={true}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`submits form successfully 2`] = `
|
||||
<div
|
||||
className="App-root"
|
||||
>
|
||||
<form
|
||||
autoComplete="off"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-double"
|
||||
>
|
||||
<h1
|
||||
className="Typography-root Typography-heading1 Typography-colorTextPrimary Typography-alignCenter"
|
||||
>
|
||||
Sign in to join the conversation
|
||||
</h1>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="email"
|
||||
onChange={[Function]}
|
||||
placeholder="Email Address"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
<label
|
||||
className="Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="TextField-root TextField-colorRegular TextField-fullWidth"
|
||||
disabled={false}
|
||||
name="password"
|
||||
onChange={[Function]}
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
disabled={false}
|
||||
id="signIn-gotoForgotPasswordButton"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Forgot your password?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorPrimary Button-variantFilled Button-fullWidth"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
<div
|
||||
className="Flex-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Typography-root Typography-bodyCopy Typography-colorTextPrimary Flex-flex"
|
||||
>
|
||||
<span>
|
||||
Don't have an account? <button>Sign Up</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
import { IResolvers } from "graphql-tools";
|
||||
import { Environment, RecordProxy, RecordSourceProxy } from "relay-runtime";
|
||||
import { createRelayEnvironment } from "talk-framework/testHelpers";
|
||||
|
||||
interface CreateEnvironmentParams {
|
||||
logNetwork?: boolean;
|
||||
resolvers?: IResolvers<any, any>;
|
||||
initLocalState?: (
|
||||
local: RecordProxy,
|
||||
source: RecordSourceProxy,
|
||||
environment: Environment
|
||||
) => void;
|
||||
}
|
||||
|
||||
export default function createEnvironment(params: CreateEnvironmentParams) {
|
||||
return createRelayEnvironment({
|
||||
network: {
|
||||
logNetwork: params.logNetwork,
|
||||
resolvers: params.resolvers || {},
|
||||
projectName: "tenant",
|
||||
},
|
||||
initLocalState: (localRecord, source, environment) => {
|
||||
if (params.initLocalState) {
|
||||
params.initLocalState(localRecord, source, environment);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// Enable after this is solved: https://github.com/projectfluent/fluent.js/issues/280
|
||||
|
||||
import React from "react";
|
||||
import TestRenderer from "react-test-renderer";
|
||||
import { RecordProxy } from "relay-runtime";
|
||||
|
||||
import AppContainer from "talk-auth/containers/AppContainer";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
|
||||
const environment = createEnvironment({
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue("SIGN_IN", "view");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
<TalkContextProvider value={context}>
|
||||
<AppContainer />
|
||||
</TalkContextProvider>
|
||||
);
|
||||
|
||||
it("renders sign in form", async () => {
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("navigates to sign up form", async () => {
|
||||
testRenderer.root
|
||||
.findByProps({ id: "signIn-gotoSignUpButton" })
|
||||
.props.onClick();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("navigates to sign in form", async () => {
|
||||
testRenderer.root
|
||||
.findByProps({ id: "signUp-gotoSignInButton" })
|
||||
.props.onClick();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("navigates to forgot password form", async () => {
|
||||
testRenderer.root
|
||||
.findByProps({ id: "signIn-gotoForgotPasswordButton" })
|
||||
.props.onClick();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
@@ -0,0 +1,140 @@
|
||||
import React from "react";
|
||||
import TestRenderer, { ReactTestInstance } from "react-test-renderer";
|
||||
import { RecordProxy } from "relay-runtime";
|
||||
import sinon from "sinon";
|
||||
|
||||
import AppContainer from "talk-auth/containers/AppContainer";
|
||||
import { animationFrame, timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
|
||||
const environment = createEnvironment({
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue("SIGN_IN", "view");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
<TalkContextProvider value={context}>
|
||||
<AppContainer />
|
||||
</TalkContextProvider>
|
||||
);
|
||||
|
||||
const inputPredicate = (name: string) => (n: ReactTestInstance) => {
|
||||
return n.props.name === name && n.props.onChange;
|
||||
};
|
||||
|
||||
const form = testRenderer.root.findByType("form");
|
||||
|
||||
it("renders sign in form", async () => {
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows error when submitting empty form", async () => {
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for invalid email", async () => {
|
||||
form
|
||||
.find(inputPredicate("email"))
|
||||
.props.onChange({ target: { value: "invalid-email" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts valid email", async () => {
|
||||
form
|
||||
.find(inputPredicate("email"))
|
||||
.props.onChange({ target: { value: "hans@test.com" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts correct password", async () => {
|
||||
form
|
||||
.find(inputPredicate("password"))
|
||||
.props.onChange({ target: { value: "testtest" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows server error", async () => {
|
||||
const windowMock = sinon.mock(window);
|
||||
windowMock.expects("resizeTo");
|
||||
|
||||
const error = new Error("Server Error");
|
||||
const restMock = sinon.mock(context.rest);
|
||||
restMock
|
||||
.expects("fetch")
|
||||
.withArgs("/tenant/auth/local", {
|
||||
method: "POST",
|
||||
body: {
|
||||
email: "hans@test.com",
|
||||
password: "testtest",
|
||||
},
|
||||
})
|
||||
.once()
|
||||
.throws(error);
|
||||
|
||||
const postMessageMock = sinon.mock(context.postMessage);
|
||||
postMessageMock
|
||||
.expects("send")
|
||||
.withArgs("authError", error.toString(), window.opener)
|
||||
.once();
|
||||
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
// popup resize will be triggered if we wait for the animation frame first.
|
||||
await animationFrame();
|
||||
await timeout();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
postMessageMock.verify();
|
||||
windowMock.verify();
|
||||
});
|
||||
|
||||
it("submits form successfully", async () => {
|
||||
const windowMock = sinon.mock(window);
|
||||
windowMock.expects("close").once();
|
||||
windowMock.expects("resizeTo");
|
||||
|
||||
const restMock = sinon.mock(context.rest);
|
||||
restMock
|
||||
.expects("fetch")
|
||||
.withArgs("/tenant/auth/local", {
|
||||
method: "POST",
|
||||
body: {
|
||||
email: "hans@test.com",
|
||||
password: "testtest",
|
||||
},
|
||||
})
|
||||
.once()
|
||||
.returns({ token: "auth-token" });
|
||||
|
||||
const postMessageMock = sinon.mock(context.postMessage);
|
||||
postMessageMock
|
||||
.expects("send")
|
||||
.withArgs("setAuthToken", "auth-token", window.opener)
|
||||
.once();
|
||||
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
// popup resize will be triggered if we wait for the animation frame first.
|
||||
await animationFrame();
|
||||
await timeout();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
postMessageMock.verify();
|
||||
windowMock.verify();
|
||||
});
|
||||
@@ -0,0 +1,191 @@
|
||||
import React from "react";
|
||||
import TestRenderer, { ReactTestInstance } from "react-test-renderer";
|
||||
import { RecordProxy } from "relay-runtime";
|
||||
import sinon from "sinon";
|
||||
|
||||
import AppContainer from "talk-auth/containers/AppContainer";
|
||||
import { animationFrame, timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
|
||||
const environment = createEnvironment({
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue("SIGN_UP", "view");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
<TalkContextProvider value={context}>
|
||||
<AppContainer />
|
||||
</TalkContextProvider>
|
||||
);
|
||||
|
||||
const inputPredicate = (name: string) => (n: ReactTestInstance) => {
|
||||
return n.props.name === name && n.props.onChange;
|
||||
};
|
||||
|
||||
const form = testRenderer.root.findByType("form");
|
||||
|
||||
it("renders sign up form", async () => {
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows error when submitting empty form", async () => {
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for invalid email", async () => {
|
||||
form
|
||||
.find(inputPredicate("email"))
|
||||
.props.onChange({ target: { value: "invalid-email" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts valid email", async () => {
|
||||
form
|
||||
.find(inputPredicate("email"))
|
||||
.props.onChange({ target: { value: "hans@test.com" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for too short username", async () => {
|
||||
form
|
||||
.find(inputPredicate("username"))
|
||||
.props.onChange({ target: { value: "u" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for too long username", async () => {
|
||||
form
|
||||
.find(inputPredicate("username"))
|
||||
.props.onChange({ target: { value: "a".repeat(100) } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for invalid characters in username", async () => {
|
||||
form
|
||||
.find(inputPredicate("username"))
|
||||
.props.onChange({ target: { value: "$%$§$%$§%" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts valid username", async () => {
|
||||
form
|
||||
.find(inputPredicate("username"))
|
||||
.props.onChange({ target: { value: "hans" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for too short password", async () => {
|
||||
form
|
||||
.find(inputPredicate("password"))
|
||||
.props.onChange({ target: { value: "pass" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts correct password", async () => {
|
||||
form
|
||||
.find(inputPredicate("password"))
|
||||
.props.onChange({ target: { value: "testtest" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("checks for wrong password confirmation", async () => {
|
||||
form
|
||||
.find(inputPredicate("confirmPassword"))
|
||||
.props.onChange({ target: { value: "not-matching" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("accepts correct password confirmation", async () => {
|
||||
form
|
||||
.find(inputPredicate("confirmPassword"))
|
||||
.props.onChange({ target: { value: "testtest" } });
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows server error", async () => {
|
||||
const windowMock = sinon.mock(window);
|
||||
windowMock.expects("resizeTo");
|
||||
|
||||
const error = new Error("Server Error");
|
||||
const restMock = sinon.mock(context.rest);
|
||||
restMock
|
||||
.expects("fetch")
|
||||
.withArgs("/tenant/auth/local/signup", {
|
||||
method: "POST",
|
||||
body: {
|
||||
username: "hans",
|
||||
email: "hans@test.com",
|
||||
password: "testtest",
|
||||
},
|
||||
})
|
||||
.once()
|
||||
.throws(error);
|
||||
|
||||
const postMessageMock = sinon.mock(context.postMessage);
|
||||
postMessageMock
|
||||
.expects("send")
|
||||
.withArgs("authError", error.toString(), window.opener)
|
||||
.once();
|
||||
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
// popup resize will be triggered if we wait for the animation frame first.
|
||||
await animationFrame();
|
||||
await timeout();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
postMessageMock.verify();
|
||||
windowMock.verify();
|
||||
});
|
||||
|
||||
it("submits form successfully", async () => {
|
||||
const windowMock = sinon.mock(window);
|
||||
windowMock.expects("close").once();
|
||||
windowMock.expects("resizeTo");
|
||||
|
||||
const restMock = sinon.mock(context.rest);
|
||||
restMock
|
||||
.expects("fetch")
|
||||
.withArgs("/tenant/auth/local/signup", {
|
||||
method: "POST",
|
||||
body: {
|
||||
username: "hans",
|
||||
email: "hans@test.com",
|
||||
password: "testtest",
|
||||
},
|
||||
})
|
||||
.once()
|
||||
.returns({ token: "auth-token" });
|
||||
|
||||
const postMessageMock = sinon.mock(context.postMessage);
|
||||
postMessageMock
|
||||
.expects("send")
|
||||
.withArgs("setAuthToken", "auth-token", window.opener)
|
||||
.once();
|
||||
|
||||
form.props.onSubmit();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
// popup resize will be triggered if we wait for the animation frame first.
|
||||
await animationFrame();
|
||||
await timeout();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
postMessageMock.verify();
|
||||
windowMock.verify();
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LocalizationProvider } from "fluent-react/compat";
|
||||
import { MessageContext } from "fluent/compat";
|
||||
import { FluentBundle } from "fluent/compat";
|
||||
import { Child as PymChild } from "pym.js";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { MediaQueryMatchers } from "react-responsive";
|
||||
@@ -15,8 +15,8 @@ export interface TalkContext {
|
||||
/** relayEnvironment for our relay framework. */
|
||||
relayEnvironment: Environment;
|
||||
|
||||
/** localMessages for our i18n framework. */
|
||||
localeMessages: MessageContext[];
|
||||
/** localeBundles for our i18n framework. */
|
||||
localeBundles: FluentBundle[];
|
||||
|
||||
/** formatter for timeago. */
|
||||
timeagoFormatter?: Formatter;
|
||||
@@ -61,7 +61,7 @@ export const TalkContextProvider: StatelessComponent<{
|
||||
value: TalkContext;
|
||||
}> = ({ value, children }) => (
|
||||
<Provider value={value}>
|
||||
<LocalizationProvider messages={value.localeMessages}>
|
||||
<LocalizationProvider bundles={value.localeBundles}>
|
||||
<UIContext.Provider
|
||||
value={{
|
||||
timeagoFormatter: value.timeagoFormatter,
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { ClickFarAwayRegister } from "talk-ui/components/ClickOutside";
|
||||
|
||||
import { generateMessages, LocalesData, negotiateLanguages } from "../i18n";
|
||||
import { generateBundles, LocalesData, negotiateLanguages } from "../i18n";
|
||||
import { createFetch, TokenGetter } from "../network";
|
||||
import { PostMessageService } from "../postMessage";
|
||||
import { TalkContext } from "./TalkContext";
|
||||
@@ -104,17 +104,17 @@ export default async function createContext({
|
||||
console.log(`Negotiated locales ${JSON.stringify(locales)}`);
|
||||
}
|
||||
|
||||
const localeMessages = await generateMessages(locales, localesData);
|
||||
const localeBundles = await generateBundles(locales, localesData);
|
||||
|
||||
// Assemble context.
|
||||
const context = {
|
||||
relayEnvironment,
|
||||
localeMessages,
|
||||
localeBundles,
|
||||
timeagoFormatter,
|
||||
pym,
|
||||
eventEmitter,
|
||||
registerClickFarAway,
|
||||
rest: new RestClient("/api"),
|
||||
rest: new RestClient("/api", tokenGetter),
|
||||
postMessage: new PostMessageService(),
|
||||
localStorage: createLocalStorage(),
|
||||
sessionStorage: createSessionStorage(),
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { mapValues, once } from "lodash";
|
||||
import { ReactNode } from "react";
|
||||
import { VALIDATION_REQUIRED, VALIDATION_TOO_SHORT } from "../messages";
|
||||
import { VALIDATION_REQUIRED } from "../messages";
|
||||
|
||||
/**
|
||||
* ValidationError represents all possible string values
|
||||
* that is responded by the server.
|
||||
*/
|
||||
type ValidationError = "TOO_SHORT";
|
||||
type ValidationError = "REQUIRED";
|
||||
|
||||
/**
|
||||
* InvalidArgsMap as responded by the server.
|
||||
@@ -36,7 +36,6 @@ interface BadUserInputExtension {
|
||||
* Map server `ValidationError` to a translation message.
|
||||
*/
|
||||
const validationMap = {
|
||||
TOO_SHORT: VALIDATION_TOO_SHORT,
|
||||
REQUIRED: VALIDATION_REQUIRED,
|
||||
};
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@ export { default as NetworkError } from "./networkError";
|
||||
export { default as UnknownServerError } from "./unknownServerError";
|
||||
export { default as BadUserInputError } from "./badUserInputError";
|
||||
export { default as GraphQLError } from "./graphqlError";
|
||||
|
||||
export * from "./graphqlError";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "fluent-intl-polyfill/compat";
|
||||
import { negotiateLanguages as negotiate } from "fluent-langneg/compat";
|
||||
import { MessageContext } from "fluent/compat";
|
||||
import { FluentBundle } from "fluent/compat";
|
||||
|
||||
export interface BundledLocales {
|
||||
[locale: string]: string;
|
||||
@@ -47,18 +47,20 @@ export function negotiateLanguages(
|
||||
}
|
||||
|
||||
// Don't warn in production.
|
||||
let decorateWarnMissing = (cx: MessageContext) => cx;
|
||||
let decorateWarnMissing = (bundle: FluentBundle) => bundle;
|
||||
|
||||
// Warn about missing locales if we are not in production.
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
decorateWarnMissing = (() => {
|
||||
const warnings: string[] = [];
|
||||
return (cx: MessageContext) => {
|
||||
const original = cx.hasMessage;
|
||||
cx.hasMessage = (id: string) => {
|
||||
const result = original.apply(cx, [id]);
|
||||
return (bundle: FluentBundle) => {
|
||||
const original = bundle.hasMessage;
|
||||
bundle.hasMessage = (id: string) => {
|
||||
const result = original.apply(bundle, [id]);
|
||||
if (!result) {
|
||||
const warn = `${cx.locales} translation for key "${id}" not found`;
|
||||
const warn = `${
|
||||
bundle.locales
|
||||
} translation for key "${id}" not found`;
|
||||
if (!warnings.includes(warn)) {
|
||||
// tslint:disable:next-line: no-console
|
||||
console.warn(warn);
|
||||
@@ -67,7 +69,7 @@ if (process.env.NODE_ENV !== "production") {
|
||||
}
|
||||
return result;
|
||||
};
|
||||
return cx;
|
||||
return bundle;
|
||||
};
|
||||
})();
|
||||
}
|
||||
@@ -79,21 +81,21 @@ if (process.env.NODE_ENV !== "production") {
|
||||
*
|
||||
* Use it in conjunction with `negotiateLanguages`.
|
||||
*/
|
||||
export async function generateMessages(
|
||||
export async function generateBundles(
|
||||
locales: ReadonlyArray<string>,
|
||||
data: LocalesData
|
||||
): Promise<MessageContext[]> {
|
||||
): Promise<FluentBundle[]> {
|
||||
const promises = [];
|
||||
|
||||
for (const locale of locales) {
|
||||
const cx = new MessageContext(locale);
|
||||
const bundle = new FluentBundle(locale);
|
||||
if (locale in data.bundled) {
|
||||
cx.addMessages(data.bundled[locale]);
|
||||
promises.push(decorateWarnMissing(cx));
|
||||
bundle.addMessages(data.bundled[locale]);
|
||||
promises.push(decorateWarnMissing(bundle));
|
||||
} else if (locale in data.loadables) {
|
||||
const content = await data.loadables[locale]();
|
||||
cx.addMessages(content);
|
||||
promises.push(decorateWarnMissing(cx));
|
||||
bundle.addMessages(content);
|
||||
promises.push(decorateWarnMissing(bundle));
|
||||
} else {
|
||||
throw Error(`Locale ${locale} not available`);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,44 @@ export const VALIDATION_REQUIRED = () => (
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const VALIDATION_TOO_SHORT = () => (
|
||||
export const VALIDATION_TOO_SHORT = (minLength: number) => (
|
||||
<Localized id="framework-validation-tooShort">
|
||||
<span>This field is too short.</span>
|
||||
<span>{"This field must contain at least {$minLength} characters."}</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const INVALID_EMAIL = () => (
|
||||
<Localized id="framework-validation-invalidEmail">
|
||||
<span>Please enter a valid email address.</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const INVALID_CHARACTERS = () => (
|
||||
<Localized id="framework-validation-invalidCharacters">
|
||||
<span>Invalid characters. Try again.</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const USERNAME_TOO_SHORT = (minLength: number) => (
|
||||
<Localized id="framework-validation-usernameTooShort" $minLength={minLength}>
|
||||
<span>{"Usernames must contain at least {$minLength} characters."}</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const USERNAME_TOO_LONG = (maxLength: number) => (
|
||||
<Localized id="framework-validation-usernameTooLong" $maxLength={maxLength}>
|
||||
<span>{"Usernames cannot be longer than {$maxLength} characters."}</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const PASSWORD_TOO_SHORT = (minLength: number) => (
|
||||
<Localized id="framework-validation-passwordTooShort" $minLength={minLength}>
|
||||
<span>{"Password must contain at least {$minLength} characters."}</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
export const PASSWORDS_DO_NOT_MATCH = () => (
|
||||
<Localized id="framework-validation-passwordsDoNotMatch">
|
||||
<span>Passwords do not match. Try again.</span>
|
||||
</Localized>
|
||||
);
|
||||
|
||||
@@ -17,22 +17,27 @@ const buildOptions = (inputOptions: RequestInit = {}) => {
|
||||
return options;
|
||||
};
|
||||
|
||||
const handleResp = (res: Response) => {
|
||||
if (res.status > 399) {
|
||||
return res.json().then((err: any) => {
|
||||
// TODO: sync error handling with server.
|
||||
const message = err.message || err.error || res.status;
|
||||
const error = new Error(message);
|
||||
throw error;
|
||||
});
|
||||
} else if (res.status === 204) {
|
||||
return res.text();
|
||||
} else {
|
||||
return res.json();
|
||||
// TODO (bc): Wrap response errors into error objects once server errors have been defined
|
||||
|
||||
const handleResp = async (res: Response) => {
|
||||
if (res.status === 404) {
|
||||
const response = await res.text();
|
||||
throw new Error(response);
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
const response = await res.json();
|
||||
throw new Error(response.error);
|
||||
}
|
||||
|
||||
if (res.status === 204) {
|
||||
return res.text();
|
||||
}
|
||||
|
||||
return res.json();
|
||||
};
|
||||
|
||||
type PartialRequestInit = Overwrite<Partial<RequestInit>, { body: any }>;
|
||||
type PartialRequestInit = Overwrite<Partial<RequestInit>, { body?: any }>;
|
||||
|
||||
export class RestClient {
|
||||
public readonly uri: string;
|
||||
@@ -43,7 +48,10 @@ export class RestClient {
|
||||
this.tokenGetter = tokenGetter;
|
||||
}
|
||||
|
||||
public fetch<T>(path: string, options: PartialRequestInit): Promise<T> {
|
||||
public async fetch<T = {}>(
|
||||
path: string,
|
||||
options: PartialRequestInit
|
||||
): Promise<T> {
|
||||
let opts = options;
|
||||
if (this.tokenGetter) {
|
||||
opts = merge({}, options, {
|
||||
@@ -52,6 +60,7 @@ export class RestClient {
|
||||
},
|
||||
});
|
||||
}
|
||||
return fetch(`${this.uri}${path}`, buildOptions(opts)).then(handleResp);
|
||||
const response = await fetch(`${this.uri}${path}`, buildOptions(opts));
|
||||
return handleResp(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import { ReactNode } from "react";
|
||||
import { VALIDATION_REQUIRED } from "./messages";
|
||||
import {
|
||||
INVALID_CHARACTERS,
|
||||
INVALID_EMAIL,
|
||||
PASSWORD_TOO_SHORT,
|
||||
PASSWORDS_DO_NOT_MATCH,
|
||||
USERNAME_TOO_LONG,
|
||||
USERNAME_TOO_SHORT,
|
||||
VALIDATION_REQUIRED,
|
||||
} from "./messages";
|
||||
|
||||
type Validator<T, V> = (v: T, values: V) => ReactNode;
|
||||
|
||||
@@ -31,3 +39,60 @@ export function composeValidators<T = any, V = any>(
|
||||
* required is a Validator that checks that the value is truthy.
|
||||
*/
|
||||
export const required = createValidator(v => !!v, VALIDATION_REQUIRED());
|
||||
|
||||
/**
|
||||
* validateEmail is a Validator that checks that the value is an email.
|
||||
*/
|
||||
export const validateEmail = createValidator(
|
||||
v => /^.+@.+\..+$/.test(v),
|
||||
INVALID_EMAIL()
|
||||
);
|
||||
|
||||
/**
|
||||
* validateUsernameCharacters is a Validator that checks that the username only contains valid characters.
|
||||
*/
|
||||
export const validateUsernameCharacters = createValidator(
|
||||
v => /^[a-zA-Z0-9_.]+$/.test(v),
|
||||
INVALID_CHARACTERS()
|
||||
);
|
||||
|
||||
/**
|
||||
* validateUsernameMinLength is a Validator that checks that the username has a min length of characters
|
||||
*/
|
||||
export const validateUsernameMinLength = createValidator(
|
||||
v => v.length >= 3,
|
||||
USERNAME_TOO_SHORT(3)
|
||||
);
|
||||
|
||||
/**
|
||||
* validateUsernameMaxLength is a Validator that checks that the username has a max length of characters
|
||||
*/
|
||||
export const validateUsernameMaxLength = createValidator(
|
||||
v => v.length <= 20,
|
||||
USERNAME_TOO_LONG(20)
|
||||
);
|
||||
|
||||
/**
|
||||
* validateUsername is a Validator that checks that the username is valid.
|
||||
*/
|
||||
export const validateUsername = composeValidators(
|
||||
validateUsernameCharacters,
|
||||
validateUsernameMinLength,
|
||||
validateUsernameMaxLength
|
||||
);
|
||||
|
||||
/**
|
||||
* validateUsername is a Validator that checks that the value is a valid username.
|
||||
*/
|
||||
export const validatePassword = createValidator(
|
||||
v => v.length >= 8,
|
||||
PASSWORD_TOO_SHORT(8)
|
||||
);
|
||||
|
||||
/**s
|
||||
* validateUsername is a Validator that checks that the value is a valid username.
|
||||
*/
|
||||
export const validateEqualPasswords = createValidator(
|
||||
(v, values) => v === values.password,
|
||||
PASSWORDS_DO_NOT_MATCH()
|
||||
);
|
||||
|
||||
@@ -23,6 +23,8 @@ export async function commit(
|
||||
} else {
|
||||
localStorage.removeItem("authToken");
|
||||
}
|
||||
// Increment auth revision to indicate a change in auth state.
|
||||
record.setValue(record.getValue("authRevision") + 1, "authRevision");
|
||||
|
||||
// Force gc to trigger.
|
||||
environment
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Environment } from "relay-runtime";
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
import { createMutationContainer } from "talk-framework/lib/relay";
|
||||
import signOut from "../rest/signOut";
|
||||
import { commit as setAuthToken } from "./SetAuthTokenMutation";
|
||||
|
||||
export type SignOutMutation = () => Promise<void>;
|
||||
|
||||
export async function commit(
|
||||
environment: Environment,
|
||||
input: undefined,
|
||||
ctx: TalkContext
|
||||
) {
|
||||
await signOut(ctx.rest);
|
||||
await setAuthToken(environment, { authToken: "" }, ctx);
|
||||
}
|
||||
|
||||
export const withSignOutMutation = createMutationContainer("signOut", commit);
|
||||
@@ -3,3 +3,4 @@ export {
|
||||
SetAuthTokenMutation,
|
||||
SetAuthTokenInput,
|
||||
} from "./SetAuthTokenMutation";
|
||||
export { withSignOutMutation, SignOutMutation } from "./SignOutMutation";
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export { default as signIn, SignInInput } from "./signIn";
|
||||
export { default as signUp, SignUpInput } from "./signUp";
|
||||
export { default as signOut } from "./signOut";
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { RestClient } from "../lib/rest";
|
||||
|
||||
export default function signOut(rest: RestClient) {
|
||||
return rest.fetch("/tenant/auth", {
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
@@ -2,7 +2,6 @@ import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { Flex } from "talk-ui/components";
|
||||
|
||||
import PermalinkViewQuery from "../queries/PermalinkViewQuery";
|
||||
import StreamQuery from "../queries/StreamQuery";
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.root {
|
||||
width: 100%;
|
||||
}
|
||||
.footer {
|
||||
margin-top: var(--spacing-unit);
|
||||
|
||||
@@ -16,7 +16,7 @@ const Username: StatelessComponent<UsernameProps> = props => {
|
||||
<Typography
|
||||
variant={matches ? "heading2" : "heading3"}
|
||||
className={styles.root}
|
||||
component="span"
|
||||
container="span"
|
||||
>
|
||||
{props.children}
|
||||
</Typography>
|
||||
|
||||
@@ -2,28 +2,20 @@
|
||||
|
||||
exports[`renders correctly on big screens 1`] = `
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-itemGutter Flex-alignBaseline Flex-directionRow"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignBaseline Flex-directionRow"
|
||||
>
|
||||
<div>
|
||||
Hello World
|
||||
</div>
|
||||
<div>
|
||||
Hello World
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders correctly on small screens 1`] = `
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<div>
|
||||
Hello World
|
||||
</div>
|
||||
<div>
|
||||
Hello World
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.root {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.textField {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { MouseEvent, StatelessComponent } from "react";
|
||||
|
||||
import { Button, Flex, Typography } from "talk-ui/components";
|
||||
import { Button, Typography } from "talk-ui/components";
|
||||
|
||||
import CommentContainer from "../containers/CommentContainer";
|
||||
import * as styles from "./PermalinkView.css";
|
||||
@@ -41,11 +41,7 @@ const PermalinkView: StatelessComponent<PermalinkViewProps> = ({
|
||||
<Typography>Comment not found</Typography>
|
||||
</Localized>
|
||||
)}
|
||||
{comment && (
|
||||
<Flex direction="column">
|
||||
<CommentContainer data={comment} />
|
||||
</Flex>
|
||||
)}
|
||||
{comment && <CommentContainer data={comment} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
.root {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
composes: bodyCopy from "talk-ui/shared/typography.css";
|
||||
|
||||
display: block;
|
||||
height: 100px;
|
||||
height: 150px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: var(--spacing-unit);
|
||||
padding: var(--spacing-unit);
|
||||
border-radius: var(--round-corners);
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.postButtonContainer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
.poweredBy {
|
||||
margin-top: calc(-0.5 * var(--spacing-unit));
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { Field, Form } from "react-final-form";
|
||||
|
||||
import { OnSubmit } from "talk-framework/lib/form";
|
||||
import { required } from "talk-framework/lib/validation";
|
||||
import { Button, Typography } from "talk-ui/components";
|
||||
|
||||
import { Button, Flex, HorizontalGutter, Typography } from "talk-ui/components";
|
||||
import * as styles from "./PostCommentForm.css";
|
||||
import PoweredBy from "./PoweredBy";
|
||||
|
||||
interface FormProps {
|
||||
body: string;
|
||||
@@ -21,31 +19,44 @@ const PostCommentForm: StatelessComponent<PostCommentFormProps> = props => (
|
||||
<Form onSubmit={props.onSubmit}>
|
||||
{({ handleSubmit, submitting }) => (
|
||||
<form autoComplete="off" onSubmit={handleSubmit} className={styles.root}>
|
||||
<Field name="body" validate={required}>
|
||||
{({ input, meta }) => (
|
||||
<div>
|
||||
<textarea
|
||||
className={styles.textarea}
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
/>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<Typography align="right" color="error" gutterBottom>
|
||||
{meta.error || meta.submitError}
|
||||
</Typography>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Field>
|
||||
<div className={styles.postButtonContainer}>
|
||||
<Localized id="comments-postCommentForm-post">
|
||||
<Button color="primary" variant="filled" disabled={submitting}>
|
||||
Post
|
||||
</Button>
|
||||
</Localized>
|
||||
</div>
|
||||
<HorizontalGutter>
|
||||
<Field name="body" validate={required}>
|
||||
{({ input, meta }) => (
|
||||
<div>
|
||||
<textarea
|
||||
className={styles.textarea}
|
||||
name={input.name}
|
||||
onChange={input.onChange}
|
||||
value={input.value}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
{meta.touched &&
|
||||
(meta.error || meta.submitError) && (
|
||||
<Typography align="right" color="error" gutterBottom>
|
||||
{meta.error || meta.submitError}
|
||||
</Typography>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Field>
|
||||
<Flex
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="flex-start"
|
||||
>
|
||||
<PoweredBy className={styles.poweredBy} />
|
||||
<Localized id="comments-postCommentForm-submit">
|
||||
<Button
|
||||
color="primary"
|
||||
variant="filled"
|
||||
disabled={submitting}
|
||||
type="submit"
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Localized>
|
||||
</Flex>
|
||||
</HorizontalGutter>
|
||||
</form>
|
||||
)}
|
||||
</Form>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
.root {
|
||||
}
|
||||
|
||||
.textarea {
|
||||
composes: bodyCopy from "talk-ui/shared/typography.css";
|
||||
display: block;
|
||||
height: 150px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: var(--spacing-unit);
|
||||
border-radius: var(--round-corners);
|
||||
resize: vertical;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { shallow } from "enzyme";
|
||||
import React from "react";
|
||||
|
||||
import PostCommentFormFake from "./PostCommentFormFake";
|
||||
|
||||
it("renders correctly", () => {
|
||||
const wrapper = shallow(<PostCommentFormFake />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { Button, HorizontalGutter } from "talk-ui/components";
|
||||
import * as styles from "./PostCommentFormFake.css";
|
||||
|
||||
const PostCommentFormFake: StatelessComponent = props => (
|
||||
<HorizontalGutter className={styles.root}>
|
||||
<textarea
|
||||
className={styles.textarea}
|
||||
placeholder="Post a comment"
|
||||
disabled
|
||||
/>
|
||||
<Localized id="comments-PostCommentFormFake-signInAndJoin">
|
||||
<Button color="primary" variant="filled" disabled type="submit" fullWidth>
|
||||
Sign in and join the conversation
|
||||
</Button>
|
||||
</Localized>
|
||||
</HorizontalGutter>
|
||||
);
|
||||
|
||||
export default PostCommentFormFake;
|
||||
@@ -0,0 +1,14 @@
|
||||
import { shallow } from "enzyme";
|
||||
import React from "react";
|
||||
|
||||
import { PropTypesOf } from "talk-framework/types";
|
||||
|
||||
import PoweredBy from "./PoweredBy";
|
||||
|
||||
it("renders correctly", () => {
|
||||
const props: PropTypesOf<typeof PoweredBy> = {
|
||||
className: "custom",
|
||||
};
|
||||
const wrapper = shallow(<PoweredBy {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import cn from "classnames";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { Typography } from "talk-ui/components";
|
||||
|
||||
interface Props {
|
||||
className: string;
|
||||
}
|
||||
|
||||
const PoweredBy: StatelessComponent<Props> = props => {
|
||||
return (
|
||||
<div className={cn(props.className)}>
|
||||
<Typography
|
||||
variant="inputDescription"
|
||||
container="span"
|
||||
color="textSecondary"
|
||||
>
|
||||
Powered by
|
||||
</Typography>{" "}
|
||||
<Typography variant="heading4" container="span">
|
||||
The Coral Project
|
||||
</Typography>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PoweredBy;
|
||||
@@ -2,7 +2,7 @@ import { Localized } from "fluent-react/compat";
|
||||
import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { Button, Flex } from "talk-ui/components";
|
||||
import { Button, HorizontalGutter } from "talk-ui/components";
|
||||
|
||||
import CommentContainer from "../containers/CommentContainer";
|
||||
import Indent from "./Indent";
|
||||
@@ -18,11 +18,9 @@ export interface ReplyListProps {
|
||||
const ReplyList: StatelessComponent<ReplyListProps> = props => {
|
||||
return (
|
||||
<Indent>
|
||||
<Flex
|
||||
direction="column"
|
||||
<HorizontalGutter
|
||||
id={`talk-comments-replyList-log--${props.commentID}`}
|
||||
role="log"
|
||||
itemGutter
|
||||
>
|
||||
{props.comments.map(comment => (
|
||||
<CommentContainer key={comment.id} data={comment} />
|
||||
@@ -41,7 +39,7 @@ const ReplyList: StatelessComponent<ReplyListProps> = props => {
|
||||
</Button>
|
||||
</Localized>
|
||||
)}
|
||||
</Flex>
|
||||
</HorizontalGutter>
|
||||
</Indent>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,12 +2,13 @@ import { Localized } from "fluent-react/compat";
|
||||
import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { Button, Flex } from "talk-ui/components";
|
||||
import { Button, HorizontalGutter } from "talk-ui/components";
|
||||
|
||||
import CommentContainer from "../containers/CommentContainer";
|
||||
import PostCommentFormContainer from "../containers/PostCommentFormContainer";
|
||||
import ReplyListContainer from "../containers/ReplyListContainer";
|
||||
import UserBoxContainer from "../containers/UserBoxContainer";
|
||||
import PostCommentFormFake from "./PostCommentFormFake";
|
||||
import * as styles from "./Stream.css";
|
||||
|
||||
export interface StreamProps {
|
||||
@@ -17,25 +18,30 @@ export interface StreamProps {
|
||||
onLoadMore?: () => void;
|
||||
hasMore?: boolean;
|
||||
disableLoadMore?: boolean;
|
||||
user: {} | null;
|
||||
}
|
||||
|
||||
const Stream: StatelessComponent<StreamProps> = props => {
|
||||
return (
|
||||
<Flex className={styles.root} direction="column" itemGutter>
|
||||
<UserBoxContainer />
|
||||
<PostCommentFormContainer assetID={props.assetID} />
|
||||
<Flex
|
||||
direction="column"
|
||||
<HorizontalGutter className={styles.root} size="double">
|
||||
<HorizontalGutter size="half">
|
||||
<UserBoxContainer user={props.user} />
|
||||
{props.user ? (
|
||||
<PostCommentFormContainer assetID={props.assetID} />
|
||||
) : (
|
||||
<PostCommentFormFake />
|
||||
)}
|
||||
</HorizontalGutter>
|
||||
<HorizontalGutter
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
aria-live="polite"
|
||||
itemGutter
|
||||
>
|
||||
{props.comments.map(comment => (
|
||||
<Flex direction="column" key={comment.id} itemGutter>
|
||||
<HorizontalGutter key={comment.id}>
|
||||
<CommentContainer data={comment} />
|
||||
<ReplyListContainer comment={comment} />
|
||||
</Flex>
|
||||
</HorizontalGutter>
|
||||
))}
|
||||
{props.hasMore && (
|
||||
<Localized id="comments-stream-loadMore">
|
||||
@@ -51,8 +57,8 @@ const Stream: StatelessComponent<StreamProps> = props => {
|
||||
</Button>
|
||||
</Localized>
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</HorizontalGutter>
|
||||
</HorizontalGutter>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.child {
|
||||
width: initial;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { shallow } from "enzyme";
|
||||
import { noop } from "lodash";
|
||||
import React from "react";
|
||||
|
||||
import { PropTypesOf } from "talk-framework/types";
|
||||
|
||||
import UserBoxAuthenticated from "./UserBoxAuthenticated";
|
||||
|
||||
it("renders correctly", () => {
|
||||
const props: PropTypesOf<typeof UserBoxAuthenticated> = {
|
||||
onSignOut: noop,
|
||||
username: "Username",
|
||||
};
|
||||
const wrapper = shallow(<UserBoxAuthenticated {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { StatelessComponent } from "react";
|
||||
|
||||
import { Button, Flex, Typography } from "talk-ui/components";
|
||||
|
||||
export interface UserBoxAuthenticatedProps {
|
||||
onSignOut: () => void;
|
||||
username: string;
|
||||
}
|
||||
|
||||
const UserBoxAuthenticated: StatelessComponent<
|
||||
UserBoxAuthenticatedProps
|
||||
> = props => {
|
||||
const Username = () => (
|
||||
<Typography variant="bodyCopyBold" container="span">
|
||||
{props.username}
|
||||
</Typography>
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex itemGutter="half" wrap>
|
||||
<Localized
|
||||
id="comments-userBoxAuthenticated-signedInAs"
|
||||
username={<Username />}
|
||||
>
|
||||
<Typography variant="bodyCopy" container="div">
|
||||
{"Signed in as <username></username>."}
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="comments-userBoxAuthenticated-notYou"
|
||||
button={
|
||||
<Button
|
||||
color="primary"
|
||||
size="small"
|
||||
variant="underlined"
|
||||
onClick={props.onSignOut}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Typography variant="bodyCopy" container={Flex}>
|
||||
{"Not you? <button>Sign Out</button>"}
|
||||
</Typography>
|
||||
</Localized>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserBoxAuthenticated;
|
||||
@@ -15,23 +15,28 @@ const UserBoxUnauthenticated: StatelessComponent<
|
||||
UserBoxUnauthenticatedProps
|
||||
> = props => {
|
||||
return (
|
||||
<Flex>
|
||||
<Flex itemGutter alignItems="center">
|
||||
<MatchMedia gteWidth="sm">
|
||||
<Localized id="comments-userBoxUnauthenticated-joinTheConversation">
|
||||
<Typography
|
||||
className={styles.joinText}
|
||||
variant="bodyCopyBold"
|
||||
component="span"
|
||||
container="span"
|
||||
>
|
||||
Join the conversation
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Typography variant="bodyCopyBold" component="span">
|
||||
<Typography variant="bodyCopyBold" container="span">
|
||||
|
|
||||
</Typography>
|
||||
</MatchMedia>
|
||||
<Localized id="comments-userBoxUnauthenticated-signIn">
|
||||
<Button color="primary" size="small" onClick={props.onSignIn}>
|
||||
<Button
|
||||
color="primary"
|
||||
size="small"
|
||||
variant="underlined"
|
||||
onClick={props.onSignIn}
|
||||
>
|
||||
Sign in
|
||||
</Button>
|
||||
</Localized>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
className="PostCommentFormFake-root"
|
||||
>
|
||||
<textarea
|
||||
className="PostCommentFormFake-textarea"
|
||||
disabled={true}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
<Localized
|
||||
id="comments-PostCommentFormFake-signInAndJoin"
|
||||
>
|
||||
<withPropsOnChange(Button)
|
||||
color="primary"
|
||||
disabled={true}
|
||||
fullWidth={true}
|
||||
type="submit"
|
||||
variant="filled"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</withPropsOnChange(Button)>
|
||||
</Localized>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
`;
|
||||
@@ -0,0 +1,22 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<div
|
||||
className="custom"
|
||||
>
|
||||
<withPropsOnChange(Typography)
|
||||
color="textSecondary"
|
||||
container="span"
|
||||
variant="inputDescription"
|
||||
>
|
||||
Powered by
|
||||
</withPropsOnChange(Typography)>
|
||||
|
||||
<withPropsOnChange(Typography)
|
||||
container="span"
|
||||
variant="heading4"
|
||||
>
|
||||
The Coral Project
|
||||
</withPropsOnChange(Typography)>
|
||||
</div>
|
||||
`;
|
||||
@@ -2,10 +2,8 @@
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<Indent>
|
||||
<withPropsOnChange(Flex)
|
||||
direction="column"
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
id="talk-comments-replyList-log--comment-id"
|
||||
itemGutter={true}
|
||||
role="log"
|
||||
>
|
||||
<Relay(CommentContainer)
|
||||
@@ -24,16 +22,14 @@ exports[`renders correctly 1`] = `
|
||||
}
|
||||
key="comment-2"
|
||||
/>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
</Indent>
|
||||
`;
|
||||
|
||||
exports[`when there is more disables load more button 1`] = `
|
||||
<Indent>
|
||||
<withPropsOnChange(Flex)
|
||||
direction="column"
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
id="talk-comments-replyList-log--comment-id"
|
||||
itemGutter={true}
|
||||
role="log"
|
||||
>
|
||||
<Relay(CommentContainer)
|
||||
@@ -66,16 +62,14 @@ exports[`when there is more disables load more button 1`] = `
|
||||
Show All Replies
|
||||
</withPropsOnChange(Button)>
|
||||
</Localized>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
</Indent>
|
||||
`;
|
||||
|
||||
exports[`when there is more renders a load more button 1`] = `
|
||||
<Indent>
|
||||
<withPropsOnChange(Flex)
|
||||
direction="column"
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
id="talk-comments-replyList-log--comment-id"
|
||||
itemGutter={true}
|
||||
role="log"
|
||||
>
|
||||
<Relay(CommentContainer)
|
||||
@@ -108,6 +102,6 @@ exports[`when there is more renders a load more button 1`] = `
|
||||
Show All Replies
|
||||
</withPropsOnChange(Button)>
|
||||
</Localized>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
</Indent>
|
||||
`;
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<withPropsOnChange(Flex)
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
className="Stream-root"
|
||||
direction="column"
|
||||
itemGutter={true}
|
||||
size="double"
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(UserBoxContainer)))))) />
|
||||
<withContext(createMutationContainer(PostCommentFormContainer))
|
||||
assetID="asset-id"
|
||||
/>
|
||||
<withPropsOnChange(Flex)
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
size="half"
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer))))))))) />
|
||||
<PostCommentFormFake />
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
aria-live="polite"
|
||||
direction="column"
|
||||
id="talk-comments-stream-log"
|
||||
itemGutter={true}
|
||||
role="log"
|
||||
>
|
||||
<withPropsOnChange(Flex)
|
||||
direction="column"
|
||||
itemGutter={true}
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
key="comment-1"
|
||||
>
|
||||
<Relay(CommentContainer)
|
||||
@@ -36,10 +33,8 @@ exports[`renders correctly 1`] = `
|
||||
}
|
||||
}
|
||||
/>
|
||||
</withPropsOnChange(Flex)>
|
||||
<withPropsOnChange(Flex)
|
||||
direction="column"
|
||||
itemGutter={true}
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
key="comment-2"
|
||||
>
|
||||
<Relay(CommentContainer)
|
||||
@@ -56,31 +51,28 @@ exports[`renders correctly 1`] = `
|
||||
}
|
||||
}
|
||||
/>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
`;
|
||||
|
||||
exports[`when there is more disables load more button 1`] = `
|
||||
<withPropsOnChange(Flex)
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
className="Stream-root"
|
||||
direction="column"
|
||||
itemGutter={true}
|
||||
size="double"
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(UserBoxContainer)))))) />
|
||||
<withContext(createMutationContainer(PostCommentFormContainer))
|
||||
assetID="asset-id"
|
||||
/>
|
||||
<withPropsOnChange(Flex)
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
size="half"
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer))))))))) />
|
||||
<PostCommentFormFake />
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
aria-live="polite"
|
||||
direction="column"
|
||||
id="talk-comments-stream-log"
|
||||
itemGutter={true}
|
||||
role="log"
|
||||
>
|
||||
<withPropsOnChange(Flex)
|
||||
direction="column"
|
||||
itemGutter={true}
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
key="comment-1"
|
||||
>
|
||||
<Relay(CommentContainer)
|
||||
@@ -97,10 +89,8 @@ exports[`when there is more disables load more button 1`] = `
|
||||
}
|
||||
}
|
||||
/>
|
||||
</withPropsOnChange(Flex)>
|
||||
<withPropsOnChange(Flex)
|
||||
direction="column"
|
||||
itemGutter={true}
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
key="comment-2"
|
||||
>
|
||||
<Relay(CommentContainer)
|
||||
@@ -117,7 +107,7 @@ exports[`when there is more disables load more button 1`] = `
|
||||
}
|
||||
}
|
||||
/>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
<Localized
|
||||
id="comments-stream-loadMore"
|
||||
>
|
||||
@@ -132,30 +122,27 @@ exports[`when there is more disables load more button 1`] = `
|
||||
Load More
|
||||
</withPropsOnChange(Button)>
|
||||
</Localized>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
`;
|
||||
|
||||
exports[`when there is more renders a load more button 1`] = `
|
||||
<withPropsOnChange(Flex)
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
className="Stream-root"
|
||||
direction="column"
|
||||
itemGutter={true}
|
||||
size="double"
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(UserBoxContainer)))))) />
|
||||
<withContext(createMutationContainer(PostCommentFormContainer))
|
||||
assetID="asset-id"
|
||||
/>
|
||||
<withPropsOnChange(Flex)
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
size="half"
|
||||
>
|
||||
<withContext(createMutationContainer(withContext(createMutationContainer(withContext(createMutationContainer(withContext(withLocalStateContainer(Relay(UserBoxContainer))))))))) />
|
||||
<PostCommentFormFake />
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
aria-live="polite"
|
||||
direction="column"
|
||||
id="talk-comments-stream-log"
|
||||
itemGutter={true}
|
||||
role="log"
|
||||
>
|
||||
<withPropsOnChange(Flex)
|
||||
direction="column"
|
||||
itemGutter={true}
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
key="comment-1"
|
||||
>
|
||||
<Relay(CommentContainer)
|
||||
@@ -172,10 +159,8 @@ exports[`when there is more renders a load more button 1`] = `
|
||||
}
|
||||
}
|
||||
/>
|
||||
</withPropsOnChange(Flex)>
|
||||
<withPropsOnChange(Flex)
|
||||
direction="column"
|
||||
itemGutter={true}
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
key="comment-2"
|
||||
>
|
||||
<Relay(CommentContainer)
|
||||
@@ -192,7 +177,7 @@ exports[`when there is more renders a load more button 1`] = `
|
||||
}
|
||||
}
|
||||
/>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
<Localized
|
||||
id="comments-stream-loadMore"
|
||||
>
|
||||
@@ -207,6 +192,6 @@ exports[`when there is more renders a load more button 1`] = `
|
||||
Load More
|
||||
</withPropsOnChange(Button)>
|
||||
</Localized>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(Flex)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
`;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<withPropsOnChange(Flex)
|
||||
itemGutter="half"
|
||||
wrap={true}
|
||||
>
|
||||
<Localized
|
||||
id="comments-userBoxAuthenticated-signedInAs"
|
||||
username={<Username />}
|
||||
>
|
||||
<withPropsOnChange(Typography)
|
||||
container="div"
|
||||
variant="bodyCopy"
|
||||
>
|
||||
Signed in as <username></username>.
|
||||
</withPropsOnChange(Typography)>
|
||||
</Localized>
|
||||
<Localized
|
||||
button={
|
||||
<withPropsOnChange(Button)
|
||||
color="primary"
|
||||
onClick={[Function]}
|
||||
size="small"
|
||||
variant="underlined"
|
||||
/>
|
||||
}
|
||||
id="comments-userBoxAuthenticated-notYou"
|
||||
>
|
||||
<withPropsOnChange(Typography)
|
||||
container={[Function]}
|
||||
variant="bodyCopy"
|
||||
>
|
||||
Not you? <button>Sign Out</button>
|
||||
</withPropsOnChange(Typography)>
|
||||
</Localized>
|
||||
</withPropsOnChange(Flex)>
|
||||
`;
|
||||
+7
-3
@@ -1,7 +1,10 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<withPropsOnChange(Flex)>
|
||||
<withPropsOnChange(Flex)
|
||||
alignItems="center"
|
||||
itemGutter={true}
|
||||
>
|
||||
<MatchMediaWithContext
|
||||
gteWidth="sm"
|
||||
>
|
||||
@@ -10,14 +13,14 @@ exports[`renders correctly 1`] = `
|
||||
>
|
||||
<withPropsOnChange(Typography)
|
||||
className="UserBoxUnauthenticated-joinText"
|
||||
component="span"
|
||||
container="span"
|
||||
variant="bodyCopyBold"
|
||||
>
|
||||
Join the conversation
|
||||
</withPropsOnChange(Typography)>
|
||||
</Localized>
|
||||
<withPropsOnChange(Typography)
|
||||
component="span"
|
||||
container="span"
|
||||
variant="bodyCopyBold"
|
||||
>
|
||||
|
|
||||
@@ -30,6 +33,7 @@ exports[`renders correctly 1`] = `
|
||||
color="primary"
|
||||
onClick={[Function]}
|
||||
size="small"
|
||||
variant="underlined"
|
||||
>
|
||||
Sign in
|
||||
</withPropsOnChange(Button)>
|
||||
|
||||
@@ -3,7 +3,8 @@ import { graphql, RelayPaginationProp } from "react-relay";
|
||||
|
||||
import { withPaginationContainer } from "talk-framework/lib/relay";
|
||||
import { PropTypesOf } from "talk-framework/types";
|
||||
import { StreamContainer_asset as Data } from "talk-stream/__generated__/StreamContainer_asset.graphql";
|
||||
import { StreamContainer_asset as AssetData } from "talk-stream/__generated__/StreamContainer_asset.graphql";
|
||||
import { StreamContainer_user as UserData } from "talk-stream/__generated__/StreamContainer_user.graphql";
|
||||
import {
|
||||
COMMENT_SORT,
|
||||
StreamContainerPaginationQueryVariables,
|
||||
@@ -12,7 +13,8 @@ import {
|
||||
import Stream from "../components/Stream";
|
||||
|
||||
interface InnerProps {
|
||||
asset: Data;
|
||||
asset: AssetData;
|
||||
user: UserData | null;
|
||||
relay: RelayPaginationProp;
|
||||
}
|
||||
|
||||
@@ -31,6 +33,7 @@ export class StreamContainer extends React.Component<InnerProps> {
|
||||
onLoadMore={this.loadMore}
|
||||
hasMore={this.props.relay.hasMore()}
|
||||
disableLoadMore={this.state.disableLoadMore}
|
||||
user={this.props.user}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -61,7 +64,7 @@ interface FragmentVariables {
|
||||
}
|
||||
|
||||
const enhanced = withPaginationContainer<
|
||||
{ asset: Data },
|
||||
{ asset: AssetData; user: UserData | null },
|
||||
InnerProps,
|
||||
FragmentVariables,
|
||||
StreamContainerPaginationQueryVariables
|
||||
@@ -88,6 +91,11 @@ const enhanced = withPaginationContainer<
|
||||
}
|
||||
}
|
||||
`,
|
||||
user: graphql`
|
||||
fragment StreamContainer_user on User {
|
||||
...UserBoxContainer_user
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
direction: "forward",
|
||||
|
||||
@@ -14,10 +14,13 @@ it("renders correctly", () => {
|
||||
view: "SIGN_IN",
|
||||
},
|
||||
},
|
||||
user: null,
|
||||
// tslint:disable-next-line:no-empty
|
||||
showAuthPopup: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
setAuthPopupState: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
signOut: async () => {},
|
||||
};
|
||||
const wrapper = shallow(<UserBoxContainer {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import * as React from "react";
|
||||
import { Component } from "react";
|
||||
|
||||
import { graphql, withLocalStateContainer } from "talk-framework/lib/relay";
|
||||
import {
|
||||
graphql,
|
||||
withFragmentContainer,
|
||||
withLocalStateContainer,
|
||||
} from "talk-framework/lib/relay";
|
||||
import { SignOutMutation, withSignOutMutation } from "talk-framework/mutations";
|
||||
import { UserBoxContainer_user as UserData } from "talk-stream/__generated__/UserBoxContainer_user.graphql";
|
||||
import { UserBoxContainerLocal as Local } from "talk-stream/__generated__/UserBoxContainerLocal.graphql";
|
||||
import UserBoxUnauthenticated from "talk-stream/components/UserBoxUnauthenticated";
|
||||
import {
|
||||
SetAuthPopupStateMutation,
|
||||
ShowAuthPopupMutation,
|
||||
@@ -11,12 +18,14 @@ import {
|
||||
} from "talk-stream/mutations";
|
||||
import { Popup } from "talk-ui/components";
|
||||
|
||||
import UserBoxUnauthenticated from "../components/UserBoxUnauthenticated";
|
||||
import UserBoxAuthenticated from "../components/UserBoxAuthenticated";
|
||||
|
||||
interface InnerProps {
|
||||
local: Local;
|
||||
user: UserData | null;
|
||||
showAuthPopup: ShowAuthPopupMutation;
|
||||
setAuthPopupState: SetAuthPopupStateMutation;
|
||||
signOut: SignOutMutation;
|
||||
}
|
||||
|
||||
export class UserBoxContainer extends Component<InnerProps> {
|
||||
@@ -31,13 +40,26 @@ export class UserBoxContainer extends Component<InnerProps> {
|
||||
local: {
|
||||
authPopup: { open, focus, view },
|
||||
},
|
||||
user,
|
||||
signOut,
|
||||
} = this.props;
|
||||
|
||||
if (user) {
|
||||
return (
|
||||
<UserBoxAuthenticated
|
||||
onSignOut={signOut}
|
||||
// TODO: why nullable?
|
||||
username={user.username!}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Popup
|
||||
href={`/auth.html?view=${view}`}
|
||||
title="Talk Auth"
|
||||
features="menubar=0,resizable=0,width=500,height=550,top=200,left=500"
|
||||
features="menubar=0,resizable=0,width=350,height=395,top=200,left=500"
|
||||
open={open}
|
||||
focus={focus}
|
||||
onFocus={this.handleFocus}
|
||||
@@ -53,19 +75,29 @@ export class UserBoxContainer extends Component<InnerProps> {
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withSetAuthPopupStateMutation(
|
||||
withShowAuthPopupMutation(
|
||||
withLocalStateContainer<Local>(
|
||||
graphql`
|
||||
fragment UserBoxContainerLocal on Local {
|
||||
authPopup {
|
||||
open
|
||||
focus
|
||||
view
|
||||
const enhanced = withSignOutMutation(
|
||||
withSetAuthPopupStateMutation(
|
||||
withShowAuthPopupMutation(
|
||||
withLocalStateContainer<Local>(
|
||||
graphql`
|
||||
fragment UserBoxContainerLocal on Local {
|
||||
authPopup {
|
||||
open
|
||||
focus
|
||||
view
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
)(UserBoxContainer)
|
||||
`
|
||||
)(
|
||||
withFragmentContainer<{ user: UserData | null }>({
|
||||
user: graphql`
|
||||
fragment UserBoxContainer_user on User {
|
||||
username
|
||||
}
|
||||
`,
|
||||
})(UserBoxContainer)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
exports[`renders correctly 1`] = `
|
||||
<React.Fragment>
|
||||
<Popup
|
||||
features="menubar=0,resizable=0,width=500,height=550,top=200,left=500"
|
||||
features="menubar=0,resizable=0,width=350,height=395,top=200,left=500"
|
||||
focus={false}
|
||||
href="/auth.html?view=SIGN_IN"
|
||||
onBlur={[Function]}
|
||||
|
||||
@@ -40,9 +40,7 @@ async function main() {
|
||||
});
|
||||
|
||||
const Index: StatelessComponent = () => (
|
||||
<TalkContextProvider
|
||||
value={{ ...context, mediaQueryValues: { width: 640 } }}
|
||||
>
|
||||
<TalkContextProvider value={context}>
|
||||
<AppContainer />
|
||||
</TalkContextProvider>
|
||||
);
|
||||
|
||||
@@ -13,6 +13,7 @@ exports[`init local state 1`] = `
|
||||
\\"__id\\": \\"client:root.local\\",
|
||||
\\"__typename\\": \\"Local\\",
|
||||
\\"authToken\\": \\"\\",
|
||||
\\"authRevision\\": 0,
|
||||
\\"network\\": {
|
||||
\\"__ref\\": \\"client:root.local.network\\"
|
||||
},
|
||||
|
||||
@@ -33,6 +33,9 @@ export default async function initLocalState(
|
||||
// Set auth token
|
||||
localRecord.setValue(localStorage.getItem("authToken") || "", "authToken");
|
||||
|
||||
// Set initial auth revision, this is increment whenenver auth state might have changed.
|
||||
localRecord.setValue(0, "authRevision");
|
||||
|
||||
// Parse query params
|
||||
const query = qs.parse(location.search);
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ type Local {
|
||||
commentID: String
|
||||
authPopup: AuthPopup!
|
||||
authToken: String
|
||||
# Used to invalidate the `me` endpoint.
|
||||
# This is incremented whenever the auth status
|
||||
# might have changed.
|
||||
authRevision: Int!
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from "talk-stream/__generated__/PermalinkViewQuery.graphql";
|
||||
import { PermalinkViewQueryLocal as Local } from "talk-stream/__generated__/PermalinkViewQueryLocal.graphql";
|
||||
|
||||
import { Spinner } from "talk-ui/components";
|
||||
import PermalinkViewContainer from "../containers/PermalinkViewContainer";
|
||||
|
||||
interface InnerProps {
|
||||
@@ -29,7 +30,7 @@ export const render = ({
|
||||
if (props) {
|
||||
return <PermalinkViewContainer comment={props.comment} />;
|
||||
}
|
||||
return <div>Loading</div>;
|
||||
return <Spinner />;
|
||||
};
|
||||
|
||||
const PermalinkViewQuery: StatelessComponent<InnerProps> = ({
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { ReadyState } from "react-relay";
|
||||
|
||||
import {
|
||||
graphql,
|
||||
QueryRenderer,
|
||||
@@ -12,7 +10,7 @@ import {
|
||||
StreamQueryVariables,
|
||||
} from "talk-stream/__generated__/StreamQuery.graphql";
|
||||
import { StreamQueryLocal as Local } from "talk-stream/__generated__/StreamQueryLocal.graphql";
|
||||
|
||||
import { Spinner } from "talk-ui/components";
|
||||
import StreamContainer from "../containers/StreamContainer";
|
||||
|
||||
interface InnerProps {
|
||||
@@ -23,25 +21,34 @@ export const render = ({ error, props }: ReadyState<StreamQueryResponse>) => {
|
||||
if (error) {
|
||||
return <div>{error.message}</div>;
|
||||
}
|
||||
|
||||
if (props) {
|
||||
return <StreamContainer asset={props.asset} />;
|
||||
return <StreamContainer asset={props.asset} user={props.me} />;
|
||||
}
|
||||
return <div>Loading</div>;
|
||||
|
||||
return <Spinner />;
|
||||
};
|
||||
|
||||
const StreamQuery: StatelessComponent<InnerProps> = ({
|
||||
local: { assetID },
|
||||
local: { assetID, authRevision },
|
||||
}) => (
|
||||
<QueryRenderer<StreamQueryVariables, StreamQueryResponse>
|
||||
query={graphql`
|
||||
query StreamQuery($assetID: ID!) {
|
||||
query StreamQuery($assetID: ID!, $authRevision: Int!) {
|
||||
asset(id: $assetID) {
|
||||
...StreamContainer_asset
|
||||
}
|
||||
# authRevision is increment every time auth state has changed.
|
||||
# This is basically a cache invalidation and causes relay
|
||||
# to automatically update this query.
|
||||
me(clientAuthRevision: $authRevision) {
|
||||
...StreamContainer_user
|
||||
}
|
||||
}
|
||||
`}
|
||||
variables={{
|
||||
assetID,
|
||||
authRevision,
|
||||
}}
|
||||
render={render}
|
||||
/>
|
||||
@@ -51,6 +58,7 @@ const enhanced = withLocalStateContainer<Local>(
|
||||
graphql`
|
||||
fragment StreamQueryLocal on Local {
|
||||
assetID
|
||||
authRevision
|
||||
}
|
||||
`
|
||||
)(StreamQuery);
|
||||
|
||||
@@ -6,11 +6,7 @@ exports[`renders error 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders loading 1`] = `
|
||||
<div>
|
||||
Loading
|
||||
</div>
|
||||
`;
|
||||
exports[`renders loading 1`] = `<withPropsOnChange(Spinner) />`;
|
||||
|
||||
exports[`renders permalink view container 1`] = `
|
||||
<withContext(withContext(createMutationContainer(Relay(PermalinkViewContainer))))
|
||||
|
||||
@@ -6,11 +6,7 @@ exports[`renders error 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders loading 1`] = `
|
||||
<div>
|
||||
Loading
|
||||
</div>
|
||||
`;
|
||||
exports[`renders loading 1`] = `<withPropsOnChange(Spinner) />`;
|
||||
|
||||
exports[`renders stream container 1`] = `
|
||||
<Relay(StreamContainer)
|
||||
|
||||
@@ -2,212 +2,170 @@
|
||||
|
||||
exports[`loads more comments 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Stream-root"
|
||||
className="HorizontalGutter-root HorizontalGutter-half"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
|
||||
>
|
||||
<textarea
|
||||
className="PostCommentFormFake-textarea"
|
||||
disabled={true}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-alignCenter"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantRegular"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
className="PostCommentForm-root"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div>
|
||||
<textarea
|
||||
className="PostCommentForm-textarea"
|
||||
name="body"
|
||||
onChange={[Function]}
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="PostCommentForm-postButtonContainer"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Post
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="Flex-root"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root"
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Isabelle
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:14:00.000Z"
|
||||
title="2018-07-06T18:14:00.000Z"
|
||||
>
|
||||
2018-07-06T18:14:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Hey!
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Isabelle
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:14:00.000Z"
|
||||
title="2018-07-06T18:14:00.000Z"
|
||||
>
|
||||
2018-07-06T18:14:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Hey!
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -217,188 +175,155 @@ exports[`loads more comments 1`] = `
|
||||
|
||||
exports[`renders comment stream 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Stream-root"
|
||||
className="HorizontalGutter-root HorizontalGutter-half"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
|
||||
>
|
||||
<textarea
|
||||
className="PostCommentFormFake-textarea"
|
||||
disabled={true}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-alignCenter"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantRegular"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
className="PostCommentForm-root"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div>
|
||||
<textarea
|
||||
className="PostCommentForm-textarea"
|
||||
name="body"
|
||||
onChange={[Function]}
|
||||
value=""
|
||||
/>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="PostCommentForm-postButtonContainer"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Post
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="Flex-root"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
aria-controls="talk-comments-stream-log"
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantOutlined Button-fullWidth"
|
||||
disabled={false}
|
||||
id="talk-comments-stream-loadMore"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Load More
|
||||
</button>
|
||||
</div>
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
aria-controls="talk-comments-stream-log"
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantOutlined Button-fullWidth"
|
||||
disabled={false}
|
||||
id="talk-comments-stream-loadMore"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Load More
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,70 +2,55 @@
|
||||
|
||||
exports[`renders permalink view 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="PermalinkView-root"
|
||||
>
|
||||
<div
|
||||
className="PermalinkView-root"
|
||||
<a
|
||||
className="BaseButton-root Button-root PermalinkView-button Button-sizeRegular Button-colorPrimary Button-variantOutlined Button-fullWidth"
|
||||
href="http://localhost/"
|
||||
id="talk-comments-permalinkView-showAllComments"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
target="_parent"
|
||||
type="button"
|
||||
>
|
||||
Show all Comments
|
||||
</a>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<a
|
||||
className="BaseButton-root Button-root PermalinkView-button Button-sizeRegular Button-colorPrimary Button-variantOutlined Button-fullWidth"
|
||||
href="http://localhost/"
|
||||
id="talk-comments-permalinkView-showAllComments"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
target="_parent"
|
||||
>
|
||||
Show all Comments
|
||||
</a>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -73,130 +58,104 @@ exports[`renders permalink view 1`] = `
|
||||
|
||||
exports[`show all comments 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Stream-root"
|
||||
className="HorizontalGutter-root HorizontalGutter-half"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
|
||||
>
|
||||
<textarea
|
||||
className="PostCommentFormFake-textarea"
|
||||
disabled={true}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-alignCenter"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantRegular"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
className="PostCommentForm-root"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div>
|
||||
<textarea
|
||||
className="PostCommentForm-textarea"
|
||||
name="body"
|
||||
onChange={[Function]}
|
||||
value=""
|
||||
/>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="PostCommentForm-postButtonContainer"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Post
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="Flex-root"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+22
-25
@@ -2,35 +2,32 @@
|
||||
|
||||
exports[`renders permalink view with unknown asset 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="PermalinkView-root"
|
||||
>
|
||||
<div
|
||||
className="PermalinkView-root"
|
||||
<a
|
||||
className="BaseButton-root Button-root PermalinkView-button Button-sizeRegular Button-colorPrimary Button-variantOutlined Button-fullWidth"
|
||||
href="http://localhost/"
|
||||
id="talk-comments-permalinkView-showAllComments"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
target="_parent"
|
||||
type="button"
|
||||
>
|
||||
<a
|
||||
className="BaseButton-root Button-root PermalinkView-button Button-sizeRegular Button-colorPrimary Button-variantOutlined Button-fullWidth"
|
||||
href="http://localhost/"
|
||||
id="talk-comments-permalinkView-showAllComments"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
target="_parent"
|
||||
>
|
||||
Show all Comments
|
||||
</a>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Comment not found
|
||||
</p>
|
||||
</div>
|
||||
Show all Comments
|
||||
</a>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Comment not found
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
+105
-134
@@ -2,165 +2,136 @@
|
||||
|
||||
exports[`renders permalink view with unknown comment 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="PermalinkView-root"
|
||||
>
|
||||
<div
|
||||
className="PermalinkView-root"
|
||||
<a
|
||||
className="BaseButton-root Button-root PermalinkView-button Button-sizeRegular Button-colorPrimary Button-variantOutlined Button-fullWidth"
|
||||
href="http://localhost/"
|
||||
id="talk-comments-permalinkView-showAllComments"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
target="_parent"
|
||||
type="button"
|
||||
>
|
||||
<a
|
||||
className="BaseButton-root Button-root PermalinkView-button Button-sizeRegular Button-colorPrimary Button-variantOutlined Button-fullWidth"
|
||||
href="http://localhost/"
|
||||
id="talk-comments-permalinkView-showAllComments"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
target="_parent"
|
||||
>
|
||||
Show all Comments
|
||||
</a>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Comment not found
|
||||
</p>
|
||||
</div>
|
||||
Show all Comments
|
||||
</a>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Comment not found
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`show all comments 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Stream-root"
|
||||
className="HorizontalGutter-root HorizontalGutter-half"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
|
||||
>
|
||||
<textarea
|
||||
className="PostCommentFormFake-textarea"
|
||||
disabled={true}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-alignCenter"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantRegular"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
className="PostCommentForm-root"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div>
|
||||
<textarea
|
||||
className="PostCommentForm-textarea"
|
||||
name="body"
|
||||
onChange={[Function]}
|
||||
value=""
|
||||
/>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="PostCommentForm-postButtonContainer"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Post
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="Flex-root"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,249 +2,203 @@
|
||||
|
||||
exports[`renders comment stream 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Stream-root"
|
||||
className="HorizontalGutter-root HorizontalGutter-half"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
|
||||
>
|
||||
<textarea
|
||||
className="PostCommentFormFake-textarea"
|
||||
disabled={true}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-alignCenter"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantRegular"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
className="PostCommentForm-root"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div>
|
||||
<textarea
|
||||
className="PostCommentForm-textarea"
|
||||
name="body"
|
||||
onChange={[Function]}
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="PostCommentForm-postButtonContainer"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Post
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="Flex-root"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
I like yoghurt
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="Indent-root Indent-level0"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-replyList-log--comment-with-replies"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
I like yoghurt
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="Indent-root Indent-level0"
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
id="talk-comments-replyList-log--comment-with-replies"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,171 +2,137 @@
|
||||
|
||||
exports[`renders comment stream 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Stream-root"
|
||||
className="HorizontalGutter-root HorizontalGutter-half"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
|
||||
>
|
||||
<textarea
|
||||
className="PostCommentFormFake-textarea"
|
||||
disabled={true}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-alignCenter"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantRegular"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
className="PostCommentForm-root"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div>
|
||||
<textarea
|
||||
className="PostCommentForm-textarea"
|
||||
name="body"
|
||||
onChange={[Function]}
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="PostCommentForm-postButtonContainer"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Post
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="Flex-root"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="Flex-root"
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,191 +2,158 @@
|
||||
|
||||
exports[`renders comment stream 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Stream-root"
|
||||
className="HorizontalGutter-root HorizontalGutter-half"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
|
||||
>
|
||||
<textarea
|
||||
className="PostCommentFormFake-textarea"
|
||||
disabled={true}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-alignCenter"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantRegular"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
className="PostCommentForm-root"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div>
|
||||
<textarea
|
||||
className="PostCommentForm-textarea"
|
||||
name="body"
|
||||
onChange={[Function]}
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="PostCommentForm-postButtonContainer"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Post
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="Flex-root"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
className="Indent-root Indent-level0"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-replyList-log--comment-0"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="Indent-root Indent-level0"
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
id="talk-comments-replyList-log--comment-0"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
aria-controls="talk-comments-replyList-log--comment-0"
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantOutlined Button-fullWidth"
|
||||
disabled={false}
|
||||
id="talk-comments-replyList-showAll--comment-0"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Show All Replies
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
aria-controls="talk-comments-replyList-log--comment-0"
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorRegular Button-variantOutlined Button-fullWidth"
|
||||
disabled={false}
|
||||
id="talk-comments-replyList-showAll--comment-0"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Show All Replies
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -197,208 +164,170 @@ exports[`renders comment stream 1`] = `
|
||||
|
||||
exports[`show all replies 1`] = `
|
||||
<div
|
||||
className="Flex-root App-root"
|
||||
className="Flex-root App-root Flex-flex Flex-justifyCenter"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-justifyCenter Flex-alignCenter"
|
||||
className="HorizontalGutter-root Stream-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Flex-root Stream-root"
|
||||
className="HorizontalGutter-root HorizontalGutter-half"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root Flex-flex Flex-itemGutter Flex-alignCenter"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantUnderlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="HorizontalGutter-root PostCommentFormFake-root HorizontalGutter-full"
|
||||
>
|
||||
<textarea
|
||||
className="PostCommentFormFake-textarea"
|
||||
disabled={true}
|
||||
placeholder="Post a comment"
|
||||
/>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled Button-fullWidth Button-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="submit"
|
||||
>
|
||||
Sign in and join the conversation
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-wrap Flex-alignCenter"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantRegular"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantOutlined"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<form
|
||||
autoComplete="off"
|
||||
className="PostCommentForm-root"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div>
|
||||
<textarea
|
||||
className="PostCommentForm-textarea"
|
||||
name="body"
|
||||
onChange={[Function]}
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="PostCommentForm-postButtonContainer"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
>
|
||||
Post
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="Flex-root"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
className="Indent-root Indent-level0"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="HorizontalGutter-root HorizontalGutter-full"
|
||||
id="talk-comments-replyList-log--comment-0"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Markus
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:24:00.000Z"
|
||||
title="2018-07-06T18:24:00.000Z"
|
||||
>
|
||||
2018-07-06T18:24:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Joining Too
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="Indent-root Indent-level0"
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
<div
|
||||
className="Flex-root"
|
||||
id="talk-comments-replyList-log--comment-0"
|
||||
role="log"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-itemGutter Flex-wrap Flex-alignFlexStart Flex-directionColumn"
|
||||
>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Lukas
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:20:00.000Z"
|
||||
title="2018-07-06T18:20:00.000Z"
|
||||
>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root"
|
||||
>
|
||||
<div
|
||||
className="Flex-flex Flex-halfItemGutter Flex-wrap Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Isabelle
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:14:00.000Z"
|
||||
title="2018-07-06T18:14:00.000Z"
|
||||
>
|
||||
2018-07-06T18:14:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Hey!
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
2018-07-06T18:20:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
What's up?
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="Comment-root"
|
||||
role="article"
|
||||
>
|
||||
<div
|
||||
className="Flex-root TopBar-root Flex-flex Flex-halfItemGutter Flex-alignBaseline Flex-directionColumn"
|
||||
>
|
||||
<span
|
||||
className="Typography-root Typography-heading3 Typography-colorTextPrimary Username-root"
|
||||
>
|
||||
Isabelle
|
||||
</span>
|
||||
<time
|
||||
className="Timestamp-root RelativeTime-root"
|
||||
dateTime="2018-07-06T18:14:00.000Z"
|
||||
title="2018-07-06T18:14:00.000Z"
|
||||
>
|
||||
2018-07-06T18:14:00.000Z
|
||||
</time>
|
||||
</div>
|
||||
<p
|
||||
className="Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
Hey!
|
||||
</p>
|
||||
<div
|
||||
className="Comment-footer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,9 @@ import sinon from "sinon";
|
||||
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
import AppContainer from "talk-stream/containers/AppContainer";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
@@ -65,13 +68,18 @@ const environment = createEnvironment({
|
||||
logNetwork: false,
|
||||
resolvers,
|
||||
initLocalState: (localRecord, source) => {
|
||||
localRecord.setValue(0, "authRevision");
|
||||
localRecord.setValue(assetStub.id, "assetID");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeMessages: [],
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
|
||||
@@ -5,6 +5,9 @@ import sinon from "sinon";
|
||||
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
import AppContainer from "talk-stream/containers/AppContainer";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
@@ -49,6 +52,7 @@ const environment = createEnvironment({
|
||||
logNetwork: false,
|
||||
resolvers,
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue(0, "authRevision");
|
||||
localRecord.setValue(assetStub.id, "assetID");
|
||||
localRecord.setValue(commentStub.id, "commentID");
|
||||
},
|
||||
@@ -56,7 +60,11 @@ const environment = createEnvironment({
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeMessages: [],
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
|
||||
@@ -4,6 +4,9 @@ import { RecordProxy } from "relay-runtime";
|
||||
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
import AppContainer from "talk-stream/containers/AppContainer";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
@@ -20,6 +23,7 @@ const environment = createEnvironment({
|
||||
logNetwork: false,
|
||||
resolvers,
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue(0, "authRevision");
|
||||
localRecord.setValue("unknown-asset-id", "assetID");
|
||||
localRecord.setValue("unknown-comment-id", "commentID");
|
||||
},
|
||||
@@ -27,7 +31,11 @@ const environment = createEnvironment({
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeMessages: [],
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
|
||||
@@ -5,6 +5,9 @@ import sinon from "sinon";
|
||||
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
import AppContainer from "talk-stream/containers/AppContainer";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
@@ -47,12 +50,17 @@ const environment = createEnvironment({
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue(assetStub.id, "assetID");
|
||||
localRecord.setValue("unknown-comment-id", "commentID");
|
||||
localRecord.setValue(0, "authRevision");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeMessages: [],
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
|
||||
@@ -5,6 +5,9 @@ import sinon from "sinon";
|
||||
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
import AppContainer from "talk-stream/containers/AppContainer";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
@@ -26,12 +29,17 @@ const environment = createEnvironment({
|
||||
resolvers,
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue(assetWithReplies.id, "assetID");
|
||||
localRecord.setValue(0, "authRevision");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeMessages: [],
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
|
||||
@@ -5,6 +5,9 @@ import sinon from "sinon";
|
||||
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
import AppContainer from "talk-stream/containers/AppContainer";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
@@ -26,12 +29,17 @@ const environment = createEnvironment({
|
||||
resolvers,
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue(assets[0].id, "assetID");
|
||||
localRecord.setValue(0, "authRevision");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeMessages: [],
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
|
||||
@@ -5,6 +5,9 @@ import sinon from "sinon";
|
||||
|
||||
import { timeout } from "talk-common/utils";
|
||||
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
|
||||
import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createInMemoryStorage } from "talk-framework/lib/storage";
|
||||
import AppContainer from "talk-stream/containers/AppContainer";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
@@ -83,12 +86,17 @@ const environment = createEnvironment({
|
||||
resolvers,
|
||||
initLocalState: (localRecord: RecordProxy) => {
|
||||
localRecord.setValue(assetStub.id, "assetID");
|
||||
localRecord.setValue(0, "authRevision");
|
||||
},
|
||||
});
|
||||
|
||||
const context: TalkContext = {
|
||||
relayEnvironment: environment,
|
||||
localeMessages: [],
|
||||
localeBundles: [],
|
||||
localStorage: createInMemoryStorage(),
|
||||
sessionStorage: createInMemoryStorage(),
|
||||
rest: new RestClient("http://localhost/api"),
|
||||
postMessage: new PostMessageService(),
|
||||
};
|
||||
|
||||
const testRenderer = TestRenderer.create(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.root {
|
||||
composes: buttonReset from "talk-ui/shared/buttonReset.css";
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.keyboardFocus {
|
||||
|
||||
@@ -32,6 +32,8 @@ interface InnerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
|
||||
/** Internal: Forwarded Ref */
|
||||
forwardRef?: Ref<HTMLButtonElement>;
|
||||
|
||||
type?: "submit" | "reset" | "button";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,15 +47,15 @@ const BaseButton: StatelessComponent<InnerProps> = ({
|
||||
keyboardFocus,
|
||||
mouseHover,
|
||||
forwardRef,
|
||||
type: typeProp,
|
||||
type,
|
||||
...rest
|
||||
}) => {
|
||||
let Element = "button";
|
||||
|
||||
if (anchor) {
|
||||
Element = "a";
|
||||
}
|
||||
|
||||
let type = typeProp;
|
||||
if (anchor && type) {
|
||||
// tslint:disable:next-line: no-console
|
||||
console.warn(
|
||||
@@ -69,7 +71,9 @@ const BaseButton: StatelessComponent<InnerProps> = ({
|
||||
[classes.mouseHover]: mouseHover,
|
||||
});
|
||||
|
||||
return <Element {...rest} className={rootClassName} ref={forwardRef} />;
|
||||
return (
|
||||
<Element {...rest} className={rootClassName} ref={forwardRef} type={type} />
|
||||
);
|
||||
};
|
||||
|
||||
const enhanced = withForwardRef(
|
||||
|
||||
@@ -9,6 +9,7 @@ exports[`renders as anchor 1`] = `
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Push Me
|
||||
</a>
|
||||
@@ -23,6 +24,7 @@ exports[`renders correctly 1`] = `
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Push Me
|
||||
</button>
|
||||
|
||||
@@ -282,3 +282,63 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.variantUnderlined {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid currentColor;
|
||||
padding: 0;
|
||||
|
||||
&.colorRegular {
|
||||
color: var(--palette-grey-main);
|
||||
}
|
||||
&.colorPrimary {
|
||||
color: var(--palette-primary-main);
|
||||
}
|
||||
&.colorError {
|
||||
color: var(--palette-error-main);
|
||||
}
|
||||
&.colorSuccess {
|
||||
color: var(--palette-success-main);
|
||||
}
|
||||
|
||||
&:not(.disabled) {
|
||||
&.colorRegular {
|
||||
&.mouseHover {
|
||||
color: var(--palette-grey-light);
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
color: var(--palette-grey-lighter);
|
||||
}
|
||||
}
|
||||
&.colorPrimary {
|
||||
&.mouseHover {
|
||||
color: var(--palette-primary-light);
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
color: var(--palette-primary-lighter);
|
||||
}
|
||||
}
|
||||
&.colorError {
|
||||
&.mouseHover {
|
||||
color: var(--palette-error-light);
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
color: var(--palette-error-lighter);
|
||||
}
|
||||
}
|
||||
&.colorSuccess {
|
||||
&.mouseHover {
|
||||
color: var(--palette-success-light);
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
color: var(--palette-success-lighter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import Flex from '../Flex'
|
||||
|
||||
## Regular Button
|
||||
<Playground>
|
||||
<Flex itemGutter>
|
||||
<Flex itemGutter wrap>
|
||||
<Button>Push Me</Button>
|
||||
<Button size="small">Push Me</Button>
|
||||
<Button size="large">Push Me</Button>
|
||||
@@ -29,7 +29,7 @@ import Flex from '../Flex'
|
||||
|
||||
## Filled Button
|
||||
<Playground>
|
||||
<Flex itemGutter>
|
||||
<Flex itemGutter wrap>
|
||||
<Button variant="filled">Push Me</Button>
|
||||
<Button variant="filled" size="small">Push Me</Button>
|
||||
<Button variant="filled" size="large">Push Me</Button>
|
||||
@@ -45,7 +45,7 @@ import Flex from '../Flex'
|
||||
|
||||
## Outlined Button
|
||||
<Playground>
|
||||
<Flex itemGutter>
|
||||
<Flex itemGutter wrap>
|
||||
<Button variant="outlined">Push Me</Button>
|
||||
<Button variant="outlined" size="small">Push Me</Button>
|
||||
<Button variant="outlined" size="large">Push Me</Button>
|
||||
@@ -61,7 +61,7 @@ import Flex from '../Flex'
|
||||
|
||||
## Ghost Button
|
||||
<Playground>
|
||||
<Flex itemGutter>
|
||||
<Flex itemGutter wrap>
|
||||
<Button variant="ghost">Push Me</Button>
|
||||
<Button variant="ghost" size="small">Push Me</Button>
|
||||
<Button variant="ghost" size="large">Push Me</Button>
|
||||
|
||||
@@ -28,7 +28,7 @@ interface InnerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
color?: "regular" | "primary" | "error" | "success";
|
||||
|
||||
/** Variant of the button */
|
||||
variant?: "regular" | "filled" | "outlined" | "ghost";
|
||||
variant?: "regular" | "filled" | "outlined" | "ghost" | "underlined";
|
||||
|
||||
/** If set renders a full width button */
|
||||
fullWidth?: boolean;
|
||||
@@ -36,6 +36,8 @@ interface InnerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
/** If set renders active state e.g. to implement toggle buttons */
|
||||
active?: boolean;
|
||||
|
||||
type?: "submit" | "reset" | "button";
|
||||
|
||||
/** Internal: Forwarded Ref */
|
||||
forwardRef?: Ref<HTMLButtonElement>;
|
||||
}
|
||||
@@ -57,6 +59,7 @@ export class Button extends React.Component<InnerProps> {
|
||||
disabled,
|
||||
forwardRef,
|
||||
variant,
|
||||
type,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
@@ -72,6 +75,7 @@ export class Button extends React.Component<InnerProps> {
|
||||
[classes.variantFilled]: variant === "filled",
|
||||
[classes.variantOutlined]: variant === "outlined",
|
||||
[classes.variantGhost]: variant === "ghost",
|
||||
[classes.variantUnderlined]: variant === "underlined",
|
||||
[classes.fullWidth]: fullWidth,
|
||||
[classes.active]: active,
|
||||
[classes.disabled]: disabled,
|
||||
@@ -83,6 +87,7 @@ export class Button extends React.Component<InnerProps> {
|
||||
classes={pick(classes, "keyboardFocus", "mouseHover")}
|
||||
disabled={disabled}
|
||||
forwardRef={forwardRef}
|
||||
type={type}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -5,19 +5,19 @@ menu: UI Kit
|
||||
|
||||
import { Playground, PropsTable } from 'docz'
|
||||
import CallOut from './CallOut'
|
||||
import Flex from '../Flex'
|
||||
import HorizontalGutter from '../HorizontalGutter'
|
||||
|
||||
# CallOut
|
||||
|
||||
## Basic Use
|
||||
<Playground>
|
||||
<Flex itemGutter direction="column">
|
||||
<HorizontalGutter>
|
||||
<CallOut>This is a component for a callout. Any text that you are wanting to draw attention to such as community guidelines, announcements, etc. can be placed in something like a callout box. The color of the callout box can be customized according your own needs.</CallOut>
|
||||
<CallOut color="primary">This is a component for a callout. Any text that you are wanting to draw attention to such as community guidelines, announcements, etc. can be placed in something like a callout box. The color of the callout box can be customized according your own needs.</CallOut>
|
||||
<CallOut color="error">This is a component for a callout. Any text that you are wanting to draw attention to such as community guidelines, announcements, etc. can be placed in something like a callout box. The color of the callout box can be customized according your own needs.</CallOut>
|
||||
<CallOut color="error">The email address or password you entered is incorrect. Try again</CallOut>
|
||||
<CallOut color="error" fullWidth>The email address or password you entered is incorrect. Try again</CallOut>
|
||||
</Flex>
|
||||
</HorizontalGutter>
|
||||
</Playground>
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user