Merge pull request #2460 from matrix-org/jryans/versioned-img-urls

Load fonts and images via source-relative URLs and requires
This commit is contained in:
J. Ryan Stinnett 2019-01-18 14:27:55 -06:00 committed by GitHub
commit 7c9509ceb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
104 changed files with 274 additions and 231 deletions

View File

@ -168,6 +168,10 @@ module.exports = function (config) {
path.resolve('./test'), path.resolve('./test'),
] ]
}, },
{
test: /\.(gif|png|svg|ttf)$/,
loader: 'file-loader',
},
], ],
noParse: [ noParse: [
// for cross platform compatibility use [\\\/] as the path separator // for cross platform compatibility use [\\\/] as the path separator

View File

@ -47,7 +47,7 @@
"start:init": "babel src -d lib --source-maps --copy-files", "start:init": "babel src -d lib --source-maps --copy-files",
"lint": "eslint src/", "lint": "eslint src/",
"lintall": "eslint src/ test/", "lintall": "eslint src/ test/",
"lintwithexclusions": "eslint --max-warnings 18 --ignore-path .eslintignore.errorfiles src test", "lintwithexclusions": "eslint --max-warnings 13 --ignore-path .eslintignore.errorfiles src test",
"clean": "rimraf lib", "clean": "rimraf lib",
"prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt", "prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt",
"test": "karma start --single-run=true --browsers ChromeHeadless", "test": "karma start --single-run=true --browsers ChromeHeadless",
@ -125,6 +125,7 @@
"eslint-plugin-react": "^7.7.0", "eslint-plugin-react": "^7.7.0",
"estree-walker": "^0.5.0", "estree-walker": "^0.5.0",
"expect": "^23.6.0", "expect": "^23.6.0",
"file-loader": "^3.0.1",
"flow-parser": "^0.57.3", "flow-parser": "^0.57.3",
"jest-mock": "^23.2.0", "jest-mock": "^23.2.0",
"karma": "^3.0.0", "karma": "^3.0.0",

View File

@ -54,7 +54,7 @@ limitations under the License.
&:before { &:before {
background-color: $accent-fg-color; background-color: $accent-fg-color;
mask: url('../../img/icons-create-room.svg'); mask: url('$(res)/img/icons-create-room.svg');
mask-repeat: no-repeat; mask-repeat: no-repeat;
mask-position: center; mask-position: center;
mask-size: 80%; mask-size: 80%;

View File

@ -105,7 +105,7 @@ limitations under the License.
.mx_RoomSubList_addRoom { .mx_RoomSubList_addRoom {
background-color: $roomheader-addroom-color; background-color: $roomheader-addroom-color;
color: $roomsublist-background; color: $roomsublist-background;
background-image: url('../../img/icons-room-add.svg'); background-image: url('$(res)/img/icons-room-add.svg');
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
border-radius: 10px; // 16/2 + 2 padding border-radius: 10px; // 16/2 + 2 padding
@ -120,7 +120,7 @@ limitations under the License.
.mx_RoomSubList_chevron { .mx_RoomSubList_chevron {
pointer-events: none; pointer-events: none;
background-image: url('../../img/topleft-chevron.svg'); background-image: url('$(res)/img/topleft-chevron.svg');
background-repeat: no-repeat; background-repeat: no-repeat;
transition: transform 0.2s ease-in; transition: transform 0.2s ease-in;
width: 10px; width: 10px;

View File

@ -116,7 +116,7 @@ limitations under the License.
.mx_RoomView_messagePanelSearchSpinner { .mx_RoomView_messagePanelSearchSpinner {
flex: 1; flex: 1;
background-image: url('../../img/typing-indicator-2x.gif'); background-image: url('$(res)/img/typing-indicator-2x.gif');
background-position: center 367px; background-position: center 367px;
background-size: 25px; background-size: 25px;
background-repeat: no-repeat; background-repeat: no-repeat;
@ -125,7 +125,7 @@ limitations under the License.
.mx_RoomView_messagePanelSearchSpinner:before { .mx_RoomView_messagePanelSearchSpinner:before {
background-color: $greyed-fg-color; background-color: $greyed-fg-color;
mask: url('../../img/feather-icons/search-input.svg'); mask: url('$(res)/img/feather-icons/search-input.svg');
mask-repeat: no-repeat; mask-repeat: no-repeat;
mask-position: center; mask-position: center;
mask-size: 50px; mask-size: 50px;

View File

@ -16,7 +16,7 @@ limitations under the License.
.mx_SearchBox_closeButton { .mx_SearchBox_closeButton {
cursor: pointer; cursor: pointer;
background-image: url('../../img/icons-close.svg'); background-image: url('$(res)/img/icons-close.svg');
background-repeat: no-repeat; background-repeat: no-repeat;
width: 16px; width: 16px;
height: 16px; height: 16px;

View File

@ -130,12 +130,12 @@ limitations under the License.
} }
.mx_TagPanel_groupsButton > .mx_GroupsButton:before { .mx_TagPanel_groupsButton > .mx_GroupsButton:before {
mask: url('../../img/feather-icons/users.svg'); mask: url('$(res)/img/feather-icons/users.svg');
mask-position: center 11px; mask-position: center 11px;
} }
.mx_TagPanel_groupsButton > .mx_TagPanel_report:before { .mx_TagPanel_groupsButton > .mx_TagPanel_report:before {
mask: url('../../img/feather-icons/life-buoy.svg'); mask: url('$(res)/img/feather-icons/life-buoy.svg');
mask-position: center 9px; mask-position: center 9px;
} }

View File

@ -173,7 +173,7 @@ limitations under the License.
padding: 0px; padding: 0px;
width: 240px; width: 240px;
color: $input-fg-color; color: $input-fg-color;
font-family: 'Open Sans', Helvetica, Arial, Sans-Serif; font-family: $font-family;
font-size: 16px; font-size: 16px;
} }

View File

@ -61,7 +61,7 @@ limitations under the License.
padding: 0; padding: 0;
width: 240px; width: 240px;
color: $input-fg-color; color: $input-fg-color;
font-family: 'Open Sans', Helvetica, Arial, Sans-Serif; font-family: $font-family;
font-size: 16px; font-size: 16px;
} }

View File

@ -24,7 +24,7 @@ limitations under the License.
padding-bottom: 10px; padding-bottom: 10px;
&:before { &:before {
mask: url("../../img/e2e/lock-warning.svg"); mask: url("$(res)/img/e2e/lock-warning.svg");
mask-repeat: no-repeat; mask-repeat: no-repeat;
background-color: $primary-fg-color; background-color: $primary-fg-color;
content: ""; content: "";

View File

@ -44,7 +44,7 @@ input[type=text].mx_DirectorySearchBox_input:focus {
padding-right: 10px; padding-right: 10px;
background-color: $plinth-bg-color; background-color: $plinth-bg-color;
border-radius: 3px; border-radius: 3px;
background-image: url('../../img/icon-return.svg'); background-image: url('$(res)/img/icon-return.svg');
background-position: 8px 70%; background-position: 8px 70%;
background-repeat: no-repeat; background-repeat: no-repeat;
text-indent: 18px; text-indent: 18px;
@ -61,7 +61,7 @@ input[type=text].mx_DirectorySearchBox_input:focus {
.mx_DirectorySearchBox_clear { .mx_DirectorySearchBox_clear {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
background: url('../../img/icon_context_delete.svg'); background: url('$(res)/img/icon_context_delete.svg');
background-position: 0 50%; background-position: 0 50%;
background-repeat: no-repeat; background-repeat: no-repeat;
width: 15px; width: 15px;

View File

@ -50,7 +50,7 @@ limitations under the License.
max-height: 100%; max-height: 100%;
/* object-fit hack needed for Chrome due to Chrome not re-laying-out until you refresh */ /* object-fit hack needed for Chrome due to Chrome not re-laying-out until you refresh */
object-fit: contain; object-fit: contain;
/* background-image: url('../../img/trans.png'); */ /* background-image: url('$(res)/img/trans.png'); */
pointer-events: all; pointer-events: all;
} }

View File

@ -22,7 +22,7 @@ limitations under the License.
} }
.mx_EntityTile:hover { .mx_EntityTile:hover {
background-image: url('../../img/member_chevron.png'); background-image: url('$(res)/img/member_chevron.png');
background-position: center right 10px; background-position: center right 10px;
background-repeat: no-repeat; background-repeat: no-repeat;
padding-right: 30px; padding-right: 30px;

View File

@ -291,8 +291,8 @@ limitations under the License.
} }
/* always override hidden attribute for blocked and warning */ /* always override hidden attribute for blocked and warning */
.mx_EventTile_e2eIcon_hidden[src="img/e2e-blocked.svg"], .mx_EventTile_e2eIcon_hidden[src*="img/e2e-blocked.svg"],
.mx_EventTile_e2eIcon_hidden[src="img/e2e-warning.svg"] { .mx_EventTile_e2eIcon_hidden[src*="img/e2e-warning.svg"] {
display: block; display: block;
} }

View File

@ -83,7 +83,7 @@ limitations under the License.
.mx_MemberList_invite span { .mx_MemberList_invite span {
margin: 0 auto; margin: 0 auto;
background-image: url('../../img/feather-icons/user-add.svg'); background-image: url('$(res)/img/feather-icons/user-add.svg');
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center left; background-position: center left;
padding-left: 25px; padding-left: 25px;

View File

@ -29,7 +29,7 @@ limitations under the License.
display: none; display: none;
flex: 0 0 16px; flex: 0 0 16px;
height: 16px; height: 16px;
background-image: url('../../img/icon_context.svg'); background-image: url('$(res)/img/icon_context.svg');
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
} }

View File

@ -32,7 +32,7 @@ limitations under the License.
width: 37px; width: 37px;
height: 37px; height: 37px;
background-color: $accent-color; background-color: $accent-color;
mask: url('../../img/feather-icons/search-input.svg'); mask: url('$(res)/img/feather-icons/search-input.svg');
mask-repeat: no-repeat; mask-repeat: no-repeat;
mask-position: center; mask-position: center;
} }
@ -55,7 +55,7 @@ limitations under the License.
.mx_SearchBar_cancel { .mx_SearchBar_cancel {
background-color: $warning-color; background-color: $warning-color;
mask: url('../../img/cancel.svg'); mask: url('$(res)/img/cancel.svg');
mask-repeat: no-repeat; mask-repeat: no-repeat;
mask-position: center; mask-position: center;
mask-size: 14px; mask-size: 14px;

View File

@ -54,7 +54,7 @@ limitations under the License.
position: absolute; position: absolute;
width: 38px; width: 38px;
height: 38px; height: 38px;
mask: url('../../img/icon-jump-to-first-unread.svg'); mask: url('$(res)/img/icon-jump-to-first-unread.svg');
mask-repeat: no-repeat; mask-repeat: no-repeat;
mask-position: 9px 13px; mask-position: 9px 13px;
background: $roomtile-name-color; background: $roomtile-name-color;

View File

@ -61,7 +61,7 @@ limitations under the License.
} }
.mx_WhoIsTypingTile_label > span { .mx_WhoIsTypingTile_label > span {
background-image: url('../../img/typing-indicator-2x.gif'); background-image: url('$(res)/img/typing-indicator-2x.gif');
background-size: 25px; background-size: 25px;
background-position: left bottom; background-position: left bottom;
background-repeat: no-repeat; background-repeat: no-repeat;

View File

@ -149,8 +149,8 @@ $event-redacted-border-color: #000000;
// event timestamp // event timestamp
$event-timestamp-color: #acacac; $event-timestamp-color: #acacac;
$edit-button-url: "../../img/icon_context_message_dark.svg"; $edit-button-url: "$(res)/img/icon_context_message_dark.svg";
$copy-button-url: "../../img/icon_copy_message_dark.svg"; $copy-button-url: "$(res)/img/icon_copy_message_dark.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

View File

@ -1,4 +1,5 @@
@import "../../light/css/_paths.scss";
@import "../../light/css/_fonts.scss";
@import "../../light/css/_base.scss"; @import "../../light/css/_base.scss";
@import "_dark.scss"; @import "_dark.scss";
@import "../../../../res/css/_components.scss"; @import "../../../../res/css/_components.scss";

View File

@ -1,5 +1,3 @@
@import "_fonts.scss";
// XXX: check this? // XXX: check this?
/* Nunito lacks combining diacritics, so these will fall through /* Nunito lacks combining diacritics, so these will fall through
to the next font. Helevetica's diacritics however do not combine to the next font. Helevetica's diacritics however do not combine
@ -171,8 +169,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
@ -275,7 +273,7 @@ input[type=search].mx_textinput_icon {
// FIXME THEME - Tint by CSS rather than referencing a duplicate asset // FIXME THEME - Tint by CSS rather than referencing a duplicate asset
input[type=text].mx_textinput_icon.mx_textinput_search, input[type=text].mx_textinput_icon.mx_textinput_search,
input[type=search].mx_textinput_icon.mx_textinput_search { input[type=search].mx_textinput_icon.mx_textinput_search {
background-image: url('../../img/feather-icons/search-input.svg'); background-image: url('$(res)/img/feather-icons/search-input.svg');
} }
// dont search UI as not all browsers support it, // dont search UI as not all browsers support it,

View File

@ -11,37 +11,37 @@
font-family: 'Nunito'; font-family: 'Nunito';
font-style: italic; font-style: italic;
font-weight: 400; font-weight: 400;
src: url('../../fonts/Nunito/XRXX3I6Li01BKofIMNaDRss.ttf') format('truetype'); src: url('$(res)/fonts/Nunito/XRXX3I6Li01BKofIMNaDRss.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: 'Nunito'; font-family: 'Nunito';
font-style: italic; font-style: italic;
font-weight: 600; font-weight: 600;
src: url('../../fonts/Nunito/XRXQ3I6Li01BKofIMN5cYtvKUTo.ttf') format('truetype'); src: url('$(res)/fonts/Nunito/XRXQ3I6Li01BKofIMN5cYtvKUTo.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: 'Nunito'; font-family: 'Nunito';
font-style: italic; font-style: italic;
font-weight: 700; font-weight: 700;
src: url('../../fonts/Nunito/XRXQ3I6Li01BKofIMN44Y9vKUTo.ttf') format('truetype'); src: url('$(res)/fonts/Nunito/XRXQ3I6Li01BKofIMN44Y9vKUTo.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: 'Nunito'; font-family: 'Nunito';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
src: url('../../fonts/Nunito/XRXV3I6Li01BKofINeaE.ttf') format('truetype'); src: url('$(res)/fonts/Nunito/XRXV3I6Li01BKofINeaE.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: 'Nunito'; font-family: 'Nunito';
font-style: normal; font-style: normal;
font-weight: 600; font-weight: 600;
src: url('../../fonts/Nunito/XRXW3I6Li01BKofA6sKUYevN.ttf') format('truetype'); src: url('$(res)/fonts/Nunito/XRXW3I6Li01BKofA6sKUYevN.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: 'Nunito'; font-family: 'Nunito';
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
src: url('../../fonts/Nunito/XRXW3I6Li01BKofAjsOUYevN.ttf') format('truetype'); src: url('$(res)/fonts/Nunito/XRXW3I6Li01BKofAjsOUYevN.ttf') format('truetype');
} }
/* /*
@ -51,14 +51,14 @@
@font-face { @font-face {
font-family: 'Fira Mono'; font-family: 'Fira Mono';
src: url('../../fonts/Fira_Mono/FiraMono-Regular.ttf') format('truetype'); src: url('$(res)/fonts/Fira_Mono/FiraMono-Regular.ttf') format('truetype');
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: 'Fira Mono'; font-family: 'Fira Mono';
src: url('../../fonts/Fira_Mono/FiraMono-Bold.ttf') format('truetype'); src: url('$(res)/fonts/Fira_Mono/FiraMono-Bold.ttf') format('truetype');
font-weight: 700; font-weight: 700;
font-style: normal; font-style: normal;
} }

View File

@ -1,3 +1,4 @@
@import "../../light/css/_paths.scss";
@import "_fonts.scss";
@import "_dharma.scss"; @import "_dharma.scss";
@import "../../../../res/css/_components.scss"; @import "../../../../res/css/_components.scss";

View File

@ -1,5 +1,3 @@
@import "_fonts.scss";
/* Open Sans lacks combining diacritics, so these will fall through /* Open Sans lacks combining diacritics, so these will fall through
to the next font. Helevetica's diacritics however do not combine to the next font. Helevetica's diacritics however do not combine
nicely with Open Sans (on OSX, at least) and result in a huge nicely with Open Sans (on OSX, at least) and result in a huge
@ -162,8 +160,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

View File

@ -7,42 +7,42 @@
*/ */
@font-face { @font-face {
font-family: 'Open Sans'; font-family: 'Open Sans';
src: url('../../fonts/Open_Sans/OpenSans-Regular.ttf') format('truetype'); src: url('$(res)/fonts/Open_Sans/OpenSans-Regular.ttf') format('truetype');
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: 'Open Sans'; font-family: 'Open Sans';
src: url('../../fonts/Open_Sans/OpenSans-Italic.ttf') format('truetype'); src: url('$(res)/fonts/Open_Sans/OpenSans-Italic.ttf') format('truetype');
font-weight: 400; font-weight: 400;
font-style: italic; font-style: italic;
} }
@font-face { @font-face {
font-family: 'Open Sans'; font-family: 'Open Sans';
src: url('../../fonts/Open_Sans/OpenSans-Semibold.ttf') format('truetype'); src: url('$(res)/fonts/Open_Sans/OpenSans-Semibold.ttf') format('truetype');
font-weight: 600; font-weight: 600;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: 'Open Sans'; font-family: 'Open Sans';
src: url('../../fonts/Open_Sans/OpenSans-SemiboldItalic.ttf') format('truetype'); src: url('$(res)/fonts/Open_Sans/OpenSans-SemiboldItalic.ttf') format('truetype');
font-weight: 600; font-weight: 600;
font-style: italic; font-style: italic;
} }
@font-face { @font-face {
font-family: 'Open Sans'; font-family: 'Open Sans';
src: url('../../fonts/Open_Sans/OpenSans-Bold.ttf') format('truetype'); src: url('$(res)/fonts/Open_Sans/OpenSans-Bold.ttf') format('truetype');
font-weight: 700; font-weight: 700;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: 'Open Sans'; font-family: 'Open Sans';
src: url('../../fonts/Open_Sans/OpenSans-BoldItalic.ttf') format('truetype'); src: url('$(res)/fonts/Open_Sans/OpenSans-BoldItalic.ttf') format('truetype');
font-weight: 700; font-weight: 700;
font-style: italic; font-style: italic;
} }
@ -54,14 +54,14 @@
@font-face { @font-face {
font-family: 'Fira Mono'; font-family: 'Fira Mono';
src: url('../../fonts/Fira_Mono/FiraMono-Regular.ttf') format('truetype'); src: url('$(res)/fonts/Fira_Mono/FiraMono-Regular.ttf') format('truetype');
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: 'Fira Mono'; font-family: 'Fira Mono';
src: url('../../fonts/Fira_Mono/FiraMono-Bold.ttf') format('truetype'); src: url('$(res)/fonts/Fira_Mono/FiraMono-Bold.ttf') format('truetype');
font-weight: 700; font-weight: 700;
font-style: normal; font-style: normal;
} }

View File

@ -0,0 +1,3 @@
// Path from root SCSS file (such as `light.scss`) to `res` dir in the source tree
// This value is overridden by external themes in `riot-web`.
$res: ../../..;

View File

@ -1,3 +1,4 @@
@import "_paths.scss";
@import "_fonts.scss";
@import "_base.scss"; @import "_base.scss";
@import "../../../../res/css/_components.scss"; @import "../../../../res/css/_components.scss";

View File

@ -56,6 +56,6 @@ module.exports = {
for (let i = 0; i < s.length; ++i) { for (let i = 0; i < s.length; ++i) {
total += s.charCodeAt(i); total += s.charCodeAt(i);
} }
return 'img/' + images[total % images.length] + '.png'; return require('../res/img/' + images[total % images.length] + '.png');
}, },
}; };

View File

@ -125,7 +125,7 @@ const CategoryRoomList = React.createClass({
(<AccessibleButton className="mx_GroupView_featuredThings_addButton" (<AccessibleButton className="mx_GroupView_featuredThings_addButton"
onClick={this.onAddRoomsToSummaryClicked} onClick={this.onAddRoomsToSummaryClicked}
> >
<TintableSvg src="img/icons-create-room.svg" width="64" height="64" /> <TintableSvg src={require("../../../res/img/icons-create-room.svg")} width="64" height="64" />
<div className="mx_GroupView_featuredThings_addButton_label"> <div className="mx_GroupView_featuredThings_addButton_label">
{ _t('Add a Room') } { _t('Add a Room') }
</div> </div>
@ -226,7 +226,7 @@ const FeaturedRoom = React.createClass({
const deleteButton = this.props.editing ? const deleteButton = this.props.editing ?
<img <img
className="mx_GroupView_featuredThing_deleteButton" className="mx_GroupView_featuredThing_deleteButton"
src="img/cancel-small.svg" src={require("../../../res/img/cancel-small.svg")}
width="14" width="14"
height="14" height="14"
alt="Delete" alt="Delete"
@ -300,7 +300,7 @@ const RoleUserList = React.createClass({
const TintableSvg = sdk.getComponent("elements.TintableSvg"); const TintableSvg = sdk.getComponent("elements.TintableSvg");
const addButton = this.props.editing ? const addButton = this.props.editing ?
(<AccessibleButton className="mx_GroupView_featuredThings_addButton" onClick={this.onAddUsersClicked}> (<AccessibleButton className="mx_GroupView_featuredThings_addButton" onClick={this.onAddUsersClicked}>
<TintableSvg src="img/icons-create-room.svg" width="64" height="64" /> <TintableSvg src={require("../../../res/img/icons-create-room.svg")} width="64" height="64" />
<div className="mx_GroupView_featuredThings_addButton_label"> <div className="mx_GroupView_featuredThings_addButton_label">
{ _t('Add a User') } { _t('Add a User') }
</div> </div>
@ -379,7 +379,7 @@ const FeaturedUser = React.createClass({
const deleteButton = this.props.editing ? const deleteButton = this.props.editing ?
<img <img
className="mx_GroupView_featuredThing_deleteButton" className="mx_GroupView_featuredThing_deleteButton"
src="img/cancel-small.svg" src={require("../../../res/img/cancel-small.svg")}
width="14" width="14"
height="14" height="14"
alt="Delete" alt="Delete"
@ -855,7 +855,7 @@ export default React.createClass({
onClick={this._onAddRoomsClick} onClick={this._onAddRoomsClick}
> >
<div className="mx_GroupView_rooms_header_addRow_button"> <div className="mx_GroupView_rooms_header_addRow_button">
<TintableSvg src="img/icons-room-add.svg" width="24" height="24" /> <TintableSvg src={require("../../../res/img/icons-room-add.svg")} width="24" height="24" />
</div> </div>
<div className="mx_GroupView_rooms_header_addRow_label"> <div className="mx_GroupView_rooms_header_addRow_label">
{ _t('Add rooms to this community') } { _t('Add rooms to this community') }
@ -1189,7 +1189,7 @@ export default React.createClass({
</label> </label>
<div className="mx_GroupView_avatarPicker_edit"> <div className="mx_GroupView_avatarPicker_edit">
<label htmlFor="avatarInput" className="mx_GroupView_avatarPicker_label"> <label htmlFor="avatarInput" className="mx_GroupView_avatarPicker_label">
<img src="img/camera.svg" <img src={require("../../../res/img/camera.svg")}
alt={_t("Upload avatar")} title={_t("Upload avatar")} alt={_t("Upload avatar")} title={_t("Upload avatar")}
width="17" height="15" /> width="17" height="15" />
</label> </label>
@ -1255,7 +1255,7 @@ export default React.createClass({
); );
rightButtons.push( rightButtons.push(
<AccessibleButton className="mx_RoomHeader_cancelButton" onClick={this._onCancelClick} key="_cancelButton"> <AccessibleButton className="mx_RoomHeader_cancelButton" onClick={this._onCancelClick} key="_cancelButton">
<img src="img/cancel.svg" className="mx_filterFlipColor" <img src={require("../../../res/img/cancel.svg")} className="mx_filterFlipColor"
width="18" height="18" alt={_t("Cancel")} /> width="18" height="18" alt={_t("Cancel")} />
</AccessibleButton>, </AccessibleButton>,
); );
@ -1265,13 +1265,13 @@ export default React.createClass({
<AccessibleButton className="mx_GroupHeader_button" <AccessibleButton className="mx_GroupHeader_button"
onClick={this._onEditClick} title={_t("Community Settings")} key="_editButton" onClick={this._onEditClick} title={_t("Community Settings")} key="_editButton"
> >
<TintableSvg src="img/icons-settings-room.svg" width="16" height="16" /> <TintableSvg src={require("../../../res/img/icons-settings-room.svg")} width="16" height="16" />
</AccessibleButton>, </AccessibleButton>,
); );
} }
rightButtons.push( rightButtons.push(
<AccessibleButton className="mx_GroupHeader_button" onClick={this._onShareClick} title={_t('Share Community')} key="_shareButton"> <AccessibleButton className="mx_GroupHeader_button" onClick={this._onShareClick} title={_t('Share Community')} key="_shareButton">
<TintableSvg src="img/icons-share.svg" width="16" height="16" /> <TintableSvg src={require("../../../res/img/icons-share.svg")} width="16" height="16" />
</AccessibleButton>, </AccessibleButton>,
); );
} }

View File

@ -108,7 +108,7 @@ class HomePage extends React.Component {
if (this.context.matrixClient.isGuest()) { if (this.context.matrixClient.isGuest()) {
guestWarning = ( guestWarning = (
<div className="mx_HomePage_guest_warning"> <div className="mx_HomePage_guest_warning">
<img src="img/warning.svg" width="24" height="23" /> <img src={require("../../../res/img/warning.svg")} width="24" height="23" />
<div> <div>
<div> <div>
{ _t("You are currently using Riot anonymously as a guest.") } { _t("You are currently using Riot anonymously as a guest.") }

View File

@ -66,7 +66,11 @@ export default class IndicatorScrollbar extends React.Component {
} }
render() { render() {
return (<AutoHideScrollbar ref={this._collectScrollerComponent} wrappedRef={this._collectScroller} {... this.props}> return (<AutoHideScrollbar
ref={this._collectScrollerComponent}
wrappedRef={this._collectScroller}
{... this.props}
>
{ this.props.children } { this.props.children }
</AutoHideScrollbar>); </AutoHideScrollbar>);
} }

View File

@ -302,7 +302,10 @@ export default React.createClass({
// will check their settings. // will check their settings.
this.setState({ this.setState({
defaultServerName: null, // To un-hide any secrets people might be keeping defaultServerName: null, // To un-hide any secrets people might be keeping
defaultServerDiscoveryError: _t("Invalid configuration: Cannot supply a default homeserver URL and a default server name"), defaultServerDiscoveryError: _t(
"Invalid configuration: Cannot supply a default homeserver URL and " +
"a default server name",
),
}); });
} }
@ -1833,7 +1836,11 @@ export default React.createClass({
render: function() { render: function() {
// console.log(`Rendering MatrixChat with view ${this.state.view}`); // console.log(`Rendering MatrixChat with view ${this.state.view}`);
if (this.state.view === VIEWS.LOADING || this.state.view === VIEWS.LOGGING_IN || this.state.loadingDefaultHomeserver) { if (
this.state.view === VIEWS.LOADING ||
this.state.view === VIEWS.LOGGING_IN ||
this.state.loadingDefaultHomeserver
) {
const Spinner = sdk.getComponent('elements.Spinner'); const Spinner = sdk.getComponent('elements.Spinner');
return ( return (
<div className="mx_MatrixChat_splash"> <div className="mx_MatrixChat_splash">

View File

@ -107,7 +107,7 @@ export default withMatrixClient(React.createClass({
} }
return <div className="mx_MyGroups"> return <div className="mx_MyGroups">
<SimpleRoomHeader title={_t("Communities")} icon="img/icons-groups.svg" /> <SimpleRoomHeader title={_t("Communities")} icon={require("../../../res/img/icons-groups.svg")} />
<div className='mx_MyGroups_header'> <div className='mx_MyGroups_header'>
<div className="mx_MyGroups_headerCard"> <div className="mx_MyGroups_headerCard">
<AccessibleButton className='mx_MyGroups_headerCard_button' onClick={this._onCreateGroupClick}> <AccessibleButton className='mx_MyGroups_headerCard_button' onClick={this._onCreateGroupClick}>
@ -124,7 +124,7 @@ export default withMatrixClient(React.createClass({
</div> </div>
{/*<div className="mx_MyGroups_joinBox mx_MyGroups_headerCard"> {/*<div className="mx_MyGroups_joinBox mx_MyGroups_headerCard">
<AccessibleButton className='mx_MyGroups_headerCard_button' onClick={this._onJoinGroupClick}> <AccessibleButton className='mx_MyGroups_headerCard_button' onClick={this._onJoinGroupClick}>
<TintableSvg src="img/icons-create-room.svg" width="50" height="50" /> <TintableSvg src={require("../../../res/img/icons-create-room.svg")} width="50" height="50" />
</AccessibleButton> </AccessibleButton>
<div className="mx_MyGroups_headerCard_content"> <div className="mx_MyGroups_headerCard_content">
<div className="mx_MyGroups_headerCard_header"> <div className="mx_MyGroups_headerCard_header">

View File

@ -571,7 +571,7 @@ module.exports = React.createClass({
const DirectorySearchBox = sdk.getComponent('elements.DirectorySearchBox'); const DirectorySearchBox = sdk.getComponent('elements.DirectorySearchBox');
return ( return (
<div className="mx_RoomDirectory"> <div className="mx_RoomDirectory">
<SimpleRoomHeader title={ _t('Directory') } icon="img/icons-directory.svg" /> <SimpleRoomHeader title={ _t('Directory') } icon={require("../../../res/img/icons-directory.svg")} />
<div className="mx_RoomDirectory_list"> <div className="mx_RoomDirectory_list">
<div className="mx_RoomDirectory_listheader"> <div className="mx_RoomDirectory_listheader">
<DirectorySearchBox <DirectorySearchBox

View File

@ -198,7 +198,7 @@ module.exports = React.createClass({
return ( return (
<div className="mx_RoomStatusBar_scrollDownIndicator" <div className="mx_RoomStatusBar_scrollDownIndicator"
onClick={this.props.onScrollToBottomClick}> onClick={this.props.onScrollToBottomClick}>
<img src="img/newmessages.svg" width="24" height="24" <img src={require("../../../res/img/newmessages.svg")} width="24" height="24"
alt="" /> alt="" />
</div> </div>
); );
@ -209,7 +209,7 @@ module.exports = React.createClass({
return ( return (
<AccessibleButton className="mx_RoomStatusBar_scrollDownIndicator" <AccessibleButton className="mx_RoomStatusBar_scrollDownIndicator"
onClick={this.props.onScrollToBottomClick}> onClick={this.props.onScrollToBottomClick}>
<img src="img/scrolldown.svg" width="24" height="24" <img src={require("../../../res/img/scrolldown.svg")} width="24" height="24"
alt={_t("Scroll to bottom of page")} alt={_t("Scroll to bottom of page")}
title={_t("Scroll to bottom of page")} /> title={_t("Scroll to bottom of page")} />
</AccessibleButton> </AccessibleButton>
@ -219,7 +219,7 @@ module.exports = React.createClass({
if (this.props.hasActiveCall) { if (this.props.hasActiveCall) {
const TintableSvg = sdk.getComponent("elements.TintableSvg"); const TintableSvg = sdk.getComponent("elements.TintableSvg");
return ( return (
<TintableSvg src="img/sound-indicator.svg" width="23" height="20" /> <TintableSvg src={require("../../../res/img/sound-indicator.svg")} width="23" height="20" />
); );
} }
@ -327,7 +327,7 @@ module.exports = React.createClass({
} }
return <div className="mx_RoomStatusBar_connectionLostBar"> return <div className="mx_RoomStatusBar_connectionLostBar">
<img src="img/warning.svg" width="24" height="23" title={_t("Warning")} alt="" /> <img src={require("../../../res/img/warning.svg")} width="24" height="23" title={_t("Warning")} alt="" />
<div> <div>
<div className="mx_RoomStatusBar_connectionLostBar_title"> <div className="mx_RoomStatusBar_connectionLostBar_title">
{ title } { title }
@ -346,7 +346,7 @@ module.exports = React.createClass({
if (this._shouldShowConnectionError()) { if (this._shouldShowConnectionError()) {
return ( return (
<div className="mx_RoomStatusBar_connectionLostBar"> <div className="mx_RoomStatusBar_connectionLostBar">
<img src="img/warning.svg" width="24" height="23" title="/!\ " alt="/!\ " /> <img src={require("../../../res/img/warning.svg")} width="24" height="23" title="/!\ " alt="/!\ " />
<div> <div>
<div className="mx_RoomStatusBar_connectionLostBar_title"> <div className="mx_RoomStatusBar_connectionLostBar_title">
{ _t('Connectivity to the server has been lost.') } { _t('Connectivity to the server has been lost.') }

View File

@ -1777,20 +1777,20 @@ module.exports = React.createClass({
if (call.type === "video") { if (call.type === "video") {
zoomButton = ( zoomButton = (
<div className="mx_RoomView_voipButton" onClick={this.onFullscreenClick} title={_t("Fill screen")}> <div className="mx_RoomView_voipButton" onClick={this.onFullscreenClick} title={_t("Fill screen")}>
<TintableSvg src="img/fullscreen.svg" width="29" height="22" style={{ marginTop: 1, marginRight: 4 }} /> <TintableSvg src={require("../../../res/img/fullscreen.svg")} width="29" height="22" style={{ marginTop: 1, marginRight: 4 }} />
</div> </div>
); );
videoMuteButton = videoMuteButton =
<div className="mx_RoomView_voipButton" onClick={this.onMuteVideoClick}> <div className="mx_RoomView_voipButton" onClick={this.onMuteVideoClick}>
<TintableSvg src={call.isLocalVideoMuted() ? "img/video-unmute.svg" : "img/video-mute.svg"} <TintableSvg src={call.isLocalVideoMuted() ? require("../../../res/img/video-unmute.svg") : require("../../../res/img/video-mute.svg")}
alt={call.isLocalVideoMuted() ? _t("Click to unmute video") : _t("Click to mute video")} alt={call.isLocalVideoMuted() ? _t("Click to unmute video") : _t("Click to mute video")}
width="31" height="27" /> width="31" height="27" />
</div>; </div>;
} }
voiceMuteButton = voiceMuteButton =
<div className="mx_RoomView_voipButton" onClick={this.onMuteAudioClick}> <div className="mx_RoomView_voipButton" onClick={this.onMuteAudioClick}>
<TintableSvg src={call.isMicrophoneMuted() ? "img/voice-unmute.svg" : "img/voice-mute.svg"} <TintableSvg src={call.isMicrophoneMuted() ? require("../../../res/img/voice-unmute.svg") : require("../../../res/img/voice-mute.svg")}
alt={call.isMicrophoneMuted() ? _t("Click to unmute audio") : _t("Click to mute audio")} alt={call.isMicrophoneMuted() ? _t("Click to unmute audio") : _t("Click to mute audio")}
width="21" height="26" /> width="21" height="26" />
</div>; </div>;
@ -1802,7 +1802,7 @@ module.exports = React.createClass({
{ videoMuteButton } { videoMuteButton }
{ zoomButton } { zoomButton }
{ statusBar } { statusBar }
<TintableSvg className="mx_RoomView_voipChevron" src="img/voip-chevron.svg" width="22" height="17" /> <TintableSvg className="mx_RoomView_voipChevron" src={require("../../../res/img/voip-chevron.svg")} width="22" height="17" />
</div>; </div>;
} }

View File

@ -136,7 +136,7 @@ const TagPanel = React.createClass({
let clearButton; let clearButton;
if (itemsSelected) { if (itemsSelected) {
clearButton = <AccessibleButton className="mx_TagPanel_clearButton" onClick={this.onClearFilterClick}> clearButton = <AccessibleButton className="mx_TagPanel_clearButton" onClick={this.onClearFilterClick}>
<TintableSvg src="img/icons-close.svg" width="24" height="24" <TintableSvg src={require("../../../res/img/icons-close.svg")} width="24" height="24"
alt={_t("Clear filter")} alt={_t("Clear filter")}
title={_t("Clear filter")} title={_t("Clear filter")}
/> />

View File

@ -89,7 +89,7 @@ export default class TopLeftMenuButton extends React.Component {
resizeMethod="crop" resizeMethod="crop"
/> />
{ nameElement } { nameElement }
<img className="mx_TopLeftMenuButton_chevron" src="img/topleft-chevron.svg" width="11" height="6" /> <img className="mx_TopLeftMenuButton_chevron" src={require("../../../res/img/topleft-chevron.svg")} width="11" height="6" />
</AccessibleButton> </AccessibleButton>
); );
} }

View File

@ -91,8 +91,8 @@ module.exports = React.createClass({displayName: 'UploadBar',
<div className="mx_UploadBar_uploadProgressOuter"> <div className="mx_UploadBar_uploadProgressOuter">
<div className="mx_UploadBar_uploadProgressInner" style={innerProgressStyle}></div> <div className="mx_UploadBar_uploadProgressInner" style={innerProgressStyle}></div>
</div> </div>
<img className="mx_UploadBar_uploadIcon mx_filterFlipColor" src="img/fileicon.png" width="17" height="22" /> <img className="mx_UploadBar_uploadIcon mx_filterFlipColor" src={require("../../../res/img/fileicon.png")} width="17" height="22" />
<img className="mx_UploadBar_uploadCancel mx_filterFlipColor" src="img/cancel.svg" width="18" height="18" <img className="mx_UploadBar_uploadCancel mx_filterFlipColor" src={require("../../../res/img/cancel.svg")} width="18" height="18"
onClick={function() { ContentMessages.cancelUpload(upload.promise); }} onClick={function() { ContentMessages.cancelUpload(upload.promise); }}
/> />
<div className="mx_UploadBar_uploadBytes"> <div className="mx_UploadBar_uploadBytes">

View File

@ -1227,7 +1227,7 @@ module.exports = React.createClass({
/> />
</div> </div>
<div className="mx_UserSettings_threepidButton mx_filterFlipColor"> <div className="mx_UserSettings_threepidButton mx_filterFlipColor">
<AccessibleButton element="img" src="img/cancel-small.svg" width="14" height="14" alt={_t("Remove")} <AccessibleButton element="img" src={require("../../../res/img/cancel-small.svg")} width="14" height="14" alt={_t("Remove")}
onClick={onRemoveClick} /> onClick={onRemoveClick} />
</div> </div>
</div> </div>
@ -1252,7 +1252,7 @@ module.exports = React.createClass({
onValueChanged={this._onAddEmailEditFinished} /> onValueChanged={this._onAddEmailEditFinished} />
</div> </div>
<div className="mx_UserSettings_threepidButton mx_filterFlipColor"> <div className="mx_UserSettings_threepidButton mx_filterFlipColor">
<AccessibleButton element="img" src="img/plus.svg" width="14" height="14" alt={_t("Add")} onClick={this._addEmail} /> <AccessibleButton element="img" src={require("../../../res/img/plus.svg")} width="14" height="14" alt={_t("Add")} onClick={this._addEmail} />
</div> </div>
</div> </div>
); );
@ -1322,7 +1322,7 @@ module.exports = React.createClass({
<div className="mx_UserSettings_avatarPicker"> <div className="mx_UserSettings_avatarPicker">
<AccessibleButton className="mx_UserSettings_avatarPicker_remove" onClick={this.onAvatarRemoveClick}> <AccessibleButton className="mx_UserSettings_avatarPicker_remove" onClick={this.onAvatarRemoveClick}>
<img src="img/cancel.svg" <img src={require("../../../res/img/cancel.svg")}
width="15" height="15" width="15" height="15"
className="mx_filterFlipColor" className="mx_filterFlipColor"
alt={_t("Remove avatar")} alt={_t("Remove avatar")}
@ -1334,7 +1334,7 @@ module.exports = React.createClass({
</div> </div>
<div className="mx_UserSettings_avatarPicker_edit"> <div className="mx_UserSettings_avatarPicker_edit">
<label htmlFor="avatarInput" ref="file_label"> <label htmlFor="avatarInput" ref="file_label">
<img src="img/camera.svg" className="mx_filterFlipColor" <img src={require("../../../res/img/camera.svg")} className="mx_filterFlipColor"
alt={_t("Upload avatar")} title={_t("Upload avatar")} alt={_t("Upload avatar")} title={_t("Upload avatar")}
width="17" height="15" /> width="17" height="15" />
</label> </label>

View File

@ -79,7 +79,7 @@ export default class GroupInviteTileContextMenu extends React.Component {
render() { render() {
return <div> return <div>
<div className="mx_RoomTileContextMenu_leave" onClick={this._onClickReject} > <div className="mx_RoomTileContextMenu_leave" onClick={this._onClickReject} >
<img className="mx_RoomTileContextMenu_tag_icon" src="img/icon_context_delete.svg" width="15" height="15" /> <img className="mx_RoomTileContextMenu_tag_icon" src={require("../../../../res/img/icon_context_delete.svg")} width="15" height="15" />
{ _t('Reject') } { _t('Reject') }
</div> </div>
</div>; </div>;

View File

@ -245,26 +245,26 @@ module.exports = React.createClass({
return ( return (
<div className="mx_RoomTileContextMenu"> <div className="mx_RoomTileContextMenu">
<div className="mx_RoomTileContextMenu_notif_picker" > <div className="mx_RoomTileContextMenu_notif_picker" >
<img src="img/notif-slider.svg" width="20" height="107" /> <img src={require("../../../../res/img/notif-slider.svg")} width="20" height="107" />
</div> </div>
<div className={alertMeClasses} onClick={this._onClickAlertMe} > <div className={alertMeClasses} onClick={this._onClickAlertMe} >
<img className="mx_RoomTileContextMenu_notif_activeIcon" src="img/notif-active.svg" width="12" height="12" /> <img className="mx_RoomTileContextMenu_notif_activeIcon" src={require("../../../../res/img/notif-active.svg")} width="12" height="12" />
<img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src="img/icon-context-mute-off-copy.svg" width="16" height="12" /> <img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src={require("../../../../res/img/icon-context-mute-off-copy.svg")} width="16" height="12" />
{ _t('All messages (noisy)') } { _t('All messages (noisy)') }
</div> </div>
<div className={allNotifsClasses} onClick={this._onClickAllNotifs} > <div className={allNotifsClasses} onClick={this._onClickAllNotifs} >
<img className="mx_RoomTileContextMenu_notif_activeIcon" src="img/notif-active.svg" width="12" height="12" /> <img className="mx_RoomTileContextMenu_notif_activeIcon" src={require("../../../../res/img/notif-active.svg")} width="12" height="12" />
<img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src="img/icon-context-mute-off.svg" width="16" height="12" /> <img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src={require("../../../../res/img/icon-context-mute-off.svg")} width="16" height="12" />
{ _t('All messages') } { _t('All messages') }
</div> </div>
<div className={mentionsClasses} onClick={this._onClickMentions} > <div className={mentionsClasses} onClick={this._onClickMentions} >
<img className="mx_RoomTileContextMenu_notif_activeIcon" src="img/notif-active.svg" width="12" height="12" /> <img className="mx_RoomTileContextMenu_notif_activeIcon" src={require("../../../../res/img/notif-active.svg")} width="12" height="12" />
<img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src="img/icon-context-mute-mentions.svg" width="16" height="12" /> <img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src={require("../../../../res/img/icon-context-mute-mentions.svg")} width="16" height="12" />
{ _t('Mentions only') } { _t('Mentions only') }
</div> </div>
<div className={muteNotifsClasses} onClick={this._onClickMute} > <div className={muteNotifsClasses} onClick={this._onClickMute} >
<img className="mx_RoomTileContextMenu_notif_activeIcon" src="img/notif-active.svg" width="12" height="12" /> <img className="mx_RoomTileContextMenu_notif_activeIcon" src={require("../../../../res/img/notif-active.svg")} width="12" height="12" />
<img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src="img/icon-context-mute.svg" width="16" height="12" /> <img className="mx_RoomTileContextMenu_notif_icon mx_filterFlipColor" src={require("../../../../res/img/icon-context-mute.svg")} width="16" height="12" />
{ _t('Mute') } { _t('Mute') }
</div> </div>
</div> </div>
@ -298,7 +298,7 @@ module.exports = React.createClass({
return ( return (
<div> <div>
<div className="mx_RoomTileContextMenu_leave" onClick={leaveClickHandler} > <div className="mx_RoomTileContextMenu_leave" onClick={leaveClickHandler} >
<img className="mx_RoomTileContextMenu_tag_icon" src="img/icon_context_delete.svg" width="15" height="15" /> <img className="mx_RoomTileContextMenu_tag_icon" src={require("../../../../res/img/icon_context_delete.svg")} width="15" height="15" />
{ leaveText } { leaveText }
</div> </div>
</div> </div>
@ -327,18 +327,18 @@ module.exports = React.createClass({
return ( return (
<div> <div>
<div className={favouriteClasses} onClick={this._onClickFavourite} > <div className={favouriteClasses} onClick={this._onClickFavourite} >
<img className="mx_RoomTileContextMenu_tag_icon" src="img/icon_context_fave.svg" width="15" height="15" /> <img className="mx_RoomTileContextMenu_tag_icon" src={require("../../../../res/img/icon_context_fave.svg")} width="15" height="15" />
<img className="mx_RoomTileContextMenu_tag_icon_set" src="img/icon_context_fave_on.svg" width="15" height="15" /> <img className="mx_RoomTileContextMenu_tag_icon_set" src={require("../../../../res/img/icon_context_fave_on.svg")} width="15" height="15" />
{ _t('Favourite') } { _t('Favourite') }
</div> </div>
<div className={lowPriorityClasses} onClick={this._onClickLowPriority} > <div className={lowPriorityClasses} onClick={this._onClickLowPriority} >
<img className="mx_RoomTileContextMenu_tag_icon" src="img/icon_context_low.svg" width="15" height="15" /> <img className="mx_RoomTileContextMenu_tag_icon" src={require("../../../../res/img/icon_context_low.svg")} width="15" height="15" />
<img className="mx_RoomTileContextMenu_tag_icon_set" src="img/icon_context_low_on.svg" width="15" height="15" /> <img className="mx_RoomTileContextMenu_tag_icon_set" src={require("../../../../res/img/icon_context_low_on.svg")} width="15" height="15" />
{ _t('Low Priority') } { _t('Low Priority') }
</div> </div>
<div className={dmClasses} onClick={this._onClickDM} > <div className={dmClasses} onClick={this._onClickDM} >
<img className="mx_RoomTileContextMenu_tag_icon" src="img/icon_context_person.svg" width="15" height="15" /> <img className="mx_RoomTileContextMenu_tag_icon" src={require("../../../../res/img/icon_context_person.svg")} width="15" height="15" />
<img className="mx_RoomTileContextMenu_tag_icon_set" src="img/icon_context_person_on.svg" width="15" height="15" /> <img className="mx_RoomTileContextMenu_tag_icon_set" src={require("../../../../res/img/icon_context_person_on.svg")} width="15" height="15" />
{ _t('Direct Chat') } { _t('Direct Chat') }
</div> </div>
</div> </div>

View File

@ -59,7 +59,7 @@ export default class TagTileContextMenu extends React.Component {
<div className="mx_TagTileContextMenu_item" onClick={this._onViewCommunityClick} > <div className="mx_TagTileContextMenu_item" onClick={this._onViewCommunityClick} >
<TintableSvg <TintableSvg
className="mx_TagTileContextMenu_item_icon" className="mx_TagTileContextMenu_item_icon"
src="img/icons-groups.svg" src={require("../../../../res/img/icons-groups.svg")}
width="15" width="15"
height="15" height="15"
/> />
@ -67,7 +67,7 @@ export default class TagTileContextMenu extends React.Component {
</div> </div>
<hr className="mx_TagTileContextMenu_separator" /> <hr className="mx_TagTileContextMenu_separator" />
<div className="mx_TagTileContextMenu_item" onClick={this._onRemoveClick} > <div className="mx_TagTileContextMenu_item" onClick={this._onRemoveClick} >
<img className="mx_TagTileContextMenu_item_icon" src="img/icon_context_delete.svg" width="15" height="15" /> <img className="mx_TagTileContextMenu_item_icon" src={require("../../../../res/img/icon_context_delete.svg")} width="15" height="15" />
{ _t('Remove') } { _t('Remove') }
</div> </div>
</div>; </div>;

View File

@ -111,7 +111,7 @@ export default React.createClass({
let cancelButton; let cancelButton;
if (this.props.hasCancel) { if (this.props.hasCancel) {
cancelButton = <AccessibleButton onClick={this._onCancelClick} className="mx_Dialog_cancelButton"> cancelButton = <AccessibleButton onClick={this._onCancelClick} className="mx_Dialog_cancelButton">
<TintableSvg src="img/icons-close-button.svg" width="35" height="35" /> <TintableSvg src={require("../../../../res/img/icons-close-button.svg")} width="35" height="35" />
</AccessibleButton>; </AccessibleButton>;
} }

View File

@ -127,7 +127,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
onClick={this.props.onNewDMClick} onClick={this.props.onNewDMClick}
> >
<div className="mx_RoomTile_avatar"> <div className="mx_RoomTile_avatar">
<img src="img/create-big.svg" width="26" height="26" /> <img src={require("../../../../res/img/create-big.svg")} width="26" height="26" />
</div> </div>
<div className={labelClasses}><i>{ _t("Start new chat") }</i></div> <div className={labelClasses}><i>{ _t("Start new chat") }</i></div>
</AccessibleButton>; </AccessibleButton>;

View File

@ -26,11 +26,11 @@ import * as ContextualMenu from "../../structures/ContextualMenu";
const socials = [ const socials = [
{ {
name: 'Facebook', name: 'Facebook',
img: 'img/social/facebook.png', img: require("../../../../res/img/social/facebook.png"),
url: (url) => `https://www.facebook.com/sharer/sharer.php?u=${url}`, url: (url) => `https://www.facebook.com/sharer/sharer.php?u=${url}`,
}, { }, {
name: 'Twitter', name: 'Twitter',
img: 'img/social/twitter-2.png', img: require("../../../../res/img/social/twitter-2.png"),
url: (url) => `https://twitter.com/home?status=${url}`, url: (url) => `https://twitter.com/home?status=${url}`,
}, /* // icon missing }, /* // icon missing
name: 'Google Plus', name: 'Google Plus',
@ -38,15 +38,15 @@ const socials = [
url: (url) => `https://plus.google.com/share?url=${url}`, url: (url) => `https://plus.google.com/share?url=${url}`,
},*/ { },*/ {
name: 'LinkedIn', name: 'LinkedIn',
img: 'img/social/linkedin.png', img: require("../../../../res/img/social/linkedin.png"),
url: (url) => `https://www.linkedin.com/shareArticle?mini=true&url=${url}`, url: (url) => `https://www.linkedin.com/shareArticle?mini=true&url=${url}`,
}, { }, {
name: 'Reddit', name: 'Reddit',
img: 'img/social/reddit.png', img: require("../../../../res/img/social/reddit.png"),
url: (url) => `http://www.reddit.com/submit?url=${url}`, url: (url) => `http://www.reddit.com/submit?url=${url}`,
}, { }, {
name: 'email', name: 'email',
img: 'img/social/email-1.png', img: require("../../../../res/img/social/email-1.png"),
url: (url) => `mailto:?body=${url}`, url: (url) => `mailto:?body=${url}`,
}, },
]; ];
@ -202,7 +202,7 @@ export default class ShareDialog extends React.Component {
<div className="mx_ShareDialog_split"> <div className="mx_ShareDialog_split">
<div className="mx_ShareDialog_qrcode_container"> <div className="mx_ShareDialog_qrcode_container">
<QRCode value={matrixToUrl} size={256} logoWidth={48} logo="img/matrix-m.svg" /> <QRCode value={matrixToUrl} size={256} logoWidth={48} logo={require("../../../../res/img/matrix-m.svg")} />
</div> </div>
<div className="mx_ShareDialog_social_container"> <div className="mx_ShareDialog_social_container">
{ {

View File

@ -18,7 +18,7 @@ import React from 'react';
import MatrixClientPeg from '../../../MatrixClientPeg'; import MatrixClientPeg from '../../../MatrixClientPeg';
import {instanceForInstanceId} from '../../../utils/DirectoryUtils'; import {instanceForInstanceId} from '../../../utils/DirectoryUtils';
const DEFAULT_ICON_URL = "img/network-matrix.svg"; const DEFAULT_ICON_URL = require("../../../../res/img/network-matrix.svg");
export default class NetworkDropdown extends React.Component { export default class NetworkDropdown extends React.Component {
constructor(props) { constructor(props) {
@ -191,7 +191,7 @@ export default class NetworkDropdown extends React.Component {
} else if (!instance) { } else if (!instance) {
key = server + '_all'; key = server + '_all';
name = 'Matrix'; name = 'Matrix';
icon = <img src="img/network-matrix.svg" />; icon = <img src={require("../../../../res/img/network-matrix.svg")} />;
span_class = 'mx_NetworkDropdown_menu_network'; span_class = 'mx_NetworkDropdown_menu_network';
} else { } else {
key = server + '_inst_' + instance.instance_id; key = server + '_inst_' + instance.instance_id;

View File

@ -150,7 +150,7 @@ export default React.createClass({
showAddress={this.props.showAddress} showAddress={this.props.showAddress}
justified={true} justified={true}
networkName="vector" networkName="vector"
networkUrl="img/search-icon-vector.svg" networkUrl={require("../../../../res/img/search-icon-vector.svg")}
/> />
</div>, </div>,
); );

View File

@ -54,7 +54,7 @@ export default React.createClass({
address.avatarMxc, 25, 25, 'crop', address.avatarMxc, 25, 25, 'crop',
)); ));
} else if (address.addressType === 'email') { } else if (address.addressType === 'email') {
imgUrls.push('img/icon-email-user.svg'); imgUrls.push(require("../../../../res/img/icon-email-user.svg"));
} }
// Removing networks for now as they're not really supported // Removing networks for now as they're not really supported
@ -141,7 +141,7 @@ export default React.createClass({
if (this.props.canDismiss) { if (this.props.canDismiss) {
dismiss = ( dismiss = (
<div className="mx_AddressTile_dismiss" onClick={this.props.onDismissed} > <div className="mx_AddressTile_dismiss" onClick={this.props.onDismissed} >
<TintableSvg src="img/icon-address-delete.svg" width="9" height="9" /> <TintableSvg src={require("../../../../res/img/icon-address-delete.svg")} width="9" height="9" />
</div> </div>
); );
} }

View File

@ -47,7 +47,7 @@ export default class AppPermission extends React.Component {
return ( return (
<div className='mx_AppPermissionWarning'> <div className='mx_AppPermissionWarning'>
<div className='mx_AppPermissionWarningImage'> <div className='mx_AppPermissionWarningImage'>
<img src='img/warning.svg' alt={_t('Warning!')} /> <img src={require("../../../../res/img/warning.svg")} alt={_t('Warning!')} />
</div> </div>
<div className='mx_AppPermissionWarningText'> <div className='mx_AppPermissionWarningText'>
<span className='mx_AppPermissionWarningTextLabel'>{ _t('Do you want to load widget from URL:') }</span> <span className='mx_AppPermissionWarningTextURL'>{ this.state.curlBase }</span> <span className='mx_AppPermissionWarningTextLabel'>{ _t('Do you want to load widget from URL:') }</span> <span className='mx_AppPermissionWarningTextURL'>{ this.state.curlBase }</span>

View File

@ -582,19 +582,21 @@ export default class AppTile extends React.Component {
// editing is done in scalar // editing is done in scalar
const showEditButton = Boolean(this._scalarClient && this._canUserModify()); const showEditButton = Boolean(this._scalarClient && this._canUserModify());
const deleteWidgetLabel = this._deleteWidgetLabel(); const deleteWidgetLabel = this._deleteWidgetLabel();
let deleteIcon = 'img/cancel_green.svg'; let deleteIcon = require("../../../../res/img/cancel_green.svg");
let deleteClasses = 'mx_AppTileMenuBarWidget'; let deleteClasses = 'mx_AppTileMenuBarWidget';
if (this._canUserModify()) { if (this._canUserModify()) {
deleteIcon = 'img/icon-delete-pink.svg'; deleteIcon = require("../../../../res/img/icon-delete-pink.svg");
deleteClasses += ' mx_AppTileMenuBarWidgetDelete'; deleteClasses += ' mx_AppTileMenuBarWidgetDelete';
} }
// Picture snapshot - only show button when apps are maximised. // Picture snapshot - only show button when apps are maximised.
const showPictureSnapshotButton = this._hasCapability('m.capability.screenshot') && this.props.show; const showPictureSnapshotButton = this._hasCapability('m.capability.screenshot') && this.props.show;
const showPictureSnapshotIcon = 'img/camera_green.svg'; const showPictureSnapshotIcon = require("../../../../res/img/camera_green.svg");
const popoutWidgetIcon = 'img/button-new-window.svg'; const popoutWidgetIcon = require("../../../../res/img/button-new-window.svg");
const reloadWidgetIcon = 'img/button-refresh.svg'; const reloadWidgetIcon = require("../../../../res/img/button-refresh.svg");
const windowStateIcon = (this.props.show ? 'img/minimize.svg' : 'img/maximize.svg'); const minimizeIcon = require("../../../../res/img/minimize.svg");
const maximizeIcon = require("../../../../res/img/maximize.svg");
const windowStateIcon = (this.props.show ? minimizeIcon : maximizeIcon);
let appTileClass; let appTileClass;
if (this.props.miniMode) { if (this.props.miniMode) {
@ -653,7 +655,7 @@ export default class AppTile extends React.Component {
{ /* Edit widget */ } { /* Edit widget */ }
{ showEditButton && <TintableSvgButton { showEditButton && <TintableSvgButton
src="img/edit_green.svg" src={require("../../../../res/img/edit_green.svg")}
className={"mx_AppTileMenuBarWidget " + className={"mx_AppTileMenuBarWidget " +
(this.props.showDelete ? "mx_AppTileMenuBarWidgetPadding" : "")} (this.props.showDelete ? "mx_AppTileMenuBarWidgetPadding" : "")}
title={_t('Edit')} title={_t('Edit')}

View File

@ -5,7 +5,7 @@ const AppWarning = (props) => {
return ( return (
<div className='mx_AppPermissionWarning'> <div className='mx_AppPermissionWarning'>
<div className='mx_AppPermissionWarningImage'> <div className='mx_AppPermissionWarningImage'>
<img src='img/warning.svg' alt='' /> <img src={require("../../../../res/img/warning.svg")} alt='' />
</div> </div>
<div className='mx_AppPermissionWarningText'> <div className='mx_AppPermissionWarningText'>
<span className='mx_AppPermissionWarningTextLabel'>{ props.errorMsg }</span> <span className='mx_AppPermissionWarningTextLabel'>{ props.errorMsg }</span>

View File

@ -25,7 +25,7 @@ const CreateRoomButton = function(props) {
<ActionButton action="view_create_room" <ActionButton action="view_create_room"
mouseOverAction={props.callout ? "callout_create_room" : null} mouseOverAction={props.callout ? "callout_create_room" : null}
label={_t("Create new room")} label={_t("Create new room")}
iconPath="img/icons-create-room.svg" iconPath={require("../../../../res/img/icons-create-room.svg")}
size={props.size} size={props.size}
tooltip={props.tooltip} tooltip={props.tooltip}
/> />

View File

@ -62,13 +62,13 @@ const EditableItem = React.createClass({
{ this.props.onAdd ? { this.props.onAdd ?
<div className="mx_EditableItem_addButton"> <div className="mx_EditableItem_addButton">
<img className="mx_filterFlipColor" <img className="mx_filterFlipColor"
src="img/plus.svg" width="14" height="14" src={require("../../../../res/img/plus.svg")} width="14" height="14"
alt={_t("Add")} onClick={this.onAdd} /> alt={_t("Add")} onClick={this.onAdd} />
</div> </div>
: :
<div className="mx_EditableItem_removeButton"> <div className="mx_EditableItem_removeButton">
<img className="mx_filterFlipColor" <img className="mx_filterFlipColor"
src="img/cancel-small.svg" width="14" height="14" src={require("../../../../res/img/cancel-small.svg")} width="14" height="14"
alt={_t("Delete")} onClick={this.onRemove} /> alt={_t("Delete")} onClick={this.onRemove} />
</div> </div>
} }

View File

@ -24,7 +24,7 @@ const HomeButton = function(props) {
return ( return (
<ActionButton action="view_home_page" <ActionButton action="view_home_page"
label={_t("Home")} label={_t("Home")}
iconPath="img/icons-home.svg" iconPath={require("../../../../res/img/icons-home.svg")}
size={props.size} size={props.size}
tooltip={props.tooltip} tooltip={props.tooltip}
/> />

View File

@ -176,7 +176,7 @@ module.exports = React.createClass({
<img src={this.props.src} style={style} /> <img src={this.props.src} style={style} />
<div className="mx_ImageView_labelWrapper"> <div className="mx_ImageView_labelWrapper">
<div className="mx_ImageView_label"> <div className="mx_ImageView_label">
<AccessibleButton className="mx_ImageView_cancel" onClick={ this.props.onFinished }><img src="img/cancel-white.svg" width="18" height="18" alt={ _t('Close') } /></AccessibleButton> <AccessibleButton className="mx_ImageView_cancel" onClick={ this.props.onFinished }><img src={require("../../../../res/img/cancel-white.svg")} width="18" height="18" alt={ _t('Close') } /></AccessibleButton>
<div className="mx_ImageView_shim"> <div className="mx_ImageView_shim">
</div> </div>
<div className="mx_ImageView_name"> <div className="mx_ImageView_name">

View File

@ -26,7 +26,7 @@ module.exports = React.createClass({
return ( return (
<div className="mx_InlineSpinner"> <div className="mx_InlineSpinner">
<img src="img/spinner.gif" width={w} height={h} className={imgClass} /> <img src={require("../../../../res/img/spinner.gif")} width={w} height={h} className={imgClass} />
</div> </div>
); );
}, },

View File

@ -80,7 +80,11 @@ export default class ManageIntegsButton extends React.Component {
}); });
if (this.state.scalarError && !this.scalarClient.hasCredentials()) { if (this.state.scalarError && !this.scalarClient.hasCredentials()) {
integrationsWarningTriangle = <img src="img/warning.svg" title={_t('Integrations Error')} width="17" />; integrationsWarningTriangle = <img
src={require("../../../../res/img/warning.svg")}
title={_t('Integrations Error')}
width="17"
/>;
// Popup shown when hovering over integrationsButton_error (via CSS) // Popup shown when hovering over integrationsButton_error (via CSS)
integrationsErrorPopup = ( integrationsErrorPopup = (
<span className="mx_RoomSettings_integrationsButton_errorPopup"> <span className="mx_RoomSettings_integrationsButton_errorPopup">
@ -91,7 +95,7 @@ export default class ManageIntegsButton extends React.Component {
integrationsButton = ( integrationsButton = (
<AccessibleButton className={integrationsButtonClasses} onClick={this.onManageIntegrations} title={_t('Manage Integrations')}> <AccessibleButton className={integrationsButtonClasses} onClick={this.onManageIntegrations} title={_t('Manage Integrations')}>
<TintableSvg src="img/feather-icons/grid.svg" width="20" height="20" /> <TintableSvg src={require("../../../../res/img/feather-icons/grid.svg")} width="20" height="20" />
{ integrationsWarningTriangle } { integrationsWarningTriangle }
{ integrationsErrorPopup } { integrationsErrorPopup }
</AccessibleButton> </AccessibleButton>

View File

@ -27,7 +27,7 @@ module.exports = React.createClass({
return ( return (
<div className="mx_Spinner"> <div className="mx_Spinner">
<div className="mx_Spinner_Msg">{ msg }</div>&nbsp; <div className="mx_Spinner_Msg">{ msg }</div>&nbsp;
<img src="img/spinner.gif" width={w} height={h} className={imgClass} /> <img src={require("../../../../res/img/spinner.gif")} width={w} height={h} className={imgClass} />
</div> </div>
); );
}, },

View File

@ -25,7 +25,7 @@ const RoomDirectoryButton = function(props) {
<ActionButton action="view_room_directory" <ActionButton action="view_room_directory"
mouseOverAction={props.callout ? "callout_room_directory" : null} mouseOverAction={props.callout ? "callout_room_directory" : null}
label={_t("Room directory")} label={_t("Room directory")}
iconPath="img/icons-directory.svg" iconPath={require("../../../../res/img/icons-directory.svg")}
size={props.size} size={props.size}
tooltip={props.tooltip} tooltip={props.tooltip}
/> />

View File

@ -24,7 +24,7 @@ const SettingsButton = function(props) {
return ( return (
<ActionButton action="view_user_settings" <ActionButton action="view_user_settings"
label={_t("Settings")} label={_t("Settings")}
iconPath="img/icons-settings.svg" iconPath={require("../../../../res/img/icons-settings.svg")}
size={props.size} size={props.size}
tooltip={props.tooltip} tooltip={props.tooltip}
/> />

View File

@ -27,7 +27,7 @@ module.exports = React.createClass({
const imgClass = this.props.imgClassName || ""; const imgClass = this.props.imgClassName || "";
return ( return (
<div className="mx_Spinner"> <div className="mx_Spinner">
<img src="img/spinner.gif" width={w} height={h} className={imgClass} /> <img src={require("../../../../res/img/spinner.gif")} width={w} height={h} className={imgClass} />
</div> </div>
); );
}, },

View File

@ -25,7 +25,7 @@ const StartChatButton = function(props) {
<ActionButton action="view_create_chat" <ActionButton action="view_create_chat"
mouseOverAction={props.callout ? "callout_start_chat" : null} mouseOverAction={props.callout ? "callout_start_chat" : null}
label={_t("Start chat")} label={_t("Start chat")}
iconPath="img/icons-people.svg" iconPath={require("../../../../res/img/icons-people.svg")}
size={props.size} size={props.size}
tooltip={props.tooltip} tooltip={props.tooltip}
/> />

View File

@ -51,7 +51,7 @@ export default class CookieBar extends React.Component {
const toolbarClasses = "mx_MatrixToolbar"; const toolbarClasses = "mx_MatrixToolbar";
return ( return (
<div className={toolbarClasses}> <div className={toolbarClasses}>
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="" /> <img className="mx_MatrixToolbar_warning" src={require("../../../../res/img/warning.svg")} width="24" height="23" alt="" />
<div className="mx_MatrixToolbar_content"> <div className="mx_MatrixToolbar_content">
{ this.props.policyUrl ? _t( { this.props.policyUrl ? _t(
"Please help improve Riot.im by sending <UsageDataLink>anonymous usage data</UsageDataLink>. " + "Please help improve Riot.im by sending <UsageDataLink>anonymous usage data</UsageDataLink>. " +
@ -95,7 +95,7 @@ export default class CookieBar extends React.Component {
{ _t("Yes, I want to help!") } { _t("Yes, I want to help!") }
</AccessibleButton> </AccessibleButton>
<AccessibleButton className="mx_MatrixToolbar_close" onClick={this.onReject}> <AccessibleButton className="mx_MatrixToolbar_close" onClick={this.onReject}>
<img src="img/cancel.svg" width="18" height="18" alt={_t('Close')} /> <img src={require("../../../../res/img/cancel.svg")} width="18" height="18" alt={_t('Close')} />
</AccessibleButton> </AccessibleButton>
</div> </div>
); );

View File

@ -35,11 +35,11 @@ module.exports = React.createClass({
render: function() { render: function() {
return ( return (
<div className="mx_MatrixToolbar"> <div className="mx_MatrixToolbar">
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" /> <img className="mx_MatrixToolbar_warning" src={require("../../../../res/img/warning.svg")} width="24" height="23" />
<div className="mx_MatrixToolbar_content"> <div className="mx_MatrixToolbar_content">
{ _t('You are not receiving desktop notifications') } <a className="mx_MatrixToolbar_link" onClick={ this.onClick }> { _t('Enable them now') }</a> { _t('You are not receiving desktop notifications') } <a className="mx_MatrixToolbar_link" onClick={ this.onClick }> { _t('Enable them now') }</a>
</div> </div>
<AccessibleButton className="mx_MatrixToolbar_close" onClick={ this.hideToolbar } ><img src="img/cancel.svg" width="18" height="18" alt={_t('Close')} /></AccessibleButton> <AccessibleButton className="mx_MatrixToolbar_close" onClick={ this.hideToolbar } ><img src={require("../../../../res/img/cancel.svg")} width="18" height="18" alt={_t('Close')} /></AccessibleButton>
</div> </div>
); );
}, },

View File

@ -96,7 +96,7 @@ export default React.createClass({
} }
return ( return (
<div className="mx_MatrixToolbar"> <div className="mx_MatrixToolbar">
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" /> <img className="mx_MatrixToolbar_warning" src={require("../../../../res/img/warning.svg")} width="24" height="23" />
<div className="mx_MatrixToolbar_content"> <div className="mx_MatrixToolbar_content">
{_t("A new version of Riot is available.")} {_t("A new version of Riot is available.")}
</div> </div>

View File

@ -31,7 +31,7 @@ export default React.createClass({
return ( return (
<div className={toolbarClasses} onClick={this.onUpdateClicked}> <div className={toolbarClasses} onClick={this.onUpdateClicked}>
<img className="mx_MatrixToolbar_warning" <img className="mx_MatrixToolbar_warning"
src="img/warning.svg" src={require("../../../../res/img/warning.svg")}
width="24" width="24"
height="23" height="23"
alt="" alt=""

View File

@ -71,9 +71,9 @@ export default React.createClass({
let image; let image;
if (doneStatuses.includes(this.props.status)) { if (doneStatuses.includes(this.props.status)) {
image = <img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="" />; image = <img className="mx_MatrixToolbar_warning" src={require("../../../../res/img/warning.svg")} width="24" height="23" alt="" />;
} else { } else {
image = <img className="mx_MatrixToolbar_warning" src="img/spinner.gif" width="24" height="23" alt="" />; image = <img className="mx_MatrixToolbar_warning" src={require("../../../../res/img/spinner.gif")} width="24" height="23" alt="" />;
} }
return ( return (
@ -83,7 +83,7 @@ export default React.createClass({
{message} {message}
</div> </div>
<AccessibleButton className="mx_MatrixToolbar_close" onClick={this.hideToolbar}> <AccessibleButton className="mx_MatrixToolbar_close" onClick={this.hideToolbar}>
<img src="img/cancel.svg" width="18" height="18" alt={_t('Close')} /> <img src={require("../../../../res/img/cancel.svg")} width="18" height="18" alt={_t('Close')} />
</AccessibleButton> </AccessibleButton>
</div> </div>
); );

View File

@ -188,7 +188,7 @@ module.exports = React.createClass({
<div className="mx_MemberInfo"> <div className="mx_MemberInfo">
<GeminiScrollbarWrapper autoshow={true}> <GeminiScrollbarWrapper autoshow={true}>
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}> <AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
<img src="img/cancel.svg" width="18" height="18" className="mx_filterFlipColor" /> <img src={require("../../../../res/img/cancel.svg")} width="18" height="18" className="mx_filterFlipColor" />
</AccessibleButton> </AccessibleButton>
<div className="mx_MemberInfo_avatar"> <div className="mx_MemberInfo_avatar">
{ avatar } { avatar }

View File

@ -87,7 +87,7 @@ export default React.createClass({
const text = _t("and %(count)s others...", { count: overflowCount }); const text = _t("and %(count)s others...", { count: overflowCount });
return ( return (
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={ <EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
<BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} /> <BaseAvatar url={require("../../../../res/img/ellipsis.svg")} name="..." width={36} height={36} />
} name={text} presenceState="online" suppressOnHover={true} } name={text} presenceState="online" suppressOnHover={true}
onClick={this._showFullMemberList} /> onClick={this._showFullMemberList} />
); );
@ -214,7 +214,7 @@ export default React.createClass({
onClick={this.onInviteToGroupButtonClick} onClick={this.onInviteToGroupButtonClick}
> >
<div className="mx_RightPanel_icon" > <div className="mx_RightPanel_icon" >
<TintableSvg src="img/icon-invite-people.svg" width="18" height="14" /> <TintableSvg src={require("../../../../res/img/icon-invite-people.svg")} width="18" height="14" />
</div> </div>
<div className="mx_RightPanel_message">{ _t('Invite to this community') }</div> <div className="mx_RightPanel_message">{ _t('Invite to this community') }</div>
</AccessibleButton>); </AccessibleButton>);

View File

@ -215,7 +215,7 @@ module.exports = React.createClass({
<div className="mx_MemberInfo"> <div className="mx_MemberInfo">
<GeminiScrollbarWrapper autoshow={true}> <GeminiScrollbarWrapper autoshow={true}>
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}> <AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
<img src="img/cancel.svg" width="18" height="18" className="mx_filterFlipColor" /> <img src={require("../../../../res/img/cancel.svg")} width="18" height="18" className="mx_filterFlipColor" />
</AccessibleButton> </AccessibleButton>
<div className="mx_MemberInfo_avatar"> <div className="mx_MemberInfo_avatar">
{ avatar } { avatar }

View File

@ -77,7 +77,7 @@ export default React.createClass({
const text = _t("and %(count)s others...", { count: overflowCount }); const text = _t("and %(count)s others...", { count: overflowCount });
return ( return (
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={ <EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
<BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} /> <BaseAvatar url={require("../../../../res/img/ellipsis.svg")} name="..." width={36} height={36} />
} name={text} presenceState="online" suppressOnHover={true} } name={text} presenceState="online" suppressOnHover={true}
onClick={this._showFullRoomList} /> onClick={this._showFullRoomList} />
); );
@ -137,7 +137,7 @@ export default React.createClass({
onClick={this.onAddRoomToGroupButtonClick} onClick={this.onAddRoomToGroupButtonClick}
> >
<div className="mx_RightPanel_icon" > <div className="mx_RightPanel_icon" >
<TintableSvg src="img/icons-room-add.svg" width="18" height="14" /> <TintableSvg src={require("../../../../res/img/icons-room-add.svg")} width="18" height="14" />
</div> </div>
<div className="mx_RightPanel_message">{ _t('Add rooms to this community') }</div> <div className="mx_RightPanel_message">{ _t('Add rooms to this community') }</div>
</AccessibleButton> </AccessibleButton>

View File

@ -70,7 +70,7 @@ export default class CountryDropdown extends React.Component {
} }
_flagImgForIso2(iso2) { _flagImgForIso2(iso2) {
return <img src={`img/flags/${iso2}.png`} />; return <img src={require(`../../../../res/img/flags/${iso2}.png`)} />;
} }
_getShortOption(iso2) { _getShortOption(iso2) {

View File

@ -81,7 +81,7 @@ export default class MAudioBody extends React.Component {
if (this.state.error !== null) { if (this.state.error !== null) {
return ( return (
<span className="mx_MAudioBody" ref="body"> <span className="mx_MAudioBody" ref="body">
<img src="img/warning.svg" width="16" height="16" /> <img src={require("../../../../res/img/warning.svg")} width="16" height="16" />
{ _t("Error decrypting audio") } { _t("Error decrypting audio") }
</span> </span>
); );
@ -94,7 +94,7 @@ export default class MAudioBody extends React.Component {
// Not sure how tall the audio player is so not sure how tall it should actually be. // Not sure how tall the audio player is so not sure how tall it should actually be.
return ( return (
<span className="mx_MAudioBody"> <span className="mx_MAudioBody">
<img src="img/spinner.gif" alt={content.body} width="16" height="16" /> <img src={require("../../../../res/img/spinner.gif")} alt={content.body} width="16" height="16" />
</span> </span>
); );
} }

View File

@ -29,15 +29,15 @@ import request from 'browser-request';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
// A cached tinted copy of "img/download.svg" // A cached tinted copy of require("../../../../res/img/download.svg")
let tintedDownloadImageURL; let tintedDownloadImageURL;
// Track a list of mounted MFileBody instances so that we can update // Track a list of mounted MFileBody instances so that we can update
// the "img/download.svg" when the tint changes. // the require("../../../../res/img/download.svg") when the tint changes.
let nextMountId = 0; let nextMountId = 0;
const mounts = {}; const mounts = {};
/** /**
* Updates the tinted copy of "img/download.svg" when the tint changes. * Updates the tinted copy of require("../../../../res/img/download.svg") when the tint changes.
*/ */
function updateTintedDownloadImage() { function updateTintedDownloadImage() {
// Download the svg as an XML document. // Download the svg as an XML document.
@ -46,7 +46,7 @@ function updateTintedDownloadImage() {
// Also note that we can't use fetch here because fetch doesn't support // Also note that we can't use fetch here because fetch doesn't support
// file URLs, which the download image will be if we're running from // file URLs, which the download image will be if we're running from
// the filesystem (like in an Electron wrapper). // the filesystem (like in an Electron wrapper).
request({uri: "img/download.svg"}, (err, response, body) => { request({uri: require("../../../../res/img/download.svg")}, (err, response, body) => {
if (err) return; if (err) return;
const svg = new DOMParser().parseFromString(body, "image/svg+xml"); const svg = new DOMParser().parseFromString(body, "image/svg+xml");
@ -254,7 +254,7 @@ module.exports = React.createClass({
}, },
tint: function() { tint: function() {
// Update our tinted copy of "img/download.svg" // Update our tinted copy of require("../../../../res/img/download.svg")
if (this.refs.downloadImage) { if (this.refs.downloadImage) {
this.refs.downloadImage.src = tintedDownloadImageURL; this.refs.downloadImage.src = tintedDownloadImageURL;
} }

View File

@ -282,7 +282,12 @@ export default class MImageBody extends React.Component {
// e2e image hasn't been decrypted yet // e2e image hasn't been decrypted yet
if (content.file !== undefined && this.state.decryptedUrl === null) { if (content.file !== undefined && this.state.decryptedUrl === null) {
placeholder = <img src="img/spinner.gif" alt={content.body} width="32" height="32" />; placeholder = <img
src={require("../../../../res/img/spinner.gif")}
alt={content.body}
width="32"
height="32"
/>;
} else if (!this.state.imgLoaded) { } else if (!this.state.imgLoaded) {
// Deliberately, getSpinner is left unimplemented here, MStickerBody overides // Deliberately, getSpinner is left unimplemented here, MStickerBody overides
placeholder = this.getPlaceholder(); placeholder = this.getPlaceholder();
@ -363,7 +368,7 @@ export default class MImageBody extends React.Component {
if (this.state.error !== null) { if (this.state.error !== null) {
return ( return (
<span className="mx_MImageBody" ref="body"> <span className="mx_MImageBody" ref="body">
<img src="img/warning.svg" width="16" height="16" /> <img src={require("../../../../res/img/warning.svg")} width="16" height="16" />
{ _t("Error decrypting image") } { _t("Error decrypting image") }
</span> </span>
); );

View File

@ -35,7 +35,7 @@ export default class MStickerBody extends MImageBody {
// img onLoad hasn't fired yet. // img onLoad hasn't fired yet.
getPlaceholder() { getPlaceholder() {
const TintableSVG = sdk.getComponent('elements.TintableSvg'); const TintableSVG = sdk.getComponent('elements.TintableSvg');
return <TintableSVG src="img/icons-show-stickers.svg" width="75" height="75" />; return <TintableSVG src={require("../../../../res/img/icons-show-stickers.svg")} width="75" height="75" />;
} }
// Tooltip to show on mouse over // Tooltip to show on mouse over

View File

@ -135,7 +135,7 @@ module.exports = React.createClass({
if (this.state.error !== null) { if (this.state.error !== null) {
return ( return (
<span className="mx_MVideoBody" ref="body"> <span className="mx_MVideoBody" ref="body">
<img src="img/warning.svg" width="16" height="16" /> <img src={require("../../../../res/img/warning.svg")} width="16" height="16" />
{ _t("Error decrypting video") } { _t("Error decrypting video") }
</span> </span>
); );
@ -148,7 +148,7 @@ module.exports = React.createClass({
return ( return (
<span className="mx_MVideoBody" ref="body"> <span className="mx_MVideoBody" ref="body">
<div className="mx_MImageBody_thumbnail mx_MImageBody_thumbnail_spinner" ref="image"> <div className="mx_MImageBody_thumbnail mx_MImageBody_thumbnail_spinner" ref="image">
<img src="img/spinner.gif" alt={content.body} width="16" height="16" /> <img src={require("../../../../res/img/spinner.gif")} alt={content.body} width="16" height="16" />
</div> </div>
</span> </span>
); );

View File

@ -48,7 +48,7 @@ module.exports = React.createClass({
return <div />; // We should never have been instaniated in this case return <div />; // We should never have been instaniated in this case
} }
return <div className="mx_CreateEvent"> return <div className="mx_CreateEvent">
<img className="mx_CreateEvent_image" src="img/room-continuation.svg" /> <img className="mx_CreateEvent_image" src={require("../../../../res/img/room-continuation.svg")} />
<div className="mx_CreateEvent_header"> <div className="mx_CreateEvent_header">
{_t("This room is a continuation of another conversation.")} {_t("This room is a continuation of another conversation.")}
</div> </div>

View File

@ -65,12 +65,12 @@ export default class GroupHeaderButtons extends HeaderButtons {
]; ];
return [ return [
<HeaderButton key="_groupMembersButton" title={_t('Members')} iconSrc="img/icons-people.svg" <HeaderButton key="_groupMembersButton" title={_t('Members')} iconSrc={require("../../../../res/img/icons-people.svg")}
isHighlighted={this.isPhase(groupPhases)} isHighlighted={this.isPhase(groupPhases)}
clickPhase={RightPanel.Phase.GroupMemberList} clickPhase={RightPanel.Phase.GroupMemberList}
analytics={['Right Panel', 'Group Member List Button', 'click']} analytics={['Right Panel', 'Group Member List Button', 'click']}
/>, />,
<HeaderButton key="_roomsButton" title={_t('Rooms')} iconSrc="img/icons-room-nobg.svg" <HeaderButton key="_roomsButton" title={_t('Rooms')} iconSrc={require("../../../../res/img/icons-room-nobg.svg")}
isHighlighted={this.isPhase(roomPhases)} isHighlighted={this.isPhase(roomPhases)}
clickPhase={RightPanel.Phase.GroupRoomList} clickPhase={RightPanel.Phase.GroupRoomList}
analytics={['Right Panel', 'Group Room List Button', 'click']} analytics={['Right Panel', 'Group Room List Button', 'click']}

View File

@ -52,17 +52,17 @@ export default class RoomHeaderButtons extends HeaderButtons {
]; ];
return [ return [
<HeaderButton key="_membersButton" title={_t('Members')} iconSrc="img/feather-icons/user.svg" <HeaderButton key="_membersButton" title={_t('Members')} iconSrc={require("../../../../res/img/feather-icons/user.svg")}
isHighlighted={this.isPhase(membersPhases)} isHighlighted={this.isPhase(membersPhases)}
clickPhase={RightPanel.Phase.RoomMemberList} clickPhase={RightPanel.Phase.RoomMemberList}
analytics={['Right Panel', 'Member List Button', 'click']} analytics={['Right Panel', 'Member List Button', 'click']}
/>, />,
<HeaderButton key="_filesButton" title={_t('Files')} iconSrc="img/feather-icons/files.svg" <HeaderButton key="_filesButton" title={_t('Files')} iconSrc={require("../../../../res/img/feather-icons/files.svg")}
isHighlighted={this.isPhase(RightPanel.Phase.FilePanel)} isHighlighted={this.isPhase(RightPanel.Phase.FilePanel)}
clickPhase={RightPanel.Phase.FilePanel} clickPhase={RightPanel.Phase.FilePanel}
analytics={['Right Panel', 'File List Button', 'click']} analytics={['Right Panel', 'File List Button', 'click']}
/>, />,
<HeaderButton key="_notifsButton" title={_t('Notifications')} iconSrc="img/feather-icons/notifications.svg" <HeaderButton key="_notifsButton" title={_t('Notifications')} iconSrc={require("../../../../res/img/feather-icons/notifications.svg")}
isHighlighted={this.isPhase(RightPanel.Phase.NotificationPanel)} isHighlighted={this.isPhase(RightPanel.Phase.NotificationPanel)}
clickPhase={RightPanel.Phase.NotificationPanel} clickPhase={RightPanel.Phase.NotificationPanel}
analytics={['Right Panel', 'Notification List Button', 'click']} analytics={['Right Panel', 'Notification List Button', 'click']}

View File

@ -131,7 +131,7 @@ module.exports = React.createClass({
if (i === this.state.index) { if (i === this.state.index) {
selected = ( selected = (
<div className="mx_RoomSettings_roomColor_selected"> <div className="mx_RoomSettings_roomColor_selected">
<img src="img/tick.svg" width="17" height="14" alt="./" /> <img src={require("../../../../res/img/tick.svg")} width="17" height="14" alt="./" />
</div> </div>
); );
} }

View File

@ -147,7 +147,7 @@ module.exports = React.createClass({
<div className="mx_RoomView_fileDropTarget"> <div className="mx_RoomView_fileDropTarget">
<div className="mx_RoomView_fileDropTargetLabel" <div className="mx_RoomView_fileDropTargetLabel"
title={_t("Drop File Here")}> title={_t("Drop File Here")}>
<TintableSvg src="img/upload-big.svg" width="45" height="59" /> <TintableSvg src={require("../../../../res/img/upload-big.svg")} width="45" height="59" />
<br /> <br />
{ _t("Drop file here to upload") } { _t("Drop file here to upload") }
</div> </div>

View File

@ -160,7 +160,7 @@ const EntityTile = React.createClass({
if (this.props.showInviteButton) { if (this.props.showInviteButton) {
inviteButton = ( inviteButton = (
<div className="mx_EntityTile_invite"> <div className="mx_EntityTile_invite">
<img src="img/plus.svg" width="16" height="16" /> <img src={require("../../../../res/img/plus.svg")} width="16" height="16" />
</div> </div>
); );
} }
@ -169,8 +169,8 @@ const EntityTile = React.createClass({
const powerStatus = this.props.powerStatus; const powerStatus = this.props.powerStatus;
if (powerStatus) { if (powerStatus) {
const src = { const src = {
[EntityTile.POWER_STATUS_MODERATOR]: "img/mod.svg", [EntityTile.POWER_STATUS_MODERATOR]: require("../../../../res/img/mod.svg"),
[EntityTile.POWER_STATUS_ADMIN]: "img/admin.svg", [EntityTile.POWER_STATUS_ADMIN]: require("../../../../res/img/admin.svg"),
}[powerStatus]; }[powerStatus];
const alt = { const alt = {
[EntityTile.POWER_STATUS_MODERATOR]: _t("Moderator"), [EntityTile.POWER_STATUS_MODERATOR]: _t("Moderator"),

View File

@ -768,23 +768,31 @@ module.exports.haveTileForEvent = function(e) {
function E2ePadlockUndecryptable(props) { function E2ePadlockUndecryptable(props) {
return ( return (
<E2ePadlock alt={_t("Undecryptable")} <E2ePadlock alt={_t("Undecryptable")}
src="img/e2e-blocked.svg" width="12" height="12" src={require("../../../../res/img/e2e-blocked.svg")} width="12" height="12"
style={{ marginLeft: "-1px" }} {...props} /> style={{ marginLeft: "-1px" }} {...props} />
); );
} }
function E2ePadlockEncrypting(props) { function E2ePadlockEncrypting(props) {
return <E2ePadlock alt={_t("Encrypting")} src="img/e2e-encrypting.svg" width="10" height="12" {...props} />; return (
<E2ePadlock alt={_t("Encrypting")}
src={require("../../../../res/img/e2e-encrypting.svg")} width="10" height="12"
{...props} />
);
} }
function E2ePadlockNotSent(props) { function E2ePadlockNotSent(props) {
return <E2ePadlock alt={_t("Encrypted, not sent")} src="img/e2e-not_sent.svg" width="10" height="12" {...props} />; return (
<E2ePadlock alt={_t("Encrypted, not sent")}
src={require("../../../../res/img/e2e-not_sent.svg")} width="10" height="12"
{...props} />
);
} }
function E2ePadlockVerified(props) { function E2ePadlockVerified(props) {
return ( return (
<E2ePadlock alt={_t("Encrypted by a verified device")} <E2ePadlock alt={_t("Encrypted by a verified device")}
src="img/e2e-verified.svg" width="10" height="12" src={require("../../../../res/img/e2e-verified.svg")} width="10" height="12"
{...props} /> {...props} />
); );
} }
@ -792,7 +800,7 @@ function E2ePadlockVerified(props) {
function E2ePadlockUnverified(props) { function E2ePadlockUnverified(props) {
return ( return (
<E2ePadlock alt={_t("Encrypted by an unverified device")} <E2ePadlock alt={_t("Encrypted by an unverified device")}
src="img/e2e-warning.svg" width="15" height="12" src={require("../../../../res/img/e2e-warning.svg")} width="15" height="12"
style={{ marginLeft: "-2px" }} {...props} /> style={{ marginLeft: "-2px" }} {...props} />
); );
} }
@ -800,7 +808,7 @@ function E2ePadlockUnverified(props) {
function E2ePadlockUnencrypted(props) { function E2ePadlockUnencrypted(props) {
return ( return (
<E2ePadlock alt={_t("Unencrypted message")} <E2ePadlock alt={_t("Unencrypted message")}
src="img/e2e-unencrypted.svg" width="12" height="12" src={require("../../../../res/img/e2e-unencrypted.svg")} width="12" height="12"
{...props} /> {...props} />
); );
} }

View File

@ -135,7 +135,7 @@ module.exports = React.createClass({
</div> </div>
</div> </div>
<img className="mx_LinkPreviewWidget_cancel mx_filterFlipColor" <img className="mx_LinkPreviewWidget_cancel mx_filterFlipColor"
src="img/cancel.svg" width="18" height="18" src={require("../../../../res/img/cancel.svg")} width="18" height="18"
onClick={this.props.onCancelClick} /> onClick={this.props.onCancelClick} />
</div> </div>
); );

View File

@ -27,19 +27,19 @@ export default class MemberDeviceInfo extends React.Component {
if (this.props.device.isBlocked()) { if (this.props.device.isBlocked()) {
indicator = ( indicator = (
<div className="mx_MemberDeviceInfo_blacklisted"> <div className="mx_MemberDeviceInfo_blacklisted">
<img src="img/e2e-blocked.svg" width="12" height="12" style={{ marginLeft: "-1px" }} alt={_t("Blacklisted")} /> <img src={require("../../../../res/img/e2e-blocked.svg")} width="12" height="12" style={{ marginLeft: "-1px" }} alt={_t("Blacklisted")} />
</div> </div>
); );
} else if (this.props.device.isVerified()) { } else if (this.props.device.isVerified()) {
indicator = ( indicator = (
<div className="mx_MemberDeviceInfo_verified"> <div className="mx_MemberDeviceInfo_verified">
<img src="img/e2e-verified.svg" width="10" height="12" alt={_t("Verified")} /> <img src={require("../../../../res/img/e2e-verified.svg")} width="10" height="12" alt={_t("Verified")} />
</div> </div>
); );
} else { } else {
indicator = ( indicator = (
<div className="mx_MemberDeviceInfo_unverified"> <div className="mx_MemberDeviceInfo_unverified">
<img src="img/e2e-warning.svg" width="15" height="12" style={{ marginLeft: "-2px" }} alt={_t("Unverified")} /> <img src={require("../../../../res/img/e2e-warning.svg")} width="15" height="12" style={{ marginLeft: "-2px" }} alt={_t("Unverified")} />
</div> </div>
); );
} }

View File

@ -815,7 +815,7 @@ module.exports = withMatrixClient(React.createClass({
onClick={this.onNewDMClick} onClick={this.onNewDMClick}
> >
<div className="mx_RoomTile_avatar"> <div className="mx_RoomTile_avatar">
<img src="img/create-big.svg" width="26" height="26" /> <img src={require("../../../../res/img/create-big.svg")} width="26" height="26" />
</div> </div>
<div className={labelClasses}><i>{ _t("Start a chat") }</i></div> <div className={labelClasses}><i>{ _t("Start a chat") }</i></div>
</AccessibleButton>; </AccessibleButton>;
@ -963,7 +963,7 @@ module.exports = withMatrixClient(React.createClass({
<div className="mx_MemberInfo"> <div className="mx_MemberInfo">
<div className="mx_MemberInfo_name"> <div className="mx_MemberInfo_name">
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}> <AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}>
<img src="img/minimise.svg" width="10" height="16" className="mx_filterFlipColor" alt={_t('Close')} /> <img src={require("../../../../res/img/minimise.svg")} width="10" height="16" className="mx_filterFlipColor" alt={_t('Close')} />
</AccessibleButton> </AccessibleButton>
<EmojiText element="h2">{ memberName }</EmojiText> <EmojiText element="h2">{ memberName }</EmojiText>
</div> </div>

View File

@ -253,7 +253,7 @@ module.exports = React.createClass({
const text = _t("and %(count)s others...", { count: overflowCount }); const text = _t("and %(count)s others...", { count: overflowCount });
return ( return (
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={ <EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
<BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} /> <BaseAvatar url={require("../../../../res/img/ellipsis.svg")} name="..." width={36} height={36} />
} name={text} presenceState="online" suppressOnHover={true} } name={text} presenceState="online" suppressOnHover={true}
onClick={onClick} /> onClick={onClick} />
); );

View File

@ -155,12 +155,12 @@ export default class MessageComposer extends React.Component {
const fileAcceptedOrError = this.props.uploadAllowed(files[i]); const fileAcceptedOrError = this.props.uploadAllowed(files[i]);
if (fileAcceptedOrError === true) { if (fileAcceptedOrError === true) {
acceptedFiles.push(<li key={i}> acceptedFiles.push(<li key={i}>
<TintableSvg key={i} src="img/files.svg" width="16" height="16" /> { files[i].name || _t('Attachment') } <TintableSvg key={i} src={require("../../../../res/img/files.svg")} width="16" height="16" /> { files[i].name || _t('Attachment') }
</li>); </li>);
fileList.push(files[i]); fileList.push(files[i]);
} else { } else {
failedFiles.push(<li key={i}> failedFiles.push(<li key={i}>
<TintableSvg key={i} src="img/files.svg" width="16" height="16" /> { files[i].name || _t('Attachment') } <p>{ _t('Reason') + ": " + fileAcceptedOrError}</p> <TintableSvg key={i} src={require("../../../../res/img/files.svg")} width="16" height="16" /> { files[i].name || _t('Attachment') } <p>{ _t('Reason') + ": " + fileAcceptedOrError}</p>
</li>); </li>);
} }
} }
@ -320,11 +320,11 @@ export default class MessageComposer extends React.Component {
const roomIsEncrypted = MatrixClientPeg.get().isRoomEncrypted(this.props.room.roomId); const roomIsEncrypted = MatrixClientPeg.get().isRoomEncrypted(this.props.room.roomId);
if (roomIsEncrypted) { if (roomIsEncrypted) {
// FIXME: show a /!\ if there are untrusted devices in the room... // FIXME: show a /!\ if there are untrusted devices in the room...
e2eImg = 'img/e2e-verified.svg'; e2eImg = require("../../../../res/img/e2e-verified.svg");
e2eTitle = _t('Encrypted room'); e2eTitle = _t('Encrypted room');
e2eClass = 'mx_MessageComposer_e2eIcon'; e2eClass = 'mx_MessageComposer_e2eIcon';
} else { } else {
e2eImg = 'img/e2e-unencrypted.svg'; e2eImg = require("../../../../res/img/e2e-unencrypted.svg");
e2eTitle = _t('Unencrypted room'); e2eTitle = _t('Unencrypted room');
e2eClass = 'mx_MessageComposer_e2eIcon mx_filterFlipColor'; e2eClass = 'mx_MessageComposer_e2eIcon mx_filterFlipColor';
} }
@ -344,16 +344,16 @@ export default class MessageComposer extends React.Component {
if (this.props.callState && this.props.callState !== 'ended') { if (this.props.callState && this.props.callState !== 'ended') {
hangupButton = hangupButton =
<AccessibleButton key="controls_hangup" className="mx_MessageComposer_hangup" onClick={this.onHangupClick}> <AccessibleButton key="controls_hangup" className="mx_MessageComposer_hangup" onClick={this.onHangupClick}>
<img src="img/hangup.svg" alt={_t('Hangup')} title={_t('Hangup')} width="25" height="25" /> <img src={require("../../../../res/img/hangup.svg")} alt={_t('Hangup')} title={_t('Hangup')} width="25" height="25" />
</AccessibleButton>; </AccessibleButton>;
} else { } else {
callButton = callButton =
<AccessibleButton key="controls_call" className="mx_MessageComposer_voicecall" onClick={this.onVoiceCallClick} title={_t('Voice call')}> <AccessibleButton key="controls_call" className="mx_MessageComposer_voicecall" onClick={this.onVoiceCallClick} title={_t('Voice call')}>
<TintableSvg src="img/feather-icons/phone.svg" width="20" height="20" /> <TintableSvg src={require("../../../../res/img/feather-icons/phone.svg")} width="20" height="20" />
</AccessibleButton>; </AccessibleButton>;
videoCallButton = videoCallButton =
<AccessibleButton key="controls_videocall" className="mx_MessageComposer_videocall" onClick={this.onCallClick} title={_t('Video call')}> <AccessibleButton key="controls_videocall" className="mx_MessageComposer_videocall" onClick={this.onCallClick} title={_t('Video call')}>
<TintableSvg src="img/feather-icons/video.svg" width="20" height="20" /> <TintableSvg src={require("../../../../res/img/feather-icons/video.svg")} width="20" height="20" />
</AccessibleButton>; </AccessibleButton>;
} }
@ -395,7 +395,7 @@ export default class MessageComposer extends React.Component {
const uploadButton = ( const uploadButton = (
<AccessibleButton key="controls_upload" className="mx_MessageComposer_upload" <AccessibleButton key="controls_upload" className="mx_MessageComposer_upload"
onClick={this.onUploadClick} title={_t('Upload file')}> onClick={this.onUploadClick} title={_t('Upload file')}>
<TintableSvg src="img/feather-icons/paperclip.svg" width="20" height="20" /> <TintableSvg src={require("../../../../res/img/feather-icons/paperclip.svg")} width="20" height="20" />
<input ref="uploadInput" type="file" <input ref="uploadInput" type="file"
style={uploadInputStyle} style={uploadInputStyle}
multiple multiple
@ -407,7 +407,7 @@ export default class MessageComposer extends React.Component {
<AccessibleButton element="img" className="mx_MessageComposer_formatting" <AccessibleButton element="img" className="mx_MessageComposer_formatting"
alt={_t("Show Text Formatting Toolbar")} alt={_t("Show Text Formatting Toolbar")}
title={_t("Show Text Formatting Toolbar")} title={_t("Show Text Formatting Toolbar")}
src="img/button-text-formatting.svg" src={require("../../../../res/img/button-text-formatting.svg")}
onClick={this.onToggleFormattingClicked} onClick={this.onToggleFormattingClicked}
style={{visibility: this.state.showFormatting ? 'hidden' : 'visible'}} style={{visibility: this.state.showFormatting ? 'hidden' : 'visible'}}
key="controls_formatting" /> key="controls_formatting" />
@ -451,7 +451,7 @@ export default class MessageComposer extends React.Component {
controls.push(<div className="mx_MessageComposer_replaced_wrapper"> controls.push(<div className="mx_MessageComposer_replaced_wrapper">
<div className="mx_MessageComposer_replaced_valign"> <div className="mx_MessageComposer_replaced_valign">
<img className="mx_MessageComposer_roomReplaced_icon" src="img/room_replaced.svg" /> <img className="mx_MessageComposer_roomReplaced_icon" src={require("../../../../res/img/room_replaced.svg")} />
<span className="mx_MessageComposer_roomReplaced_header"> <span className="mx_MessageComposer_roomReplaced_header">
{_t("This room has been replaced and is no longer active.")} {_t("This room has been replaced and is no longer active.")}
</span><br /> </span><br />
@ -487,7 +487,7 @@ export default class MessageComposer extends React.Component {
title={_t(name)} title={_t(name)}
onMouseDown={onFormatButtonClicked} onMouseDown={onFormatButtonClicked}
key={name} key={name}
src={`img/button-text-${name}${suffix}.svg`} src={require(`../../../../res/img/button-text-${name}${suffix}.svg`)}
height="17" />; height="17" />;
}, },
); );
@ -500,11 +500,11 @@ export default class MessageComposer extends React.Component {
<img title={this.state.inputState.isRichTextEnabled ? _t("Turn Markdown on") : _t("Turn Markdown off")} <img title={this.state.inputState.isRichTextEnabled ? _t("Turn Markdown on") : _t("Turn Markdown off")}
onMouseDown={this.onToggleMarkdownClicked} onMouseDown={this.onToggleMarkdownClicked}
className="mx_MessageComposer_formatbar_markdown mx_filterFlipColor" className="mx_MessageComposer_formatbar_markdown mx_filterFlipColor"
src={`img/button-md-${!this.state.inputState.isRichTextEnabled}.png`} /> src={require(`../../../../res/img/button-md-${!this.state.inputState.isRichTextEnabled}.png`)} />
<AccessibleButton element="img" title={_t("Hide Text Formatting Toolbar")} <AccessibleButton element="img" title={_t("Hide Text Formatting Toolbar")}
onClick={this.onToggleFormattingClicked} onClick={this.onToggleFormattingClicked}
className="mx_MessageComposer_formatbar_cancel mx_filterFlipColor" className="mx_MessageComposer_formatbar_cancel mx_filterFlipColor"
src="img/icon-text-cancel.svg" /> src={require("../../../../res/img/icon-text-cancel.svg")} />
</div> </div>
</div>; </div>;
} }

View File

@ -1599,7 +1599,7 @@ export default class MessageComposerInput extends React.Component {
<img className="mx_MessageComposer_input_markdownIndicator mx_filterFlipColor" <img className="mx_MessageComposer_input_markdownIndicator mx_filterFlipColor"
onMouseDown={this.onMarkdownToggleClicked} onMouseDown={this.onMarkdownToggleClicked}
title={this.state.isRichTextEnabled ? _t("Markdown is disabled") : _t("Markdown is enabled")} title={this.state.isRichTextEnabled ? _t("Markdown is disabled") : _t("Markdown is enabled")}
src={`img/button-md-${!this.state.isRichTextEnabled}.png`} /> src={require(`../../../../res/img/button-md-${!this.state.isRichTextEnabled}.png`)} />
<Editor ref={this._collectEditor} <Editor ref={this._collectEditor}
dir="auto" dir="auto"
className="mx_MessageComposer_editor" className="mx_MessageComposer_editor"

View File

@ -67,7 +67,7 @@ module.exports = React.createClass({
if (this._canUnpin()) { if (this._canUnpin()) {
unpinButton = ( unpinButton = (
<AccessibleButton onClick={this.onUnpinClicked} className="mx_PinnedEventTile_unpinButton"> <AccessibleButton onClick={this.onUnpinClicked} className="mx_PinnedEventTile_unpinButton">
<img src="img/cancel-red.svg" width="8" height="8" alt={_t('Unpin Message')} title={_t('Unpin Message')} /> <img src={require("../../../../res/img/cancel-red.svg")} width="8" height="8" alt={_t('Unpin Message')} title={_t('Unpin Message')} />
</AccessibleButton> </AccessibleButton>
); );
} }

View File

@ -130,7 +130,7 @@ module.exports = React.createClass({
<div className="mx_PinnedEventsPanel"> <div className="mx_PinnedEventsPanel">
<div className="mx_PinnedEventsPanel_body"> <div className="mx_PinnedEventsPanel_body">
<AccessibleButton className="mx_PinnedEventsPanel_cancel" onClick={this.props.onCancelClick}> <AccessibleButton className="mx_PinnedEventsPanel_cancel" onClick={this.props.onCancelClick}>
<img className="mx_filterFlipColor" src="img/cancel.svg" width="18" height="18" /> <img className="mx_filterFlipColor" src={require("../../../../res/img/cancel.svg")} width="18" height="18" />
</AccessibleButton> </AccessibleButton>
<h3 className="mx_PinnedEventsPanel_header">{ _t("Pinned Messages") }</h3> <h3 className="mx_PinnedEventsPanel_header">{ _t("Pinned Messages") }</h3>
{ tiles } { tiles }

View File

@ -68,7 +68,7 @@ export default class ReplyPreview extends React.Component {
{ '💬 ' + _t('Replying') } { '💬 ' + _t('Replying') }
</EmojiText> </EmojiText>
<div className="mx_ReplyPreview_header mx_ReplyPreview_cancel"> <div className="mx_ReplyPreview_header mx_ReplyPreview_cancel">
<img className="mx_filterFlipColor" src="img/cancel.svg" width="18" height="18" <img className="mx_filterFlipColor" src={require("../../../../res/img/cancel.svg")} width="18" height="18"
onClick={cancelQuoting} /> onClick={cancelQuoting} />
</div> </div>
<div className="mx_ReplyPreview_clear" /> <div className="mx_ReplyPreview_clear" />

View File

@ -312,14 +312,14 @@ module.exports = React.createClass({
</div> </div>
<div className="mx_RoomHeader_avatarPicker_edit"> <div className="mx_RoomHeader_avatarPicker_edit">
<label htmlFor="avatarInput" ref="file_label"> <label htmlFor="avatarInput" ref="file_label">
<img src="img/camera.svg" <img src={require("../../../../res/img/camera.svg")}
alt={_t("Upload avatar")} title={_t("Upload avatar")} alt={_t("Upload avatar")} title={_t("Upload avatar")}
width="17" height="15" /> width="17" height="15" />
</label> </label>
<input id="avatarInput" type="file" onChange={this.onAvatarSelected} /> <input id="avatarInput" type="file" onChange={this.onAvatarSelected} />
</div> </div>
<div className="mx_RoomHeader_avatarPicker_remove" onClick={this.onAvatarRemoveClick}> <div className="mx_RoomHeader_avatarPicker_remove" onClick={this.onAvatarRemoveClick}>
<img src="img/cancel.svg" <img src={require("../../../../res/img/cancel.svg")}
className="mx_filterFlipColor" className="mx_filterFlipColor"
width="10" width="10"
alt={_t("Remove avatar")} alt={_t("Remove avatar")}
@ -337,7 +337,7 @@ module.exports = React.createClass({
if (this.props.onSettingsClick) { if (this.props.onSettingsClick) {
settingsButton = settingsButton =
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSettingsClick} title={_t("Settings")}> <AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSettingsClick} title={_t("Settings")}>
<TintableSvg src="img/feather-icons/settings.svg" width="20" height="20" /> <TintableSvg src={require("../../../../res/img/feather-icons/settings.svg")} width="20" height="20" />
</AccessibleButton>; </AccessibleButton>;
} }
@ -353,7 +353,7 @@ module.exports = React.createClass({
<AccessibleButton className="mx_RoomHeader_button mx_RoomHeader_pinnedButton" <AccessibleButton className="mx_RoomHeader_button mx_RoomHeader_pinnedButton"
onClick={this.props.onPinnedClick} title={_t("Pinned Messages")}> onClick={this.props.onPinnedClick} title={_t("Pinned Messages")}>
{ pinsIndicator } { pinsIndicator }
<TintableSvg src="img/icons-pin.svg" width="16" height="16" /> <TintableSvg src={require("../../../../res/img/icons-pin.svg")} width="16" height="16" />
</AccessibleButton>; </AccessibleButton>;
} }
@ -361,7 +361,7 @@ module.exports = React.createClass({
// if (this.props.onLeaveClick) { // if (this.props.onLeaveClick) {
// leave_button = // leave_button =
// <div className="mx_RoomHeader_button" onClick={this.props.onLeaveClick} title="Leave room"> // <div className="mx_RoomHeader_button" onClick={this.props.onLeaveClick} title="Leave room">
// <TintableSvg src="img/leave.svg" width="26" height="20"/> // <TintableSvg src={require("../../../../res/img/leave.svg")} width="26" height="20"/>
// </div>; // </div>;
// } // }
@ -369,7 +369,7 @@ module.exports = React.createClass({
if (this.props.onForgetClick) { if (this.props.onForgetClick) {
forgetButton = forgetButton =
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onForgetClick} title={_t("Forget room")}> <AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onForgetClick} title={_t("Forget room")}>
<TintableSvg src="img/leave.svg" width="26" height="20" /> <TintableSvg src={require("../../../../res/img/leave.svg")} width="26" height="20" />
</AccessibleButton>; </AccessibleButton>;
} }
@ -377,7 +377,7 @@ module.exports = React.createClass({
if (this.props.onSearchClick && this.props.inRoom) { if (this.props.onSearchClick && this.props.inRoom) {
searchButton = searchButton =
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSearchClick} title={_t("Search")}> <AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSearchClick} title={_t("Search")}>
<TintableSvg src="img/feather-icons/search.svg" width="20" height="20" /> <TintableSvg src={require("../../../../res/img/feather-icons/search.svg")} width="20" height="20" />
</AccessibleButton>; </AccessibleButton>;
} }
@ -385,7 +385,7 @@ module.exports = React.createClass({
if (this.props.inRoom) { if (this.props.inRoom) {
shareRoomButton = shareRoomButton =
<AccessibleButton className="mx_RoomHeader_button" onClick={this.onShareRoomClick} title={_t('Share room')}> <AccessibleButton className="mx_RoomHeader_button" onClick={this.onShareRoomClick} title={_t('Share room')}>
<TintableSvg src="img/feather-icons/share.svg" width="20" height="20" /> <TintableSvg src={require("../../../../res/img/feather-icons/share.svg")} width="20" height="20" />
</AccessibleButton>; </AccessibleButton>;
} }

View File

@ -124,7 +124,7 @@ module.exports = React.createClass({
emailMatchBlock = emailMatchBlock =
<div className="mx_RoomPreviewBar_warning"> <div className="mx_RoomPreviewBar_warning">
<div className="mx_RoomPreviewBar_warningIcon"> <div className="mx_RoomPreviewBar_warningIcon">
<img src="img/warning.svg" width="24" height="23" title= "/!\\" alt="/!\\" /> <img src={require("../../../../res/img/warning.svg")} width="24" height="23" title= "/!\\" alt="/!\\" />
</div> </div>
<div className="mx_RoomPreviewBar_warningText"> <div className="mx_RoomPreviewBar_warningText">
{ _t("This invitation was sent to an email address which is not associated with this account:") } { _t("This invitation was sent to an email address which is not associated with this account:") }

View File

@ -616,7 +616,7 @@ module.exports = React.createClass({
<div> <div>
<label> <label>
<input type="checkbox" ref="encrypt" onClick={this.onEnableEncryptionClick} /> <input type="checkbox" ref="encrypt" onClick={this.onEnableEncryptionClick} />
<img className="mx_RoomSettings_e2eIcon mx_filterFlipColor" src="img/e2e-unencrypted.svg" width="12" height="12" /> <img className="mx_RoomSettings_e2eIcon mx_filterFlipColor" src={require("../../../../res/img/e2e-unencrypted.svg")} width="12" height="12" />
{ _t('Enable encryption') } { _t('(warning: cannot be disabled again!)') } { _t('Enable encryption') } { _t('(warning: cannot be disabled again!)') }
</label> </label>
{ settings } { settings }
@ -627,8 +627,8 @@ module.exports = React.createClass({
<div> <div>
<label> <label>
{ isEncrypted { isEncrypted
? <img className="mx_RoomSettings_e2eIcon" src="img/e2e-verified.svg" width="10" height="12" /> ? <img className="mx_RoomSettings_e2eIcon" src={require("../../../../res/img/e2e-verified.svg")} width="10" height="12" />
: <img className="mx_RoomSettings_e2eIcon mx_filterFlipColor" src="img/e2e-unencrypted.svg" width="12" height="12" /> : <img className="mx_RoomSettings_e2eIcon mx_filterFlipColor" src={require("../../../../res/img/e2e-unencrypted.svg")} width="12" height="12" />
} }
{ isEncrypted ? _t("Encryption is enabled in this room") : _t("Encryption is not enabled in this room") }. { isEncrypted ? _t("Encryption is enabled in this room") : _t("Encryption is not enabled in this room") }.
</label> </label>

View File

@ -392,7 +392,13 @@ module.exports = React.createClass({
let dmIndicator; let dmIndicator;
if (this._isDirectMessageRoom(this.props.room.roomId)) { if (this._isDirectMessageRoom(this.props.room.roomId)) {
dmIndicator = <img src="img/icon_person.svg" className="mx_RoomTile_dm" width="11" height="13" alt="dm" />; dmIndicator = <img
src={require("../../../../res/img/icon_person.svg")}
className="mx_RoomTile_dm"
width="11"
height="13"
alt="dm"
/>;
} }
return <AccessibleButton tabIndex="0" return <AccessibleButton tabIndex="0"

View File

@ -120,7 +120,7 @@ const SearchableEntityList = React.createClass({
const text = _t("and %(count)s others...", { count: overflowCount }); const text = _t("and %(count)s others...", { count: overflowCount });
return ( return (
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={ <EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
<BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} /> <BaseAvatar url={require("../../../../res/img/ellipsis.svg")} name="..." width={36} height={36} />
} name={text} presenceState="online" suppressOnHover={true} } name={text} presenceState="online" suppressOnHover={true}
onClick={this._showAll} /> onClick={this._showAll} />
); );

Some files were not shown because too many files have changed in this diff Show More