diff --git a/.travis.yml b/.travis.yml index c68279a269..e020ba7d15 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,14 @@ node_js: # - 7.x is the current 'current' version (until October 2017) # # see: https://github.com/nodejs/LTS/ - - 6.0 + # + # anything before 6.3 ships with npm 3.9 or earlier, which had problems + # with symlinks in node_modules (see + # https://github.com/npm/npm/releases/tag/v3.10.0 'FIXES AND REFACTORING'). + - 6.3 - 6 - 7 install: - - scripts/fetch-develop.deps.sh - - npm install + # clone the deps with depth 1: we know we will only ever need that one + # commit. + - scripts/fetch-develop.deps.sh --depth 1 && npm install diff --git a/CHANGELOG.md b/CHANGELOG.md index 2165700527..41b0970134 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,130 @@ +Changes in [0.10.1](https://github.com/vector-im/riot-web/releases/tag/v0.10.1) (2017-06-02) +============================================================================================ +[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.10.0...v0.10.1) + + * Update to matrix-react-sdk 0.9.1 to fix i18n error which broke start chat in some circumstances + +Changes in [0.10.0](https://github.com/vector-im/riot-web/releases/tag/v0.10.0) (2017-06-02) +============================================================================================ +[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.10.0-rc.2...v0.10.0) + + * Update from Weblate. + [\#4152](https://github.com/vector-im/riot-web/pull/4152) + +Changes in [0.10.0-rc.2](https://github.com/vector-im/riot-web/releases/tag/v0.10.0-rc.2) (2017-06-02) +====================================================================================================== +[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.10.0-rc.1...v0.10.0-rc.2) + + * Update from Weblate. + [\#4150](https://github.com/vector-im/riot-web/pull/4150) + * styling for webrtc settings + [\#4019](https://github.com/vector-im/riot-web/pull/4019) + * Update from Weblate. + [\#4140](https://github.com/vector-im/riot-web/pull/4140) + * add styles for compact layout + [\#4132](https://github.com/vector-im/riot-web/pull/4132) + * Various tweaks to fetch-develop-deps + [\#4147](https://github.com/vector-im/riot-web/pull/4147) + * Don't try to build with node 6.0 + [\#4145](https://github.com/vector-im/riot-web/pull/4145) + * Support 12hr time on DateSeparator + [\#4143](https://github.com/vector-im/riot-web/pull/4143) + * Update from Weblate. + [\#4137](https://github.com/vector-im/riot-web/pull/4137) + * Update from Weblate. + [\#4105](https://github.com/vector-im/riot-web/pull/4105) + * Update from Weblate. + [\#4094](https://github.com/vector-im/riot-web/pull/4094) + * Update from Weblate. + [\#4091](https://github.com/vector-im/riot-web/pull/4091) + * Update from Weblate. + [\#4089](https://github.com/vector-im/riot-web/pull/4089) + * Update from Weblate. + [\#4083](https://github.com/vector-im/riot-web/pull/4083) + +Changes in [0.10.0-rc.1](https://github.com/vector-im/riot-web/releases/tag/v0.10.0-rc.1) (2017-06-01) +====================================================================================================== +[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.10...v0.10.0-rc.1) + + * basic electron profile support + [\#4030](https://github.com/vector-im/riot-web/pull/4030) + * Finish translations for vector-im/riot-web + [\#4122](https://github.com/vector-im/riot-web/pull/4122) + * Translate src/vector + [\#4119](https://github.com/vector-im/riot-web/pull/4119) + * electron flashFrame was way too annoying + [\#4128](https://github.com/vector-im/riot-web/pull/4128) + * auto-launch support [Electron] + [\#4012](https://github.com/vector-im/riot-web/pull/4012) + * Show 12hr time on hover too + [\#4092](https://github.com/vector-im/riot-web/pull/4092) + * Translate src/notifications + [\#4087](https://github.com/vector-im/riot-web/pull/4087) + * Translate src/components/structures + [\#4084](https://github.com/vector-im/riot-web/pull/4084) + * Smaller font size on timestamp to better fit in the available space + [\#4085](https://github.com/vector-im/riot-web/pull/4085) + * Make travis run the build with several versions of node + [\#4079](https://github.com/vector-im/riot-web/pull/4079) + * Piwik Analytics + [\#4056](https://github.com/vector-im/riot-web/pull/4056) + * Update from Weblate. + [\#4077](https://github.com/vector-im/riot-web/pull/4077) + * managed to eat the eventStatus check, can't redact a local-echo etc + [\#4078](https://github.com/vector-im/riot-web/pull/4078) + * show redact in context menu only if has PL to/sent message + [\#3925](https://github.com/vector-im/riot-web/pull/3925) + * Update from Weblate. + [\#4064](https://github.com/vector-im/riot-web/pull/4064) + * Change redact -> remove to improve clarity + [\#3722](https://github.com/vector-im/riot-web/pull/3722) + * Update from Weblate. + [\#4058](https://github.com/vector-im/riot-web/pull/4058) + * Message Forwarding + [\#3688](https://github.com/vector-im/riot-web/pull/3688) + * Update from Weblate. + [\#4057](https://github.com/vector-im/riot-web/pull/4057) + * Fixed an input field's background color in dark theme + [\#4053](https://github.com/vector-im/riot-web/pull/4053) + * Update from Weblate. + [\#4051](https://github.com/vector-im/riot-web/pull/4051) + * Update from Weblate. + [\#4049](https://github.com/vector-im/riot-web/pull/4049) + * Update from Weblate. + [\#4048](https://github.com/vector-im/riot-web/pull/4048) + * Update from Weblate. + [\#4040](https://github.com/vector-im/riot-web/pull/4040) + * Update translating.md: Minor suggestions + [\#4041](https://github.com/vector-im/riot-web/pull/4041) + * tidy electron files, they weren't pwetty + [\#3993](https://github.com/vector-im/riot-web/pull/3993) + * Prevent Power Save when in call (Electron) + [\#3992](https://github.com/vector-im/riot-web/pull/3992) + * Translations! + [\#4035](https://github.com/vector-im/riot-web/pull/4035) + * Kieran gould/12hourtimestamp + [\#3961](https://github.com/vector-im/riot-web/pull/3961) + * Don't include src in the test resolve root + [\#4033](https://github.com/vector-im/riot-web/pull/4033) + * add moar context menus [Electron] + [\#4021](https://github.com/vector-im/riot-web/pull/4021) + * Add `Chat` to Linux app categories + [\#4022](https://github.com/vector-im/riot-web/pull/4022) + * add menu category for linux build of app + [\#3975](https://github.com/vector-im/riot-web/pull/3975) + * Electron Tray Improvements + [\#3909](https://github.com/vector-im/riot-web/pull/3909) + * More riot-web test deflakification + [\#3966](https://github.com/vector-im/riot-web/pull/3966) + * Script to fetch corresponding branches of dependent projects + [\#3945](https://github.com/vector-im/riot-web/pull/3945) + * Add type="text/css" to SVG logos + [\#3964](https://github.com/vector-im/riot-web/pull/3964) + * Fix some setState-after-unmount in roomdirectory + [\#3958](https://github.com/vector-im/riot-web/pull/3958) + * Attempt to deflakify joining test + [\#3956](https://github.com/vector-im/riot-web/pull/3956) + Changes in [0.9.10](https://github.com/vector-im/riot-web/releases/tag/v0.9.10) (2017-05-22) ============================================================================================ [Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.10-rc.1...v0.9.10) diff --git a/README.md b/README.md index be3f3a8b4b..94e2a9cc9c 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,8 @@ Building From Source Riot is a modular webapp built with modern ES6 and requires a npm build system to build. -1. Install or update `node.js` so that your `node` is at least v6.0.0 (and `npm` - is at least v3.8.6). +1. Install or update `node.js` so that your `node` is at least v6.3.0 (and `npm` + is at least v3.10.x). 1. Clone the repo: `git clone https://github.com/vector-im/riot-web.git`. 1. Switch to the riot-web directory: `cd riot-web`. 1. If you're using the `develop` branch, install the develop versions of the @@ -134,7 +134,7 @@ Running as a Desktop app Riot can also be run as a desktop app, wrapped in electron. You can download a pre-built version from https://riot.im/desktop.html or, if you prefer, -built it yourself. +build it yourself. Requires Electron >=1.6.0 To run as a desktop app: diff --git a/docs/translating.md b/docs/translating.md index ca9920d323..9a4f6f6e9c 100644 --- a/docs/translating.md +++ b/docs/translating.md @@ -8,7 +8,7 @@ ## Step 0: Join #riotweb-translations:matrix.org -1. Come and join https://riot.im/develop/#/room/#riotweb-translations:matrix.org +1. Come and join https://matrix.to/#/#riotweb-translations:matrix.org 2. Read scrollback and/or ask if anyone else is working on your language, and co-ordinate if needed. In general little-or-no coordination is needed though :) ## Step 1: Preparing your Weblate Profile diff --git a/electron_app/package.json b/electron_app/package.json index df9c3bd261..820b498891 100644 --- a/electron_app/package.json +++ b/electron_app/package.json @@ -2,10 +2,13 @@ "name": "riot-web", "productName": "Riot", "main": "src/electron-main.js", - "version": "0.9.10", + "version": "0.10.1", "description": "A feature-rich client for Matrix.org", "author": "Vector Creations Ltd.", "dependencies": { - "electron-window-state": "^4.1.0" + "auto-launch": "^5.0.1", + "electron-window-state": "^4.1.0", + "minimist": "^1.2.0", + "png-to-ico": "^1.0.2" } } diff --git a/electron_app/src/electron-main.js b/electron_app/src/electron-main.js index ca8c3a1be6..3491ce0fa3 100644 --- a/electron_app/src/electron-main.js +++ b/electron_app/src/electron-main.js @@ -1,6 +1,7 @@ /* Copyright 2016 Aviral Dasgupta Copyright 2016 OpenMarket Ltd +Copyright 2017 Michael Telatynski <7t3chguy@gmail.com> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +22,9 @@ limitations under the License. const checkSquirrelHooks = require('./squirrelhooks'); if (checkSquirrelHooks()) return; +const argv = require('minimist')(process.argv); const electron = require('electron'); +const AutoLaunch = require('auto-launch'); const tray = require('./tray'); const vectorMenu = require('./vectormenu'); @@ -29,6 +32,10 @@ const webContentsHandler = require('./webcontents-handler'); const windowStateKeeper = require('electron-window-state'); +if (argv.profile) { + electron.app.setPath('userData', `${electron.app.getPath('userData')}-${argv.profile}`); +} + let vectorConfig = {}; try { vectorConfig = require('../../webapp/config.json'); @@ -45,47 +52,6 @@ const INITIAL_UPDATE_DELAY_MS = 30 * 1000; let mainWindow = null; let appQuitting = false; -function safeOpenURL(target) { - // openExternal passes the target to open/start/xdg-open, - // so put fairly stringent limits on what can be opened - // (for instance, open /bin/sh does indeed open a terminal - // with a shell, albeit with no arguments) - const parsedUrl = url.parse(target); - if (PERMITTED_URL_SCHEMES.indexOf(parsedUrl.protocol) > -1) { - // explicitly use the URL re-assembled by the url library, - // so we know the url parser has understood all the parts - // of the input string - const newTarget = url.format(parsedUrl); - electron.shell.openExternal(newTarget); - } -} - -function onWindowOrNavigate(ev, target) { - // always prevent the default: if something goes wrong, - // we don't want to end up opening it in the electron - // app, as we could end up opening any sort of random - // url in a window that has node scripting access. - ev.preventDefault(); - safeOpenURL(target); -} - -function onLinkContextMenu(ev, params) { - const popupMenu = new electron.Menu(); - - popupMenu.append(new electron.MenuItem({ - label: params.linkURL, - click() { safeOpenURL(params.linkURL); }, - })); - - popupMenu.append(new electron.MenuItem({ - label: 'Copy Link Address', - click() { electron.clipboard.writeText(params.linkURL); }, - })); - - popupMenu.popup(); - ev.preventDefault(); -} - function installUpdate() { // for some reason, quitAndInstall does not fire the // before-quit event, so we need to set the flag here. @@ -159,19 +125,19 @@ electron.ipcMain.on('install_update', installUpdate); let focusHandlerAttached = false; electron.ipcMain.on('setBadgeCount', function(ev, count) { electron.app.setBadgeCount(count); - if (process.platform === 'win32' && mainWindow && !mainWindow.isFocused()) { - if (count > 0) { - if (!focusHandlerAttached) { - mainWindow.once('focus', () => { - mainWindow.flashFrame(false); - focusHandlerAttached = false; - }); - focusHandlerAttached = true; - } - mainWindow.flashFrame(true); - } else { + if (count === 0) { + mainWindow.flashFrame(false); + } +}); + +electron.ipcMain.on('loudNotification', function() { + if (process.platform === 'win32' && mainWindow && !mainWindow.isFocused() && !focusHandlerAttached) { + mainWindow.flashFrame(true); + mainWindow.once('focus', () => { mainWindow.flashFrame(false); - } + focusHandlerAttached = false; + }); + focusHandlerAttached = true; } }); @@ -206,10 +172,65 @@ const shouldQuit = electron.app.makeSingleInstance((commandLine, workingDirector if (shouldQuit) { console.log('Other instance detected: exiting'); - electron.app.quit(); + electron.app.exit(); } + +const launcher = new AutoLaunch({ + name: vectorConfig.brand || 'Riot', + isHidden: true, + mac: { + useLaunchAgent: true, + }, +}); + +const settings = { + 'auto-launch': { + get: launcher.isEnabled, + set: function(bool) { + if (bool) { + return launcher.enable(); + } else { + return launcher.disable(); + } + }, + }, +}; + +electron.ipcMain.on('settings_get', async function(ev) { + const data = {}; + + try { + await Promise.all(Object.keys(settings).map(async function (setting) { + data[setting] = await settings[setting].get(); + })); + + ev.sender.send('settings', data); + } catch(e) { console.error(e); } +}); + +electron.ipcMain.on('settings_set', function(ev, key, value) { + console.log(key, value); + if (settings[key] && settings[key].set) { + settings[key].set(value); + } +}); + electron.app.on('ready', () => { + + if (argv.devtools) { + try { + const { default: installExtension, REACT_DEVELOPER_TOOLS, REACT_PERF } = require('electron-devtools-installer'); + installExtension(REACT_DEVELOPER_TOOLS) + .then((name) => console.log(`Added Extension: ${name}`)) + .catch((err) => console.log('An error occurred: ', err)); + installExtension(REACT_PERF) + .then((name) => console.log(`Added Extension: ${name}`)) + .catch((err) => console.log('An error occurred: ', err)); + } catch(e) {console.log(e);} + } + + if (vectorConfig.update_base_url) { console.log(`Starting auto update with base URL: ${vectorConfig.update_base_url}`); startAutoUpdate(vectorConfig.update_base_url); @@ -238,13 +259,17 @@ electron.app.on('ready', () => { mainWindow.loadURL(`file://${__dirname}/../../webapp/index.html`); electron.Menu.setApplicationMenu(vectorMenu); + // explicitly hide because setApplicationMenu on Linux otherwise shows... + // https://github.com/electron/electron/issues/9621 + mainWindow.hide(); + // Create trayIcon icon tray.create(mainWindow, { icon_path: iconPath, brand: vectorConfig.brand || 'Riot', }); - if (!process.argv.includes('--hidden')) { + if (!argv.hidden) { mainWindow.once('ready-to-show', () => { mainWindow.show(); }); diff --git a/electron_app/src/tray.js b/electron_app/src/tray.js index 9df1a0fb60..039e7133fa 100644 --- a/electron_app/src/tray.js +++ b/electron_app/src/tray.js @@ -16,6 +16,9 @@ limitations under the License. */ const {app, Tray, Menu, nativeImage} = require('electron'); +const pngToIco = require('png-to-ico'); +const path = require('path'); +const fs = require('fs'); let trayIcon = null; @@ -57,7 +60,7 @@ exports.create = function(win, config) { trayIcon.on('click', toggleWin); let lastFavicon = null; - win.webContents.on('page-favicon-updated', function(ev, favicons) { + win.webContents.on('page-favicon-updated', async function(ev, favicons) { let newFavicon = config.icon_path; if (favicons && favicons.length > 0 && favicons[0].startsWith('data:')) { newFavicon = favicons[0]; @@ -70,6 +73,15 @@ exports.create = function(win, config) { // if its not default we have to construct into nativeImage if (newFavicon !== config.icon_path) { newFavicon = nativeImage.createFromDataURL(favicons[0]); + + if (process.platform === 'win32') { + try { + const icoPath = path.join(app.getPath('temp'), 'win32_riot_icon.ico') + const icoBuf = await pngToIco(newFavicon.toPNG()); + fs.writeFileSync(icoPath, icoBuf); + newFavicon = icoPath; + } catch (e) {console.error(e);} + } } trayIcon.setImage(newFavicon); diff --git a/package.json b/package.json index 29b5beee07..bb3edc4075 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "riot-web", "productName": "Riot", "main": "electron_app/src/electron-main.js", - "version": "0.9.10", + "version": "0.10.1", "description": "A feature-rich client for Matrix.org", "author": "Vector Creations Ltd.", "repository": { @@ -33,7 +33,7 @@ "build:compile": "npm run reskindex && babel --source-maps -d lib src", "build:bundle": "cross-env NODE_ENV=production webpack -p --progress", "build:bundle:dev": "webpack --optimize-occurence-order --progress", - "build:electron": "npm run clean && npm run build && build -wml --ia32 --x64", + "build:electron": "npm run clean && npm run build && npm run install:electron && build -wml --ia32 --x64", "build": "npm run reskindex && npm run build:res && npm run build:bundle", "build:dev": "npm run reskindex && npm run build:res && npm run build:bundle:dev", "dist": "scripts/package.sh", @@ -65,8 +65,8 @@ "gfm.css": "^1.1.1", "highlight.js": "^9.0.0", "linkifyjs": "^2.1.3", - "matrix-js-sdk": "matrix-org/matrix-js-sdk#develop", - "matrix-react-sdk": "matrix-org/matrix-react-sdk#develop", + "matrix-js-sdk": "0.7.10", + "matrix-react-sdk": "0.9.1", "modernizr": "^3.1.0", "pako": "^1.0.5", "q": "^1.4.1", @@ -101,6 +101,7 @@ "css-raw-loader": "^0.1.1", "electron-builder": "^11.2.4", "electron-builder-squirrel-windows": "^11.2.1", + "electron-devtools-installer": "^2.2.0", "emojione": "^2.2.7", "eslint": "^3.14.0", "eslint-config-google": "^0.7.1", @@ -162,7 +163,7 @@ "category": "Network;InstantMessaging;Chat", "maintainer": "support@riot.im", "desktop": { - "StartupWMClass": "riot-web" + "StartupWMClass": "riot" } }, "win": { diff --git a/scripts/copy-res.js b/scripts/copy-res.js index d6835a237f..1c471a0516 100755 --- a/scripts/copy-res.js +++ b/scripts/copy-res.js @@ -9,15 +9,18 @@ // This could readily be automated, but it's nice to explicitly // control when we languages are available. const INCLUDE_LANGS = [ - //'be' Omitted because no translations in react-sdk - 'en_EN', - 'da', - 'de_DE', - 'fr', - 'be', - 'pt', - 'pt_BR', - 'ru', + {'value': 'en_EN', 'label': 'English'}, + {'value': 'en_US', 'label': 'English (US)'}, + {'value': 'da', 'label': 'Dansk'}, + {'value': 'nl', 'label': 'Nederlands'}, + {'value': 'de_DE', 'label': 'Deutsch'}, + {'value': 'fr', 'label': 'Français'}, + {'value': 'pt', 'label': 'Português'}, + {'value': 'pt_BR', 'label': 'Português do Brasil'}, + {'value': 'ru', 'label': 'Русский'}, + {'value': 'sv', 'label': 'Svenska'}, + {'value': 'es', 'label': 'Español'}, + {'value': 'zh_Hans', 'label': '中文'} ]; // cpx includes globbed parts of the filename in the destination, but excludes @@ -37,7 +40,7 @@ const COPY_LIST = [ INCLUDE_LANGS.forEach(function(l) { COPY_LIST.push([ - l, "webapp/i18n/", { lang: 1 }, + l.value, "webapp/i18n/", { lang: 1 }, ]); }); @@ -159,17 +162,22 @@ function genLangFile(lang, dest) { function genLangList() { const languages = {}; INCLUDE_LANGS.forEach(function(lang) { - const normalizedLanguage = lang.toLowerCase().replace("_", "-"); + const normalizedLanguage = lang.value.toLowerCase().replace("_", "-"); const languageParts = normalizedLanguage.split('-'); if (languageParts.length == 2 && languageParts[0] == languageParts[1]) { - languages[languageParts[0]] = lang + '.json'; + languages[languageParts[0]] = {'fileName': lang.value + '.json', 'label': lang.label}; } else { - languages[normalizedLanguage] = lang + '.json'; + languages[normalizedLanguage] = {'fileName': lang.value + '.json', 'label': lang.label}; + } + }); + fs.writeFile('webapp/i18n/languages.json', JSON.stringify(languages, null, 4), function(err) { + if (err) { + console.error("Copy Error occured: " + err); + throw new Error("Failed to generate languages.json"); } }); - fs.writeFile('webapp/i18n/languages.json', JSON.stringify(languages, null, 4)); if (verbose) { - console.log("Generated language list"); + console.log("Generated languages.json"); } } diff --git a/scripts/fetch-develop.deps.sh b/scripts/fetch-develop.deps.sh index bbbc834152..cc0f221a20 100755 --- a/scripts/fetch-develop.deps.sh +++ b/scripts/fetch-develop.deps.sh @@ -6,6 +6,10 @@ # the branch the current checkout is on, use that branch. Otherwise, # use develop. +set -e + +GIT_CLONE_ARGS=("$@") + # Look in the many different CI env vars for which branch we're # building if [[ "$TRAVIS" == true ]]; then @@ -23,41 +27,62 @@ fi echo "Determined branch to be $curbranch" +# clone a specific branch of a github repo +function clone() { + org=$1 + repo=$2 + branch=$3 + git clone https://github.com/$org/$repo.git $repo --branch $branch \ + "${GIT_CLONE_ARGS[@]}" +} + function dodep() { org=$1 repo=$2 - rm -rf $repo || true - git clone https://github.com/$org/$repo.git $repo - pushd $repo - git checkout $curbranch || git checkout develop - echo "$repo set to branch "`git rev-parse --abbrev-ref HEAD` - popd + rm -rf $repo + clone $org $repo $curbranch || { + [ "$curbranch" != 'develop' ] && clone $org $repo develop + } || return $? + + ( + cd $repo + echo "$repo set to branch "`git rev-parse --abbrev-ref HEAD` + ) + + mkdir -p node_modules + rm -r "node_modules/$repo" 2>/dev/null || true + ln -sv "../$repo" node_modules/ } +echo -en 'travis_fold:start:matrix-js-sdk\r' +echo 'Setting up matrix-js-sdk' + dodep matrix-org matrix-js-sdk +( + cd node_modules/matrix-js-sdk + npm install +) + +echo -en 'travis_fold:end:matrix-js-sdk\r' + +echo -en 'travis_fold:start:matrix-react-sdk\r' +echo 'Setting up matrix-react-sdk' + dodep matrix-org matrix-react-sdk -mkdir -p node_modules -cd node_modules +mkdir -p node_modules/matrix-react-sdk/node_modules +ln -s ../../matrix-js-sdk node_modules/matrix-react-sdk/node_modules/ -rm -r matrix-js-sdk 2> /dev/null -ln -s ../matrix-js-sdk ./ -pushd matrix-js-sdk -npm install -popd +( + cd node_modules/matrix-react-sdk + npm install +) + +echo -en 'travis_fold:end:matrix-react-sdk\r' -rm -r matrix-react-sdk 2> /dev/null -ln -s ../matrix-react-sdk ./ -pushd matrix-react-sdk -mkdir -p node_modules -cd node_modules -ln -s ../../matrix-js-sdk matrix-js-sdk -cd .. -npm install -popd # Link the reskindex binary in place: if we used npm link, # npm would do this for us, but we don't because we'd have # to define the npm prefix somewhere so it could put the # intermediate symlinks there. Instead, we do it ourselves. -mkdir -p .bin -ln -sf ../matrix-react-sdk/scripts/reskindex.js .bin/reskindex +mkdir -p node_modules/.bin +ln -sfv ../matrix-react-sdk/scripts/reskindex.js node_modules/.bin/reskindex diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 5445fd4fb8..e3f4d14042 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -182,7 +182,7 @@ module.exports = React.createClass({ if (content.msgtype && content.msgtype !== 'm.bad.encrypted' && content.hasOwnProperty('body')) { forwardButton = (
- Forward Message + { _t('Forward Message') }
); } diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 7a65ac587f..0db425e33f 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import sdk from 'matrix-react-sdk'; import SdkConfig from 'matrix-react-sdk/lib/SdkConfig'; +import { _t } from 'matrix-react-sdk/lib/languageHandler'; export default class BugReportDialog extends React.Component { constructor(props, context) { @@ -49,12 +50,12 @@ export default class BugReportDialog extends React.Component { const userText = this.state.text; if (!sendLogs && userText.trim().length === 0) { this.setState({ - err: "Please describe the bug and/or send logs.", + err: _t("Please describe the bug and/or send logs."), }); return; } this.setState({ busy: true, progress: null, err: null }); - this._sendProgressCallback("Loading bug report module"); + this._sendProgressCallback(_t("Loading bug report module")); require(['../../../vector/submit-rageshake'], (s) => { s(SdkConfig.get().bug_report_endpoint_url, { @@ -69,8 +70,9 @@ export default class BugReportDialog extends React.Component { }, (err) => { if (!this._unmounted) { this.setState({ - busy: false, progress: null, - err: `Failed to send report: ${err.message}`, + busy: false, + progress: null, + err: _t("Failed to send report: ") + `${err.message}`, }); } }); @@ -105,7 +107,7 @@ export default class BugReportDialog extends React.Component { let cancelButton = null; if (!this.state.busy) { cancelButton = ; } @@ -122,25 +124,27 @@ export default class BugReportDialog extends React.Component { return (
- Report a bug + { _t("Report a bug") }
-

Please describe the bug. What did you do? - What did you expect to happen? - What actually happened?

+

+ { _t("Please describe the bug. What did you do? What did you expect to happen? What actually happened?") } +