Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
2cc6f36b68
23 changed files with 1214 additions and 466 deletions
|
@ -157,8 +157,6 @@ For a good example, see https://riot.im/develop/config.json
|
||||||
1. `whitelistedHSUrls`: a list of HS URLs to not redact from the analytics
|
1. `whitelistedHSUrls`: a list of HS URLs to not redact from the analytics
|
||||||
1. `whitelistedISUrls`: a list of IS URLs to not redact from the analytics
|
1. `whitelistedISUrls`: a list of IS URLs to not redact from the analytics
|
||||||
1. `siteId`: The Piwik Site ID to use when sending analytics to the Piwik server configured above
|
1. `siteId`: The Piwik Site ID to use when sending analytics to the Piwik server configured above
|
||||||
1. `teamServerConfig`, `teamTokenMap`, `referralBaseUrl`: an obsolete precursor to communities
|
|
||||||
with referral tracking; please ignore it.
|
|
||||||
1. `welcomeUserId`: the user ID of a bot to invite whenever users register that can give them a tour
|
1. `welcomeUserId`: the user ID of a bot to invite whenever users register that can give them a tour
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
const {clipboard, nativeImage, Menu, MenuItem, shell} = require('electron');
|
const {clipboard, nativeImage, Menu, MenuItem, shell} = require('electron');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
|
|
||||||
|
const MAILTO_PREFIX = "mailto:";
|
||||||
|
|
||||||
const PERMITTED_URL_SCHEMES = [
|
const PERMITTED_URL_SCHEMES = [
|
||||||
'http:',
|
'http:',
|
||||||
'https:',
|
'https:',
|
||||||
'mailto:',
|
MAILTO_PREFIX,
|
||||||
];
|
];
|
||||||
|
|
||||||
function safeOpenURL(target) {
|
function safeOpenURL(target) {
|
||||||
|
@ -47,7 +49,7 @@ function onLinkContextMenu(ev, params) {
|
||||||
|
|
||||||
if (params.mediaType && params.mediaType === 'image' && !url.startsWith('file://')) {
|
if (params.mediaType && params.mediaType === 'image' && !url.startsWith('file://')) {
|
||||||
popupMenu.append(new MenuItem({
|
popupMenu.append(new MenuItem({
|
||||||
label: 'Copy Image',
|
label: 'Copy image',
|
||||||
click() {
|
click() {
|
||||||
if (url.startsWith('data:')) {
|
if (url.startsWith('data:')) {
|
||||||
clipboard.writeImage(nativeImage.createFromDataURL(url));
|
clipboard.writeImage(nativeImage.createFromDataURL(url));
|
||||||
|
@ -58,14 +60,24 @@ function onLinkContextMenu(ev, params) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// No point offerring to copy a blob: URL either
|
// No point offering to copy a blob: URL either
|
||||||
if (!url.startsWith('blob:')) {
|
if (!url.startsWith('blob:')) {
|
||||||
popupMenu.append(new MenuItem({
|
// Special-case e-mail URLs to strip the `mailto:` like modern browsers do
|
||||||
label: 'Copy Link Address',
|
if (url.startsWith(MAILTO_PREFIX)) {
|
||||||
click() {
|
popupMenu.append(new MenuItem({
|
||||||
clipboard.writeText(url);
|
label: 'Copy email address',
|
||||||
},
|
click() {
|
||||||
}));
|
clipboard.writeText(url.substr(MAILTO_PREFIX.length));
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
popupMenu.append(new MenuItem({
|
||||||
|
label: 'Copy link address',
|
||||||
|
click() {
|
||||||
|
clipboard.writeText(url);
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// popup() requires an options object even for no options
|
// popup() requires an options object even for no options
|
||||||
popupMenu.popup({});
|
popupMenu.popup({});
|
||||||
|
@ -117,6 +129,18 @@ function onEditableContextMenu(ev, params) {
|
||||||
|
|
||||||
module.exports = (webContents) => {
|
module.exports = (webContents) => {
|
||||||
webContents.on('new-window', onWindowOrNavigate);
|
webContents.on('new-window', onWindowOrNavigate);
|
||||||
|
// XXX: The below now does absolutely nothing because of
|
||||||
|
// https://github.com/electron/electron/issues/8841
|
||||||
|
// Whilst this isn't a security issue since without
|
||||||
|
// node integration and with the sandbox, it should be
|
||||||
|
// no worse than opening the site in Chrome, it obviously
|
||||||
|
// means the user has to restart Riot to make it usable
|
||||||
|
// again (often unintuitive because it minimises to the
|
||||||
|
// system tray). We therefore need to be vigilant about
|
||||||
|
// putting target="_blank" on links in Riot (although
|
||||||
|
// we should generally be doing this anyway since links
|
||||||
|
// navigating you away from Riot in the browser is
|
||||||
|
// also annoying).
|
||||||
webContents.on('will-navigate', onWindowOrNavigate);
|
webContents.on('will-navigate', onWindowOrNavigate);
|
||||||
|
|
||||||
webContents.on('context-menu', function(ev, params) {
|
webContents.on('context-menu', function(ev, params) {
|
||||||
|
|
1212
package-lock.json
generated
1212
package-lock.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
@ -33,8 +33,8 @@
|
||||||
"build:res": "node scripts/copy-res.js",
|
"build:res": "node scripts/copy-res.js",
|
||||||
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
|
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
|
||||||
"build:compile": "npm run reskindex && babel --source-maps -d lib src",
|
"build:compile": "npm run reskindex && babel --source-maps -d lib src",
|
||||||
"build:bundle": "cross-env NODE_ENV=production webpack-cli -p --progress --bail --mode production",
|
"build:bundle": "cross-env NODE_ENV=production webpack -p --progress --bail --mode production",
|
||||||
"build:bundle:dev": "webpack-cli --progress --bail --mode development",
|
"build:bundle:dev": "webpack --progress --bail --mode development",
|
||||||
"build:electron": "npm run clean && npm run build && npm run install:electron && build -wml --ia32 --x64",
|
"build:electron": "npm run clean && npm run build && npm run install:electron && build -wml --ia32 --x64",
|
||||||
"build:react-sdk": "node scripts/npm-sub.js matrix-react-sdk run build",
|
"build:react-sdk": "node scripts/npm-sub.js matrix-react-sdk run build",
|
||||||
"build:js-sdk": "node scripts/npm-sub.js matrix-js-sdk run start:init",
|
"build:js-sdk": "node scripts/npm-sub.js matrix-js-sdk run start:init",
|
||||||
|
@ -100,7 +100,8 @@
|
||||||
"concurrently": "^4.0.1",
|
"concurrently": "^4.0.1",
|
||||||
"cpx": "^1.3.2",
|
"cpx": "^1.3.2",
|
||||||
"cross-env": "^4.0.0",
|
"cross-env": "^4.0.0",
|
||||||
"electron-builder": "^20.29.0",
|
"css-loader": "^2.1.0",
|
||||||
|
"electron-builder": "^20.38.5",
|
||||||
"electron-builder-squirrel-windows": "^11.6.1",
|
"electron-builder-squirrel-windows": "^11.6.1",
|
||||||
"electron-devtools-installer": "^2.2.4",
|
"electron-devtools-installer": "^2.2.4",
|
||||||
"emojione": "^2.2.7",
|
"emojione": "^2.2.7",
|
||||||
|
@ -110,6 +111,7 @@
|
||||||
"eslint-plugin-flowtype": "^2.50.3",
|
"eslint-plugin-flowtype": "^2.50.3",
|
||||||
"eslint-plugin-react": "^7.11.1",
|
"eslint-plugin-react": "^7.11.1",
|
||||||
"expect": "^1.16.0",
|
"expect": "^1.16.0",
|
||||||
|
"file-loader": "^3.0.1",
|
||||||
"fs-extra": "^0.30.0",
|
"fs-extra": "^0.30.0",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"json-loader": "^0.5.3",
|
"json-loader": "^0.5.3",
|
||||||
|
@ -136,7 +138,6 @@
|
||||||
"postcss-scss": "^1.0.6",
|
"postcss-scss": "^1.0.6",
|
||||||
"postcss-simple-vars": "^4.1.0",
|
"postcss-simple-vars": "^4.1.0",
|
||||||
"postcss-strip-inline-comments": "^0.1.5",
|
"postcss-strip-inline-comments": "^0.1.5",
|
||||||
"raw-loader": "^0.5.1",
|
|
||||||
"react-addons-perf": "^15.4.0",
|
"react-addons-perf": "^15.4.0",
|
||||||
"react-addons-test-utils": "^15.6.0",
|
"react-addons-test-utils": "^15.6.0",
|
||||||
"rimraf": "^2.4.3",
|
"rimraf": "^2.4.3",
|
||||||
|
@ -146,7 +147,7 @@
|
||||||
"webpack-dev-server": "^3.1.10"
|
"webpack-dev-server": "^3.1.10"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"olm": "https://matrix.org/packages/npm/olm/olm-3.0.0.tgz"
|
"olm": "https://matrix.org/packages/npm/olm/olm-3.1.0-pre1.tgz"
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"appId": "im.riot.app",
|
"appId": "im.riot.app",
|
||||||
|
|
|
@ -130,7 +130,7 @@
|
||||||
<div>
|
<div>
|
||||||
<h3>_t("Search the room directory")</h3>
|
<h3>_t("Search the room directory")</h3>
|
||||||
<a class="mx_HomePage_room" href="#/directory">
|
<a class="mx_HomePage_room" href="#/directory">
|
||||||
<img class="mx_HomePage_icon" src="img/icons-directory.svg">
|
<img class="mx_HomePage_icon" src="home/images/icons-directory.svg">
|
||||||
</a>
|
</a>
|
||||||
<span class="mx_HomePage_comment">
|
<span class="mx_HomePage_comment">
|
||||||
_t("Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!")
|
_t("Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!")
|
||||||
|
|
24
res/home/images/icons-directory.svg
Normal file
24
res/home/images/icons-directory.svg
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="25px" height="25px" viewBox="0 0 25 25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>icons_directory</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="Left-panel" transform="translate(-83.000000, -726.000000)">
|
||||||
|
<g id="icons_directory">
|
||||||
|
<g transform="translate(83.000000, 726.000000)">
|
||||||
|
<path d="M12.5,25 C19.4035594,25 25,19.4035594 25,12.5 C25,5.59644063 19.4035594,0 12.5,0 C5.59644063,0 0,5.59644063 0,12.5 C0,19.4035594 5.59644063,25 12.5,25 Z" id="Oval-1-Copy-7" fill="#76CFA6"></path>
|
||||||
|
<g id="Lines" transform="translate(6.000000, 7.000000)" stroke="#FFFFFF" stroke-linecap="round">
|
||||||
|
<path d="M4,5.5 L9,5.5" id="Line"></path>
|
||||||
|
<path d="M4,1.5 L13,1.5" id="Line-Copy-4"></path>
|
||||||
|
<path d="M0,1.5 L2,1.5" id="Line" opacity="0.6"></path>
|
||||||
|
<path d="M0,5.5 L2,5.5" id="Line" opacity="0.6"></path>
|
||||||
|
<path d="M4,9.5 L11,9.5" id="Line-Copy-6"></path>
|
||||||
|
<path d="M0,9.5 L2,9.5" id="Line-Copy-3" opacity="0.6"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -88,7 +88,7 @@ limitations under the License.
|
||||||
|
|
||||||
// overrides of .mx_Login
|
// overrides of .mx_Login
|
||||||
|
|
||||||
.mx_Login_box {
|
.mx_AuthPage_modal {
|
||||||
width: 330px;
|
width: 330px;
|
||||||
min-height: initial;
|
min-height: initial;
|
||||||
padding-top: 40px;
|
padding-top: 40px;
|
||||||
|
@ -100,13 +100,13 @@ limitations under the License.
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 25px;
|
line-height: 25px;
|
||||||
background-color: $form-bg-color;
|
background-color: $form-bg-color;
|
||||||
background-image: url(../../themes/status/img/dot.svg);
|
background-image: url("$(status)/img/dot.svg");
|
||||||
box-shadow: 0px 5px 16px 0px rgba(25,12,46,0.16);
|
box-shadow: 0px 5px 16px 0px rgba(25,12,46,0.16);
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Login_logo {
|
.mx_AuthHeader_logo {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
width: 74px;
|
width: 74px;
|
||||||
height: 74px;
|
height: 74px;
|
||||||
|
@ -118,13 +118,13 @@ limitations under the License.
|
||||||
margin-left: -36px;
|
margin-left: -36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Login_logo img {
|
.mx_AuthHeader_logo img {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
padding: 19px;
|
padding: 19px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Login_box h2 {
|
.mx_AuthPage_modal h2 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: $form-fg-color;
|
color: $form-fg-color;
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
|
|
15
res/themes/status/css/_fonts.scss
Normal file
15
res/themes/status/css/_fonts.scss
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
@font-face {
|
||||||
|
font-family:PostGrotesk-Medium;
|
||||||
|
src:url('https://status.im/fonts/PostGrotesk-Medium.eot');
|
||||||
|
src:url('https://status.im/fonts/PostGrotesk-Medium.eot?#iefix') format("embedded-opentype"),url('https://status.im/fonts/PostGrotesk-Medium.woff') format("woff"),url('https://status.im/fonts/PostGrotesk-Medium.svg#PostGrotesk-Medium') format("svg");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family:PostGrotesk-Book;
|
||||||
|
src:url('https://status.im/fonts/PostGrotesk-Book.eot');
|
||||||
|
src:url('https://status.im/fonts/PostGrotesk-Book.eot?#iefix') format("embedded-opentype"),url('https://status.im/fonts/PostGrotesk-Book.woff') format("woff"),url('https://status.im/fonts/PostGrotesk-Book.svg#PostGrotesk-Book') format("svg");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
5
res/themes/status/css/_paths.scss
Normal file
5
res/themes/status/css/_paths.scss
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// Path from root SCSS file (such as `status.scss`) to `res` dir in `matrix-react-sdk`
|
||||||
|
$res: ../../../../node_modules/matrix-react-sdk/res;
|
||||||
|
|
||||||
|
// Path from root SCSS file (such as `status.scss`) to `status` dir in `riot-web`
|
||||||
|
$status: ..;
|
|
@ -1,19 +1,3 @@
|
||||||
@font-face {
|
|
||||||
font-family:PostGrotesk-Medium;
|
|
||||||
src:url('https://status.im/fonts/PostGrotesk-Medium.eot');
|
|
||||||
src:url('https://status.im/fonts/PostGrotesk-Medium.eot?#iefix') format("embedded-opentype"),url('https://status.im/fonts/PostGrotesk-Medium.woff') format("woff"),url('https://status.im/fonts/PostGrotesk-Medium.svg#PostGrotesk-Medium') format("svg");
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family:PostGrotesk-Book;
|
|
||||||
src:url('https://status.im/fonts/PostGrotesk-Book.eot');
|
|
||||||
src:url('https://status.im/fonts/PostGrotesk-Book.eot?#iefix') format("embedded-opentype"),url('https://status.im/fonts/PostGrotesk-Book.woff') format("woff"),url('https://status.im/fonts/PostGrotesk-Book.svg#PostGrotesk-Book') format("svg");
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We deliberately prioritise Arial over Helvetica here due to diacritic problems (see _base.scss)
|
// We deliberately prioritise Arial over Helvetica here due to diacritic problems (see _base.scss)
|
||||||
// N.B. that the status.im website uses:
|
// N.B. that the status.im website uses:
|
||||||
// font-family:PostGrotesk-Book,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
|
// font-family:PostGrotesk-Book,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
|
||||||
|
@ -68,6 +52,7 @@ $focus-bg-color: #dddddd;
|
||||||
// button UI (white-on-green in light skin)
|
// button UI (white-on-green in light skin)
|
||||||
$accent-fg-color: #ffffff;
|
$accent-fg-color: #ffffff;
|
||||||
$accent-color: #6CC1F6;
|
$accent-color: #6CC1F6;
|
||||||
|
$accent-color-alt: $accent-color;
|
||||||
$accent-color-50pct: #6CC1F67F;
|
$accent-color-50pct: #6CC1F67F;
|
||||||
$accent-hover-color: #84cfff;
|
$accent-hover-color: #84cfff;
|
||||||
|
|
||||||
|
@ -118,7 +103,11 @@ $primary-hairline-color: #e5e5e5;
|
||||||
|
|
||||||
// used for the border of input text fields
|
// used for the border of input text fields
|
||||||
$input-border-color: #c9cfd4;
|
$input-border-color: #c9cfd4;
|
||||||
|
$input-darker-bg-color: #c1c9d6;
|
||||||
|
$input-darker-fg-color: #9fa9ba;
|
||||||
|
|
||||||
|
$button-bg-color: #7ac9a1;
|
||||||
|
$button-fg-color: white;
|
||||||
// apart from login forms, which have stronger border
|
// apart from login forms, which have stronger border
|
||||||
$strong-input-border-color: #c7c7c7;
|
$strong-input-border-color: #c7c7c7;
|
||||||
|
|
||||||
|
@ -129,6 +118,7 @@ $input-fg-color: rgba(74, 74, 74, 0.9);
|
||||||
// context menus
|
// context menus
|
||||||
$menu-border-color: rgba(187, 187, 187, 0.5);
|
$menu-border-color: rgba(187, 187, 187, 0.5);
|
||||||
$menu-bg-color: #f6f6f6;
|
$menu-bg-color: #f6f6f6;
|
||||||
|
$menu-selected-color: #f5f8fa;
|
||||||
|
|
||||||
$avatar-initial-color: #ffffff;
|
$avatar-initial-color: #ffffff;
|
||||||
$avatar-bg-color: transparent;
|
$avatar-bg-color: transparent;
|
||||||
|
@ -163,6 +153,15 @@ $roomtile-name-color: #ffffff;
|
||||||
$roomtile-selected-bg-color: #465561;
|
$roomtile-selected-bg-color: #465561;
|
||||||
$roomtile-focused-bg-color: #6d8597;
|
$roomtile-focused-bg-color: #6d8597;
|
||||||
|
|
||||||
|
$username-variant1-color: #1e7ddc;
|
||||||
|
$username-variant2-color: #a756a8;
|
||||||
|
$username-variant3-color: #7ac9a1;
|
||||||
|
$username-variant4-color: #f2809d;
|
||||||
|
$username-variant5-color: #ffc666;
|
||||||
|
$username-variant6-color: #76ddd7;
|
||||||
|
$username-variant7-color: #45529b;
|
||||||
|
$username-variant8-color: #bfd251;
|
||||||
|
|
||||||
$roomsublist-background: rgba(0, 0, 0, 0.2);
|
$roomsublist-background: rgba(0, 0, 0, 0.2);
|
||||||
$roomsublist-label-fg-color: #ffffff;
|
$roomsublist-label-fg-color: #ffffff;
|
||||||
$roomsublist-label-bg-color: $secondary-accent-color;
|
$roomsublist-label-bg-color: $secondary-accent-color;
|
||||||
|
@ -188,8 +187,8 @@ $event-redacted-border-color: #cccccc;
|
||||||
// event timestamp
|
// event timestamp
|
||||||
$event-timestamp-color: #acacac;
|
$event-timestamp-color: #acacac;
|
||||||
|
|
||||||
$edit-button-url: "../../img/icon_context_message.svg";
|
$edit-button-url: "$(res)/img/icon_context_message.svg";
|
||||||
$copy-button-url: "../../img/icon_copy_message.svg";
|
$copy-button-url: "$(res)/img/icon_copy_message.svg";
|
||||||
|
|
||||||
// e2e
|
// e2e
|
||||||
$e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color
|
$e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "_paths.scss";
|
||||||
|
@import "_fonts.scss";
|
||||||
@import "../../../../node_modules/matrix-react-sdk/res/themes/light/css/_base.scss";
|
@import "../../../../node_modules/matrix-react-sdk/res/themes/light/css/_base.scss";
|
||||||
@import "_status.scss";
|
@import "_status.scss";
|
||||||
@import "../../../../node_modules/matrix-react-sdk/res/css/_components.scss";
|
@import "../../../../node_modules/matrix-react-sdk/res/css/_components.scss";
|
||||||
|
|
|
@ -53,15 +53,11 @@ const COPY_LIST = [
|
||||||
["res/home.html", "webapp"],
|
["res/home.html", "webapp"],
|
||||||
["res/home-status.html", "webapp"],
|
["res/home-status.html", "webapp"],
|
||||||
["res/home/**", "webapp/home"],
|
["res/home/**", "webapp/home"],
|
||||||
["res/vector-icons/**", "webapp/vector-icons"],
|
|
||||||
["node_modules/matrix-react-sdk/res/{fonts,img,themes,media}/**", "webapp"],
|
|
||||||
["res/themes/**", "webapp/themes"],
|
["res/themes/**", "webapp/themes"],
|
||||||
|
["res/vector-icons/**", "webapp/vector-icons"],
|
||||||
|
["node_modules/matrix-react-sdk/res/media/**", "webapp/media"],
|
||||||
["node_modules/emojione/assets/svg/*", "webapp/emojione/svg/"],
|
["node_modules/emojione/assets/svg/*", "webapp/emojione/svg/"],
|
||||||
["node_modules/emojione/assets/png/*", "webapp/emojione/png/"],
|
["node_modules/emojione/assets/png/*", "webapp/emojione/png/"],
|
||||||
// XXX: This is tied quite heavily to the matching olm.js so it really should be
|
|
||||||
// in the bundle dir with the js to avoid caching issues giving us wasm that
|
|
||||||
// doesn't match our js, but I cannot find any way to get webpack to do this.
|
|
||||||
["node_modules/olm/olm.wasm", "webapp", { directwatch: 1 }],
|
|
||||||
["node_modules/olm/olm_legacy.js", "webapp", { directwatch: 1 }],
|
["node_modules/olm/olm_legacy.js", "webapp", { directwatch: 1 }],
|
||||||
["./config.json", "webapp", { directwatch: 1 }],
|
["./config.json", "webapp", { directwatch: 1 }],
|
||||||
];
|
];
|
||||||
|
|
|
@ -9,45 +9,49 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
GIT_CLONE_ARGS=("$@")
|
GIT_CLONE_ARGS=("$@")
|
||||||
|
[ -z "$defbranch" ] && defbranch="develop"
|
||||||
# Look in the many different CI env vars for which branch we're
|
|
||||||
# building
|
|
||||||
if [[ "$TRAVIS" == true ]]; then
|
|
||||||
curbranch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"
|
|
||||||
else
|
|
||||||
# ghprbSourceBranch for jenkins github pull request builder
|
|
||||||
# GIT_BRANCH for other jenkins builds
|
|
||||||
curbranch="${ghprbSourceBranch:-$GIT_BRANCH}"
|
|
||||||
# Otherwise look at the actual branch we're on
|
|
||||||
if [ -z "$curbranch" ]
|
|
||||||
then
|
|
||||||
curbranch=`git rev-parse --abbrev-ref HEAD`
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Chop 'origin' off the start as jenkins ends up using
|
|
||||||
# branches on the origin, but this doesn't work if we
|
|
||||||
# specify the branch when cloning.
|
|
||||||
curbranch=${curbranch#origin/}
|
|
||||||
|
|
||||||
echo "Determined branch to be $curbranch"
|
|
||||||
|
|
||||||
# clone a specific branch of a github repo
|
# clone a specific branch of a github repo
|
||||||
function clone() {
|
function clone() {
|
||||||
org=$1
|
org=$1
|
||||||
repo=$2
|
repo=$2
|
||||||
branch=$3
|
branch=$3
|
||||||
git clone https://github.com/$org/$repo.git $repo --branch $branch \
|
|
||||||
"${GIT_CLONE_ARGS[@]}"
|
# Chop 'origin' off the start as jenkins ends up using
|
||||||
|
# branches on the origin, but this doesn't work if we
|
||||||
|
# specify the branch when cloning.
|
||||||
|
branch=${branch#origin/}
|
||||||
|
|
||||||
|
if [ -n "$branch" ]
|
||||||
|
then
|
||||||
|
echo "Trying to use $org/$repo#$branch"
|
||||||
|
git clone https://github.com/$org/$repo.git $repo --branch $branch \
|
||||||
|
"${GIT_CLONE_ARGS[@]}"
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function dodep() {
|
function dodep() {
|
||||||
org=$1
|
org=$1
|
||||||
repo=$2
|
repo=$2
|
||||||
rm -rf $repo
|
rm -rf $repo
|
||||||
clone $org $repo $curbranch || {
|
|
||||||
[ "$curbranch" != 'develop' ] && clone $org $repo develop
|
# Try the PR author's branch in case it exists on the deps as well.
|
||||||
} || return $?
|
# Try the target branch of the push or PR.
|
||||||
|
# Use the default branch as the last resort.
|
||||||
|
if [[ "$TRAVIS" == true ]]; then
|
||||||
|
clone $org $repo $TRAVIS_PULL_REQUEST_BRANCH ||
|
||||||
|
clone $org $repo $TRAVIS_BRANCH ||
|
||||||
|
clone $org $repo $defbranch ||
|
||||||
|
return $?
|
||||||
|
else
|
||||||
|
clone $org $repo $ghprbSourceBranch ||
|
||||||
|
clone $org $repo $GIT_BRANCH ||
|
||||||
|
clone $org $repo `git rev-parse --abbrev-ref HEAD` ||
|
||||||
|
clone $org $repo $defbranch ||
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
echo "$repo set to branch "`git -C "$repo" rev-parse --abbrev-ref HEAD`
|
echo "$repo set to branch "`git -C "$repo" rev-parse --abbrev-ref HEAD`
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2019 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -21,9 +22,9 @@ import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||||
import SettingsStore from 'matrix-react-sdk/lib/settings/SettingsStore';
|
import SettingsStore from 'matrix-react-sdk/lib/settings/SettingsStore';
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'VectorLoginFooter',
|
displayName: 'VectorAuthFooter',
|
||||||
statics: {
|
statics: {
|
||||||
replaces: 'LoginFooter',
|
replaces: 'AuthFooter',
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
@ -32,11 +33,11 @@ module.exports = React.createClass({
|
||||||
if (SettingsStore.getValue("theme") === 'status') return <div />;
|
if (SettingsStore.getValue("theme") === 'status') return <div />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_Login_links">
|
<div className="mx_AuthFooter">
|
||||||
<a href="https://medium.com/@RiotChat">blog</a> ·
|
<a href="https://medium.com/@RiotChat" target="_blank" rel="noopener">blog</a>
|
||||||
<a href="https://twitter.com/@RiotChat">twitter</a> ·
|
<a href="https://twitter.com/@RiotChat" target="_blank" rel="noopener">twitter</a>
|
||||||
<a href="https://github.com/vector-im/riot-web">github</a> ·
|
<a href="https://github.com/vector-im/riot-web" target="_blank" rel="noopener">github</a>
|
||||||
<a href="https://matrix.org">{ _t('powered by Matrix') }</a>
|
<a href="https://matrix.org" target="_blank" rel="noopener">{ _t('powered by Matrix') }</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2019 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -23,9 +24,9 @@ const i = [1, 2, 3, 4, 5][Math.floor(Math.random() * 5)];
|
||||||
const DEFAULT_LOGO_URI = "themes/riot/img/logos/riot-im-logo-" + i + ".svg";
|
const DEFAULT_LOGO_URI = "themes/riot/img/logos/riot-im-logo-" + i + ".svg";
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'VectorLoginHeader',
|
displayName: 'VectorAuthHeaderLogo',
|
||||||
statics: {
|
statics: {
|
||||||
replaces: 'LoginHeader',
|
replaces: 'AuthHeaderLogo',
|
||||||
},
|
},
|
||||||
propTypes: {
|
propTypes: {
|
||||||
icon: PropTypes.string,
|
icon: PropTypes.string,
|
||||||
|
@ -33,10 +34,8 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="mx_Login_header">
|
<div className="mx_AuthHeaderLogo">
|
||||||
<div className="mx_Login_logo">
|
<img src={this.props.icon || DEFAULT_LOGO_URI} alt="Riot" />
|
||||||
<img src={this.props.icon || DEFAULT_LOGO_URI} alt="Riot" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
|
@ -16,9 +16,12 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const sanitizeHtml = require("sanitize-html");
|
|
||||||
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is identical to `CustomServerDialog` except for replacing "this app"
|
||||||
|
* with "Riot".
|
||||||
|
*/
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'VectorCustomServerDialog',
|
displayName: 'VectorCustomServerDialog',
|
||||||
statics: {
|
statics: {
|
||||||
|
@ -32,13 +35,17 @@ module.exports = React.createClass({
|
||||||
{ _t('Custom Server Options') }
|
{ _t('Custom Server Options') }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
<span dangerouslySetInnerHTML={{__html: sanitizeHtml(_t(
|
<p>{_t(
|
||||||
"You can use the custom server options to sign into other Matrix "+
|
"You can use the custom server options to sign into other " +
|
||||||
"servers by specifying a different Home server URL.<br/>This allows "+
|
"Matrix servers by specifying a different homeserver URL. This " +
|
||||||
"you to use Riot with an existing Matrix account on a different home "+
|
"allows you to use Riot with an existing Matrix account on a " +
|
||||||
"server.<br/><br/>You can also set a custom identity server but you won't "+
|
"different homeserver.",
|
||||||
"be able to invite users by email address, or be invited by email address yourself.",
|
)}</p>
|
||||||
))}} />
|
<p>{_t(
|
||||||
|
"You can also set a custom identity server, but you won't be " +
|
||||||
|
"able to invite users by email address, or be invited by email " +
|
||||||
|
"address yourself.",
|
||||||
|
)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button onClick={this.props.onFinished} autoFocus={true}>
|
<button onClick={this.props.onFinished} autoFocus={true}>
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"Riot is not supported on mobile web. Install the app?": "Riot is not supported on mobile web. Install the app?",
|
|
||||||
"Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s",
|
"Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s",
|
||||||
"Unknown device": "Unknown device",
|
"Unknown device": "Unknown device",
|
||||||
"%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s on %(osName)s",
|
"%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s on %(osName)s",
|
||||||
"You need to be using HTTPS to place a screen-sharing call.": "You need to be using HTTPS to place a screen-sharing call.",
|
"You need to be using HTTPS to place a screen-sharing call.": "You need to be using HTTPS to place a screen-sharing call.",
|
||||||
"Custom Server Options": "Custom Server Options",
|
|
||||||
"You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.<br/>This allows you to use Riot with an existing Matrix account on a different home server.<br/><br/>You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.<br/>This allows you to use Riot with an existing Matrix account on a different home server.<br/><br/>You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.",
|
|
||||||
"Dismiss": "Dismiss",
|
|
||||||
"powered by Matrix": "powered by Matrix",
|
"powered by Matrix": "powered by Matrix",
|
||||||
|
"Custom Server Options": "Custom Server Options",
|
||||||
|
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Riot with an existing Matrix account on a different homeserver.": "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Riot with an existing Matrix account on a different homeserver.",
|
||||||
|
"You can also set a custom identity server, but you won't be able to invite users by email address, or be invited by email address yourself.": "You can also set a custom identity server, but you won't be able to invite users by email address, or be invited by email address yourself.",
|
||||||
|
"Dismiss": "Dismiss",
|
||||||
"Welcome to Riot.im": "Welcome to Riot.im",
|
"Welcome to Riot.im": "Welcome to Riot.im",
|
||||||
"Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralised, encrypted chat & collaboration powered by [matrix]",
|
"Decentralised, encrypted chat & collaboration powered by [matrix]": "Decentralised, encrypted chat & collaboration powered by [matrix]",
|
||||||
"Search the room directory": "Search the room directory",
|
"Search the room directory": "Search the room directory",
|
||||||
|
|
|
@ -34,13 +34,13 @@
|
||||||
} %>
|
} %>
|
||||||
</head>
|
</head>
|
||||||
<body style="height: 100%;">
|
<body style="height: 100%;">
|
||||||
<section id="matrixchat" style="height: 100%;"></section>
|
<section id="matrixchat" style="height: 100%; overflow: auto;"></section>
|
||||||
<noscript>Sorry, Riot requires JavaScript to be enabled.</noscript> <!-- TODO: Translate this? -->
|
<noscript>Sorry, Riot requires JavaScript to be enabled.</noscript> <!-- TODO: Translate this? -->
|
||||||
<script>
|
<script>
|
||||||
window.vector_indexeddb_worker_script = '<%= htmlWebpackPlugin.files.chunks['indexeddb-worker'].entry %>';
|
window.vector_indexeddb_worker_script = '<%= htmlWebpackPlugin.files.chunks['indexeddb-worker'].entry %>';
|
||||||
</script>
|
</script>
|
||||||
<script src="<%= htmlWebpackPlugin.files.chunks['bundle'].entry %>"></script>
|
<script src="<%= htmlWebpackPlugin.files.chunks['bundle'].entry %>"></script>
|
||||||
<img src="img/warning.svg" width="24" height="23" style="visibility: hidden; position: absolute; top: 0px; left: 0px;"/>
|
<img src="<%= require('matrix-react-sdk/res/img/warning.svg') %>" width="24" height="23" style="visibility: hidden; position: absolute; top: 0px; left: 0px;"/>
|
||||||
<audio id="messageAudio">
|
<audio id="messageAudio">
|
||||||
<source src="media/message.ogg" type="audio/ogg" />
|
<source src="media/message.ogg" type="audio/ogg" />
|
||||||
<source src="media/message.mp3" type="audio/mpeg" />
|
<source src="media/message.mp3" type="audio/mpeg" />
|
||||||
|
|
|
@ -24,6 +24,8 @@ require('gfm.css/gfm.css');
|
||||||
require('highlight.js/styles/github.css');
|
require('highlight.js/styles/github.css');
|
||||||
require('draft-js/dist/Draft.css');
|
require('draft-js/dist/Draft.css');
|
||||||
|
|
||||||
|
import olmWasmPath from 'olm/olm.wasm';
|
||||||
|
|
||||||
import './rageshakesetup';
|
import './rageshakesetup';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -140,7 +142,7 @@ function onNewScreen(screen) {
|
||||||
// so in that instance, hardcode to use riot.im/app for now instead.
|
// so in that instance, hardcode to use riot.im/app for now instead.
|
||||||
function makeRegistrationUrl(params) {
|
function makeRegistrationUrl(params) {
|
||||||
let url;
|
let url;
|
||||||
if (window.location.protocol === "file:") {
|
if (window.location.protocol === "vector:") {
|
||||||
url = 'https://riot.im/app/#/register';
|
url = 'https://riot.im/app/#/register';
|
||||||
} else {
|
} else {
|
||||||
url = (
|
url = (
|
||||||
|
@ -279,7 +281,7 @@ async function loadApp() {
|
||||||
|
|
||||||
// as quickly as we possibly can, set a default theme...
|
// as quickly as we possibly can, set a default theme...
|
||||||
let a;
|
let a;
|
||||||
const theme = SettingsStore.getValue("theme");
|
const theme = "dharma";//SettingsStore.getValue("theme");
|
||||||
for (let i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
|
for (let i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
|
||||||
const href = a.getAttribute("href");
|
const href = a.getAttribute("href");
|
||||||
if (!href) continue;
|
if (!href) continue;
|
||||||
|
@ -379,18 +381,19 @@ function loadOlm() {
|
||||||
*
|
*
|
||||||
* We also need to tell the Olm js to look for its wasm file at the same
|
* We also need to tell the Olm js to look for its wasm file at the same
|
||||||
* level as index.html. It really should be in the same place as the js,
|
* level as index.html. It really should be in the same place as the js,
|
||||||
* ie. in the bundle directory, to avoid caching issues, but as far as I
|
* ie. in the bundle directory, but as far as I can tell this is
|
||||||
* can tell this is completely impossible with webpack.
|
* completely impossible with webpack. We do, however, use a hashed
|
||||||
|
* filename to avoid caching issues.
|
||||||
*/
|
*/
|
||||||
return Olm.init({
|
return Olm.init({
|
||||||
locateFile: () => 'olm.wasm',
|
locateFile: () => olmWasmPath,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
console.log("Using WebAssembly Olm");
|
console.log("Using WebAssembly Olm");
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
console.log("Failed to load Olm: trying legacy version");
|
console.log("Failed to load Olm: trying legacy version");
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const s = document.createElement('script');
|
const s = document.createElement('script');
|
||||||
s.src = 'olm_legacy.js';
|
s.src = 'olm_legacy.js'; // XXX: This should be cache-busted too
|
||||||
s.onload = resolve;
|
s.onload = resolve;
|
||||||
s.onerror = reject;
|
s.onerror = reject;
|
||||||
document.body.appendChild(s);
|
document.body.appendChild(s);
|
||||||
|
|
|
@ -28,17 +28,17 @@ const ipcRenderer = window.ipcRenderer;
|
||||||
|
|
||||||
function platformFriendlyName(): string {
|
function platformFriendlyName(): string {
|
||||||
// used to use window.process but the same info is available here
|
// used to use window.process but the same info is available here
|
||||||
if (navigator.userAgent.indexOf('Macintosh')) {
|
if (navigator.userAgent.includes('Macintosh')) {
|
||||||
return 'macOS';
|
return 'macOS';
|
||||||
} else if (navigator.userAgent.indexOf('FreeBSD')) {
|
} else if (navigator.userAgent.includes('FreeBSD')) {
|
||||||
return 'FreeBSD';
|
return 'FreeBSD';
|
||||||
} else if (navigator.userAgent.indexOf('OpenBSD')) {
|
} else if (navigator.userAgent.includes('OpenBSD')) {
|
||||||
return 'OpenBSD';
|
return 'OpenBSD';
|
||||||
} else if (navigator.userAgent.indexOf('SunOS')) {
|
} else if (navigator.userAgent.includes('SunOS')) {
|
||||||
return 'SunOS';
|
return 'SunOS';
|
||||||
} else if (navigator.userAgent.indexOf('Windows')) {
|
} else if (navigator.userAgent.includes('Windows')) {
|
||||||
return 'Windows';
|
return 'Windows';
|
||||||
} else if (navigator.userAgent.indexOf('Linux')) {
|
} else if (navigator.userAgent.includes('Linux')) {
|
||||||
return 'Linux';
|
return 'Linux';
|
||||||
} else {
|
} else {
|
||||||
return 'Unknown';
|
return 'Unknown';
|
||||||
|
@ -136,7 +136,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
// maybe we should pass basic styling (italics, bold, underline) through from MD
|
// maybe we should pass basic styling (italics, bold, underline) through from MD
|
||||||
// we only have to strip out < and > as the spec doesn't include anything about things like &
|
// we only have to strip out < and > as the spec doesn't include anything about things like &
|
||||||
// so we shouldn't assume that all implementations will treat those properly. Very basic tag parsing is done.
|
// so we shouldn't assume that all implementations will treat those properly. Very basic tag parsing is done.
|
||||||
if (navigator.userAgent.indexOf('Linux')) {
|
if (navigator.userAgent.includes('Linux')) {
|
||||||
msg = msg.replace(/</g, '<').replace(/>/g, '>');
|
msg = msg.replace(/</g, '<').replace(/>/g, '>');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,13 @@ describe('joining a room', function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not get stuck at a spinner', function() {
|
// TODO: Re-enable test
|
||||||
|
// The test is currently disabled because the room directory now resides in a dialog,
|
||||||
|
// which is not accessible from the MatrixChat component anymore. Convincing react that
|
||||||
|
// the dialog does exist and is under a different tree is incredibly difficult though,
|
||||||
|
// so for now the test has been disabled. We should revisit this test when someone has
|
||||||
|
// the time to kill to figure this out. Problem area is highlighted within the test.
|
||||||
|
xit('should not get stuck at a spinner', function() {
|
||||||
const ROOM_ALIAS = '#alias:localhost';
|
const ROOM_ALIAS = '#alias:localhost';
|
||||||
const ROOM_ID = '!id:localhost';
|
const ROOM_ID = '!id:localhost';
|
||||||
|
|
||||||
|
@ -118,8 +124,19 @@ describe('joining a room', function() {
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
console.log(`${Date.now()} App made requests for directory view; switching to a room.`);
|
console.log(`${Date.now()} App made requests for directory view; switching to a room.`);
|
||||||
|
|
||||||
|
// TODO: Make this look in the right spot for the directory dialog.
|
||||||
|
// See the comment block at the top of the test for a bit more information. The short
|
||||||
|
// story here is that the RoomDirectory does not exist under matrixChat anymore, or even
|
||||||
|
// the parentDiv we have access to. Asking React to find the RoomDirectory as a child of
|
||||||
|
// the document results in it complaining that you didn't give it a component tree to
|
||||||
|
// search in. When you do get a reference to the component tree based off the document
|
||||||
|
// root and ask it to search, it races and can't find the component in time. To top it
|
||||||
|
// all off, MatrixReactTestUtils can't find the element in time either even with a very
|
||||||
|
// high number of attempts. Assuming we can get a reference to the RoomDirectory in a
|
||||||
|
// dialog, the rest of the test should be fine.
|
||||||
const roomDir = ReactTestUtils.findRenderedComponentWithType(
|
const roomDir = ReactTestUtils.findRenderedComponentWithType(
|
||||||
matrixChat, RoomDirectory);
|
matrixChat, RoomDirectory,
|
||||||
|
);
|
||||||
|
|
||||||
// enter an alias in the input, and simulate enter
|
// enter an alias in the input, and simulate enter
|
||||||
const input = ReactTestUtils.findRenderedDOMComponentWithTag(
|
const input = ReactTestUtils.findRenderedDOMComponentWithTag(
|
||||||
|
|
|
@ -254,7 +254,7 @@ describe('loading:', function() {
|
||||||
return awaitLoginComponent(matrixChat).then(() => {
|
return awaitLoginComponent(matrixChat).then(() => {
|
||||||
// we expect a single <Login> component
|
// we expect a single <Login> component
|
||||||
ReactTestUtils.findRenderedComponentWithType(
|
ReactTestUtils.findRenderedComponentWithType(
|
||||||
matrixChat, sdk.getComponent('structures.login.Login'));
|
matrixChat, sdk.getComponent('structures.auth.Login'));
|
||||||
|
|
||||||
// the only outstanding request should be a GET /login
|
// the only outstanding request should be a GET /login
|
||||||
// (in particular there should be no /register request for
|
// (in particular there should be no /register request for
|
||||||
|
@ -343,40 +343,6 @@ describe('loading:', function() {
|
||||||
}).done(done, done);
|
}).done(done, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("logs in correctly with a Riot Team Server", function() {
|
|
||||||
sdk.setFetch(httpBackend.fetchFn); // XXX: ought to restore this!
|
|
||||||
|
|
||||||
httpBackend.when('GET', '/pushrules').respond(200, {});
|
|
||||||
httpBackend.when('POST', '/filter').respond(200, { filter_id: 'fid' });
|
|
||||||
|
|
||||||
loadApp({
|
|
||||||
config: {
|
|
||||||
teamServerConfig: {
|
|
||||||
teamServerURL: 'http://my_team_server',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise.delay(1).then(() => {
|
|
||||||
// we expect a loading spinner while we log into the RTS
|
|
||||||
assertAtLoadingSpinner(matrixChat);
|
|
||||||
|
|
||||||
httpBackend.when('GET', 'my_team_server/login').respond(200, {
|
|
||||||
team_token: 'nom',
|
|
||||||
});
|
|
||||||
return httpBackend.flush();
|
|
||||||
}).then(() => {
|
|
||||||
return awaitSyncingSpinner(matrixChat);
|
|
||||||
}).then(() => {
|
|
||||||
// we got a sync spinner - let the sync complete
|
|
||||||
return expectAndAwaitSync();
|
|
||||||
}).then(() => {
|
|
||||||
// once the sync completes, we should have a home page
|
|
||||||
ReactTestUtils.findRenderedComponentWithType(
|
|
||||||
matrixChat, sdk.getComponent('structures.HomePage'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('/#/login link:', function() {
|
describe('/#/login link:', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
loadApp({
|
loadApp({
|
||||||
|
@ -390,7 +356,7 @@ describe('loading:', function() {
|
||||||
it('shows a login view', function() {
|
it('shows a login view', function() {
|
||||||
// we expect a single <Login> component
|
// we expect a single <Login> component
|
||||||
ReactTestUtils.findRenderedComponentWithType(
|
ReactTestUtils.findRenderedComponentWithType(
|
||||||
matrixChat, sdk.getComponent('structures.login.Login'),
|
matrixChat, sdk.getComponent('structures.auth.Login'),
|
||||||
);
|
);
|
||||||
|
|
||||||
// the only outstanding request should be a GET /login
|
// the only outstanding request should be a GET /login
|
||||||
|
@ -554,7 +520,7 @@ describe('loading:', function() {
|
||||||
|
|
||||||
// we expect a single <Login> component
|
// we expect a single <Login> component
|
||||||
ReactTestUtils.findRenderedComponentWithType(
|
ReactTestUtils.findRenderedComponentWithType(
|
||||||
matrixChat, sdk.getComponent('structures.login.Login'),
|
matrixChat, sdk.getComponent('structures.auth.Login'),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -562,7 +528,7 @@ describe('loading:', function() {
|
||||||
// ILAG renders this obsolete. I think.
|
// ILAG renders this obsolete. I think.
|
||||||
it('should allow us to return to the app', function() {
|
it('should allow us to return to the app', function() {
|
||||||
const login = ReactTestUtils.findRenderedComponentWithType(
|
const login = ReactTestUtils.findRenderedComponentWithType(
|
||||||
matrixChat, sdk.getComponent('structures.login.Login')
|
matrixChat, sdk.getComponent('structures.auth.Login')
|
||||||
);
|
);
|
||||||
|
|
||||||
const linkText = 'Return to app';
|
const linkText = 'Return to app';
|
||||||
|
@ -630,7 +596,7 @@ describe('loading:', function() {
|
||||||
function completeLogin(matrixChat) {
|
function completeLogin(matrixChat) {
|
||||||
// we expect a single <Login> component
|
// we expect a single <Login> component
|
||||||
const login = ReactTestUtils.findRenderedComponentWithType(
|
const login = ReactTestUtils.findRenderedComponentWithType(
|
||||||
matrixChat, sdk.getComponent('structures.login.Login'));
|
matrixChat, sdk.getComponent('structures.auth.Login'));
|
||||||
|
|
||||||
httpBackend.when('POST', '/login').check(function(req) {
|
httpBackend.when('POST', '/login').check(function(req) {
|
||||||
expect(req.data.type).toEqual('m.login.password');
|
expect(req.data.type).toEqual('m.login.password');
|
||||||
|
@ -743,6 +709,6 @@ function awaitRoomView(matrixChat, retryLimit, retryCount) {
|
||||||
|
|
||||||
function awaitLoginComponent(matrixChat, attempts) {
|
function awaitLoginComponent(matrixChat, attempts) {
|
||||||
return MatrixReactTestUtils.waitForRenderedComponentWithType(
|
return MatrixReactTestUtils.waitForRenderedComponentWithType(
|
||||||
matrixChat, sdk.getComponent('structures.login.Login'), attempts,
|
matrixChat, sdk.getComponent('structures.auth.Login'), attempts,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,34 +16,42 @@ module.exports = {
|
||||||
"mobileguide": "./src/vector/mobile_guide/index.js",
|
"mobileguide": "./src/vector/mobile_guide/index.js",
|
||||||
|
|
||||||
// CSS themes
|
// CSS themes
|
||||||
"theme-light": "./node_modules/matrix-react-sdk/res/themes/light/css/light.scss",
|
//"theme-light": "./node_modules/matrix-react-sdk/res/themes/light/css/light.scss",
|
||||||
"theme-dark": "./node_modules/matrix-react-sdk/res/themes/dark/css/dark.scss",
|
//"theme-dark": "./node_modules/matrix-react-sdk/res/themes/dark/css/dark.scss",
|
||||||
"theme-status": "./res/themes/status/css/status.scss",
|
"theme-dharma": "./node_modules/matrix-react-sdk/res/themes/dharma/css/dharma.scss",
|
||||||
|
//"theme-status": "./res/themes/status/css/status.scss",
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{ enforce: 'pre', test: /\.js$/, use: "source-map-loader", exclude: /node_modules/, },
|
{ enforce: 'pre', test: /\.js$/, use: "source-map-loader", exclude: /node_modules/, },
|
||||||
{ test: /\.js$/, use: "babel-loader", include: path.resolve(__dirname, 'src') },
|
{ test: /\.js$/, use: "babel-loader", include: path.resolve(__dirname, 'src') },
|
||||||
|
{
|
||||||
|
test: /\.wasm$/,
|
||||||
|
loader: "file-loader",
|
||||||
|
type: "javascript/auto", // https://github.com/webpack/webpack/issues/6725
|
||||||
|
options: {
|
||||||
|
name: '[name].[hash:7].[ext]',
|
||||||
|
outputPath: '.',
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /\.scss$/,
|
test: /\.scss$/,
|
||||||
// 1. postcss-loader turns the SCSS into normal CSS.
|
// 1. postcss-loader turns the SCSS into normal CSS.
|
||||||
// 2. raw-loader turns the CSS into a javascript module
|
// 2. css-loader turns the CSS into a JS module whose default
|
||||||
// whose default export is a string containing the CSS.
|
// export is a string containing the CSS, while also adding
|
||||||
// (raw-loader is similar to css-loader, but the latter
|
// the images and fonts from CSS as Webpack inputs.
|
||||||
// would also drag in the imgs and fonts that our CSS refers to
|
|
||||||
// as webpack inputs.)
|
|
||||||
// 3. ExtractTextPlugin turns that string into a separate asset.
|
// 3. ExtractTextPlugin turns that string into a separate asset.
|
||||||
use: ExtractTextPlugin.extract({
|
use: ExtractTextPlugin.extract({
|
||||||
use: [
|
use: [
|
||||||
"raw-loader",
|
"css-loader",
|
||||||
{
|
{
|
||||||
loader: 'postcss-loader',
|
loader: 'postcss-loader',
|
||||||
options: {
|
options: {
|
||||||
config: {
|
config: {
|
||||||
path: './postcss.config.js'
|
path: './postcss.config.js',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -51,10 +59,40 @@ module.exports = {
|
||||||
// this works similarly to the scss case, without postcss.
|
// this works similarly to the scss case, without postcss.
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
use: ExtractTextPlugin.extract({
|
use: ExtractTextPlugin.extract({
|
||||||
use: "raw-loader"
|
use: "css-loader",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: /\.(gif|png|svg|ttf)$/,
|
||||||
|
// Use a content-based hash in the name so that we can set a long cache
|
||||||
|
// lifetime for assets while still delivering changes quickly.
|
||||||
|
oneOf: [
|
||||||
|
{
|
||||||
|
// Images referenced in CSS files
|
||||||
|
issuer: /\.(scss|css)$/,
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[hash:7].[ext]',
|
||||||
|
outputPath: getImgOutputPath,
|
||||||
|
publicPath: function(url, resourcePath) {
|
||||||
|
// CSS image usages end up in the `bundles/[hash]` output
|
||||||
|
// directory, so we adjust the final path to navigate up
|
||||||
|
// twice.
|
||||||
|
const outputPath = getImgOutputPath(url, resourcePath);
|
||||||
|
return toPublicPath(path.join("../..", outputPath));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Images referenced in HTML and JS files
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[hash:7].[ext]',
|
||||||
|
outputPath: getImgOutputPath,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
noParse: [
|
noParse: [
|
||||||
// for cross platform compatibility use [\\\/] as the path separator
|
// for cross platform compatibility use [\\\/] as the path separator
|
||||||
|
@ -74,14 +112,13 @@ module.exports = {
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, "webapp"),
|
path: path.join(__dirname, "webapp"),
|
||||||
|
|
||||||
// the generated js (and CSS, from the ExtractTextPlugin) are put in a
|
// The generated JS (and CSS, from the ExtractTextPlugin) are put in a
|
||||||
// unique subdirectory for the build. There will only be one such
|
// unique subdirectory for the build. There will only be one such
|
||||||
// 'bundle' directory in the generated tarball; however, hosting
|
// 'bundle' directory in the generated tarball; however, hosting
|
||||||
// servers can collect 'bundles' from multiple versions into one
|
// servers can collect 'bundles' from multiple versions into one
|
||||||
// directory and symlink it into place - this allows users who loaded
|
// directory and symlink it into place - this allows users who loaded
|
||||||
// an older version of the application to continue to access webpack
|
// an older version of the application to continue to access webpack
|
||||||
// chunks even after the app is redeployed.
|
// chunks even after the app is redeployed.
|
||||||
//
|
|
||||||
filename: "bundles/[hash]/[name].js",
|
filename: "bundles/[hash]/[name].js",
|
||||||
chunkFilename: "bundles/[hash]/[name].js",
|
chunkFilename: "bundles/[hash]/[name].js",
|
||||||
devtoolModuleFilenameTemplate: function(info) {
|
devtoolModuleFilenameTemplate: function(info) {
|
||||||
|
@ -157,3 +194,27 @@ module.exports = {
|
||||||
inline: false,
|
inline: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge assets found via CSS and imports into a single tree, while also preserving
|
||||||
|
* directories under `res`.
|
||||||
|
*
|
||||||
|
* @param {string} url The adjusted name of the file, such as `warning.1234567.svg`.
|
||||||
|
* @param {string} resourcePath The absolute path to the source file with unmodified name.
|
||||||
|
* @return {string} The returned paths will look like `img/warning.1234567.svg`.
|
||||||
|
*/
|
||||||
|
function getImgOutputPath(url, resourcePath) {
|
||||||
|
const prefix = /^.*[/\\]res[/\\]/;
|
||||||
|
const outputDir = path.dirname(resourcePath).replace(prefix, "");
|
||||||
|
return path.join(outputDir, path.basename(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert path to public path format, which always uses forward slashes, since it will
|
||||||
|
* be placed directly into things like CSS files.
|
||||||
|
*
|
||||||
|
* @param {string} path Some path to a file.
|
||||||
|
*/
|
||||||
|
function toPublicPath(path) {
|
||||||
|
return path.replace(/\\/g, '/');
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue