Merge branch 'release-v0.16.4'

pull/7377/head
David Baker 2018-09-10 11:47:09 +01:00
commit 2b18aa7d79
11 changed files with 567 additions and 85 deletions

View File

@ -1,3 +1,22 @@
Changes in [0.16.4](https://github.com/vector-im/riot-web/releases/tag/v0.16.4) (2018-09-10)
============================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.16.4-rc.1...v0.16.4)
* No changes since rc.1
Changes in [0.16.4-rc.1](https://github.com/vector-im/riot-web/releases/tag/v0.16.4-rc.1) (2018-09-07)
======================================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.16.3...v0.16.4-rc.1)
* Update from Weblate.
[\#7296](https://github.com/vector-im/riot-web/pull/7296)
* Fix config not loading & mobileguide script being loaded in riot
[\#7288](https://github.com/vector-im/riot-web/pull/7288)
* Instructions for installing mobile apps
[\#7272](https://github.com/vector-im/riot-web/pull/7272)
* Tidy up index.js
[\#7265](https://github.com/vector-im/riot-web/pull/7265)
Changes in [0.16.3](https://github.com/vector-im/riot-web/releases/tag/v0.16.3) (2018-09-03) Changes in [0.16.3](https://github.com/vector-im/riot-web/releases/tag/v0.16.3) (2018-09-03)
============================================================================================ ============================================================================================
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.16.3-rc.2...v0.16.3) [Full Changelog](https://github.com/vector-im/riot-web/compare/v0.16.3-rc.2...v0.16.3)

View File

@ -2,7 +2,7 @@
"name": "riot-web", "name": "riot-web",
"productName": "Riot", "productName": "Riot",
"main": "src/electron-main.js", "main": "src/electron-main.js",
"version": "0.16.3", "version": "0.16.4",
"description": "A feature-rich client for Matrix.org", "description": "A feature-rich client for Matrix.org",
"author": "Vector Creations Ltd.", "author": "Vector Creations Ltd.",
"dependencies": { "dependencies": {

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "riot-web", "name": "riot-web",
"version": "0.15.6", "version": "0.16.4-rc.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -2,7 +2,7 @@
"name": "riot-web", "name": "riot-web",
"productName": "Riot", "productName": "Riot",
"main": "electron_app/src/electron-main.js", "main": "electron_app/src/electron-main.js",
"version": "0.16.3", "version": "0.16.4",
"description": "A feature-rich client for Matrix.org", "description": "A feature-rich client for Matrix.org",
"author": "New Vector Ltd.", "author": "New Vector Ltd.",
"repository": { "repository": {
@ -64,8 +64,8 @@
"gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279", "gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279",
"gfm.css": "^1.1.1", "gfm.css": "^1.1.1",
"highlight.js": "^9.0.0", "highlight.js": "^9.0.0",
"matrix-js-sdk": "0.10.9", "matrix-js-sdk": "0.11.0",
"matrix-react-sdk": "0.13.3", "matrix-react-sdk": "0.13.4",
"modernizr": "^3.1.0", "modernizr": "^3.1.0",
"prop-types": "^15.5.10", "prop-types": "^15.5.10",
"react": "^15.6.0", "react": "^15.6.0",

View File

@ -33,5 +33,7 @@
"Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!", "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!",
"Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat", "Riot/Android & matrix-android-sdk chat": "Riot/Android & matrix-android-sdk chat",
"Riot/Web & Desktop chat": "Riot/Web & Desktop chat", "Riot/Web & Desktop chat": "Riot/Web & Desktop chat",
"Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat" "Riot/iOS & matrix-ios-sdk chat": "Riot/iOS & matrix-ios-sdk chat",
"You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.<br/>This allows you to use Riot with an existing Matrix account on a different home server.<br/><br/>You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.<br/>This allows you to use Riot with an existing Matrix account on a different home server.<br/><br/>You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.",
"Co-ordination for Riot translators": "Co-ordination for Riot translators"
} }

View File

@ -34,5 +34,6 @@
"Dev chat for the Riot/Web dev team": "Obrolan Developer untuk tim developer Riot/Web", "Dev chat for the Riot/Web dev team": "Obrolan Developer untuk tim developer Riot/Web",
"Dev chat for the Dendrite dev team": "Obrolan Developer untuk tim developer Dendrite", "Dev chat for the Dendrite dev team": "Obrolan Developer untuk tim developer Dendrite",
"Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Banyak ruang sudah tersedia di Matrix, terhubung ke jaringan yang sudah ada (Slack, IRC, Gitter dls) atau independen. Cek direktori!", "Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Banyak ruang sudah tersedia di Matrix, terhubung ke jaringan yang sudah ada (Slack, IRC, Gitter dls) atau independen. Cek direktori!",
"You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.<br/>This allows you to use Riot with an existing Matrix account on a different home server.<br/><br/>You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Anda dapat menggunakan opsi lain untuk mendaftar pada server Matrix yang berbeda dengan memasukkan URL server yang sesuai. <br/>Hal ini memungkinkan anda untuk menggunakan Riot dengan akun matrix yang telah tersedia pada Home server yang berbeda.<br/><br/>Anda juga dapat melakukan pengubahan identitas server akan tetapi akan berakibat tidak dapat mengundang pengguna melalui email, atau diundang melalui email." "You can use the custom server options to sign into other Matrix servers by specifying a different Home server URL.<br/>This allows you to use Riot with an existing Matrix account on a different home server.<br/><br/>You can also set a custom identity server but you won't be able to invite users by email address, or be invited by email address yourself.": "Anda dapat menggunakan opsi lain untuk mendaftar pada server Matrix yang berbeda dengan memasukkan URL server yang sesuai. <br/>Hal ini memungkinkan anda untuk menggunakan Riot dengan akun matrix yang telah tersedia pada Home server yang berbeda.<br/><br/>Anda juga dapat melakukan pengubahan identitas server akan tetapi akan berakibat tidak dapat mengundang pengguna melalui email, atau diundang melalui email.",
"Co-ordination for Riot translators": "Koordinasi dengan penerjemah Riot"
} }

67
src/vector/getconfig.js Normal file
View File

@ -0,0 +1,67 @@
/*
Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import Promise from 'bluebird';
import request from 'browser-request';
export async function getVectorConfig(relativeLocation) {
if (relativeLocation === undefined) relativeLocation = '';
if (relativeLocation !== '' && !relativeLocation.endsWith('/')) relativeLocation += '/';
try {
const configJson = await getConfig(`${relativeLocation}config.${document.domain}.json`);
// 404s succeed with an empty json config, so check that there are keys
if (Object.keys(configJson).length === 0) {
throw new Error(); // throw to enter the catch
}
return configJson;
} catch (e) {
return await getConfig(relativeLocation + "config.json");
}
}
function getConfig(configJsonFilename) {
let deferred = Promise.defer();
request(
{ method: "GET", url: configJsonFilename },
(err, response, body) => {
if (err || response.status < 200 || response.status >= 300) {
// Lack of a config isn't an error, we should
// just use the defaults.
// Also treat a blank config as no config, assuming
// the status code is 0, because we don't get 404s
// from file: URIs so this is the only way we can
// not fail if the file doesn't exist when loading
// from a file:// URI.
if (response) {
if (response.status == 404 || (response.status == 0 && body == '')) {
deferred.resolve({});
}
}
deferred.reject({err: err, response: response});
return;
}
// We parse the JSON ourselves rather than use the JSON
// parameter, since this throws a parse error on empty
// which breaks if there's no config.json and we're
// loading from the filesystem (see above).
deferred.resolve(JSON.parse(body));
}
);
return deferred.promise;
}

View File

@ -1,6 +1,7 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd Copyright 2017 Vector Creations Ltd
Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -15,8 +16,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
'use strict';
// Require common CSS here; this will make webpack process it into bundle.css. // Require common CSS here; this will make webpack process it into bundle.css.
// Our own CSS (which is themed) is imported via separate webpack entry points // Our own CSS (which is themed) is imported via separate webpack entry points
// in webpack.config.js // in webpack.config.js
@ -25,36 +24,22 @@ require('gfm.css/gfm.css');
require('highlight.js/styles/github.css'); require('highlight.js/styles/github.css');
require('draft-js/dist/Draft.css'); require('draft-js/dist/Draft.css');
const rageshake = require("matrix-react-sdk/lib/rageshake/rageshake"); import React from 'react';
rageshake.init().then(() => { // add React and ReactPerf to the global namespace, to make them easier to
console.log("Initialised rageshake: See https://bugs.chromium.org/p/chromium/issues/detail?id=583193 to fix line numbers on Chrome."); // access via the console
rageshake.cleanup(); global.React = React;
}, (err) => {
console.error("Failed to initialise rageshake: " + err);
});
window.addEventListener('beforeunload', (e) => {
console.log('riot-web closing');
// try to flush the logs to indexeddb
rageshake.flush();
});
// add React and ReactPerf to the global namespace, to make them easier to
// access via the console
global.React = require("react");
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
global.Perf = require("react-addons-perf"); global.Perf = require('react-addons-perf');
} }
var RunModernizrTests = require("./modernizr"); // this side-effects a global import RunModernizrTests from './modernizr'; // this side-effects a global
var ReactDOM = require("react-dom"); import ReactDOM from 'react-dom';
var sdk = require("matrix-react-sdk"); import sdk from 'matrix-react-sdk';
const PlatformPeg = require("matrix-react-sdk/lib/PlatformPeg"); import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
sdk.loadSkin(require('../component-index')); sdk.loadSkin(require('../component-index'));
var VectorConferenceHandler = require('matrix-react-sdk/lib/VectorConferenceHandler'); import VectorConferenceHandler from 'matrix-react-sdk/lib/VectorConferenceHandler';
import Promise from 'bluebird'; import Promise from 'bluebird';
var request = require('browser-request'); import request from 'browser-request';
import * as languageHandler from 'matrix-react-sdk/lib/languageHandler'; import * as languageHandler from 'matrix-react-sdk/lib/languageHandler';
// Also import _t directly so we can call it just `_t` as this is what gen-i18n.js expects // Also import _t directly so we can call it just `_t` as this is what gen-i18n.js expects
import { _t } from 'matrix-react-sdk/lib/languageHandler'; import { _t } from 'matrix-react-sdk/lib/languageHandler';
@ -69,12 +54,29 @@ import SettingsStore, {SettingLevel} from "matrix-react-sdk/lib/settings/Setting
import Tinter from 'matrix-react-sdk/lib/Tinter'; import Tinter from 'matrix-react-sdk/lib/Tinter';
import SdkConfig from "matrix-react-sdk/lib/SdkConfig"; import SdkConfig from "matrix-react-sdk/lib/SdkConfig";
var lastLocationHashSet = null; import rageshake from "matrix-react-sdk/lib/rageshake/rageshake";
var CallHandler = require("matrix-react-sdk/lib/CallHandler"); import CallHandler from 'matrix-react-sdk/lib/CallHandler';
CallHandler.setConferenceHandler(VectorConferenceHandler);
MatrixClientPeg.setIndexedDbWorkerScript(window.vector_indexeddb_worker_script); import {getVectorConfig} from './getconfig';
let lastLocationHashSet = null;
function initRageshake() {
rageshake.init().then(() => {
console.log("Initialised rageshake: See https://bugs.chromium.org/p/chromium/issues/detail?id=583193 to fix line numbers on Chrome.");
window.addEventListener('beforeunload', (e) => {
console.log('riot-web closing');
// try to flush the logs to indexeddb
rageshake.flush();
});
rageshake.cleanup();
}, (err) => {
console.error("Failed to initialise rageshake: " + err);
});
}
function checkBrowserFeatures(featureList) { function checkBrowserFeatures(featureList) {
if (!window.Modernizr) { if (!window.Modernizr) {
@ -100,11 +102,6 @@ function checkBrowserFeatures(featureList) {
return featureComplete; return featureComplete;
} }
var validBrowser = checkBrowserFeatures([
"displaytable", "flexbox", "es5object", "es5function", "localstorage",
"objectfit", "indexeddb", "webworkers",
]);
// Parse the given window.location and return parameters that can be used when calling // Parse the given window.location and return parameters that can be used when calling
// MatrixChat.showScreen(screen, params) // MatrixChat.showScreen(screen, params)
function getScreenFromLocation(location) { function getScreenFromLocation(location) {
@ -135,7 +132,7 @@ function onHashChange(ev) {
// This will be called whenever the SDK changes screens, // This will be called whenever the SDK changes screens,
// so a web page can update the URL bar appropriately. // so a web page can update the URL bar appropriately.
var onNewScreen = function(screen) { function onNewScreen(screen) {
console.log("newscreen "+screen); console.log("newscreen "+screen);
var hash = '#/' + screen; var hash = '#/' + screen;
lastLocationHashSet = hash; lastLocationHashSet = hash;
@ -151,7 +148,7 @@ var onNewScreen = function(screen) {
// If we're in electron, we should never pass through a file:// URL otherwise // If we're in electron, we should never pass through a file:// URL otherwise
// the identity server will try to 302 the browser to it, which breaks horribly. // the identity server will try to 302 the browser to it, which breaks horribly.
// so in that instance, hardcode to use riot.im/app for now instead. // so in that instance, hardcode to use riot.im/app for now instead.
var makeRegistrationUrl = function(params) { function makeRegistrationUrl(params) {
let url; let url;
if (window.location.protocol === "file:") { if (window.location.protocol === "file:") {
url = 'https://riot.im/app/#/register'; url = 'https://riot.im/app/#/register';
@ -177,8 +174,6 @@ var makeRegistrationUrl = function(params) {
return url; return url;
} }
window.addEventListener('hashchange', onHashChange);
function getConfig(configJsonFilename) { function getConfig(configJsonFilename) {
let deferred = Promise.defer(); let deferred = Promise.defer();
@ -226,6 +221,12 @@ function onTokenLoginCompleted() {
} }
async function loadApp() { async function loadApp() {
initRageshake();
MatrixClientPeg.setIndexedDbWorkerScript(window.vector_indexeddb_worker_script);
CallHandler.setConferenceHandler(VectorConferenceHandler);
window.addEventListener('hashchange', onHashChange);
await loadLanguage(); await loadLanguage();
const fragparts = parseQsFromFragment(window.location); const fragparts = parseQsFromFragment(window.location);
@ -239,15 +240,7 @@ async function loadApp() {
let configJson; let configJson;
let configError; let configError;
try { try {
try { configJson = await getVectorConfig();
configJson = await getConfig(`config.${document.domain}.json`);
// 404s succeed with an empty json config, so check that there are keys
if (Object.keys(configJson).length === 0) {
throw new Error(); // throw to enter the catch
}
} catch (e) {
configJson = await getConfig("config.json");
}
} catch (e) { } catch (e) {
configError = e; configError = e;
} }
@ -261,31 +254,13 @@ async function loadApp() {
const preventRedirect = Boolean(fragparts.params.client_secret); const preventRedirect = Boolean(fragparts.params.client_secret);
if (!preventRedirect) { if (!preventRedirect) {
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) { const isIos = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
// FIXME: ugly status hardcoding const isAndroid = /Android/.test(navigator.userAgent);
if (SettingsStore.getValue("theme") === 'status') { if (isIos || isAndroid) {
window.location = "https://status.im/join-riot.html"; if (!document.cookie.split(';').some((c) => c.startsWith('mobile_redirect_to_guide'))) {
window.location = "mobile_guide/";
return; return;
} }
else {
if (confirm(_t("Riot is not supported on mobile web. Install the app?"))) {
window.location = "https://itunes.apple.com/us/app/vector.im/id1083446067";
return;
}
}
}
else if (/Android/.test(navigator.userAgent)) {
// FIXME: ugly status hardcoding
if (SettingsStore.getValue("theme") === 'status') {
window.location = "https://status.im/join-riot.html";
return;
}
else {
if (confirm(_t("Riot is not supported on mobile web. Install the app?"))) {
window.location = "https://play.google.com/store/apps/details?id=im.vector.alpha";
return;
}
}
} }
} }
@ -325,17 +300,19 @@ async function loadApp() {
} }
} }
if (window.localStorage && window.localStorage.getItem('mx_accepts_unsupported_browser')) { const validBrowser = checkBrowserFeatures([
console.log('User has previously accepted risks in using an unsupported browser'); "displaytable", "flexbox", "es5object", "es5function", "localstorage",
validBrowser = true; "objectfit", "indexeddb", "webworkers",
} ]);
const acceptInvalidBrowser = window.localStorage && window.localStorage.getItem('mx_accepts_unsupported_browser');
console.log("Vector starting at "+window.location); console.log("Vector starting at "+window.location);
if (configError) { if (configError) {
window.matrixChat = ReactDOM.render(<div className="error"> window.matrixChat = ReactDOM.render(<div className="error">
Unable to load config file: please refresh the page to try again. Unable to load config file: please refresh the page to try again.
</div>, document.getElementById('matrixchat')); </div>, document.getElementById('matrixchat'));
} else if (validBrowser) { } else if (validBrowser || acceptInvalidBrowser) {
const platform = PlatformPeg.get(); const platform = PlatformPeg.get();
platform.startUpdater(); platform.startUpdater();
@ -362,7 +339,6 @@ async function loadApp() {
window.matrixChat = ReactDOM.render( window.matrixChat = ReactDOM.render(
<CompatibilityPage onAccept={function() { <CompatibilityPage onAccept={function() {
if (window.localStorage) window.localStorage.setItem('mx_accepts_unsupported_browser', true); if (window.localStorage) window.localStorage.setItem('mx_accepts_unsupported_browser', true);
validBrowser = true;
console.log("User accepts the compatibility risks."); console.log("User accepts the compatibility risks.");
loadApp(); loadApp();
}} />, }} />,

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,23 @@
import {getVectorConfig} from '../getconfig';
function onBackToRiotClick() {
document.cookie = 'mobile_redirect_to_guide=false;path=/';
window.location.href = '../';
}
async function initPage() {
document.getElementById('back_to_riot_button').onclick = onBackToRiotClick;
const config = await getVectorConfig('..');
let hsUrl;
if (config && config['default_hs_url']) {
hsUrl = config['default_hs_url'];
}
if (hsUrl && hsUrl !== 'https://matrix.org/') {
document.getElementById('step2_container').style.display = 'block';
document.getElementById('hs_url').innerHTML = hsUrl;
document.getElementById('step_login_header').innerHTML= 'Step 3: Register or Log in';
}
}
initPage();

View File

@ -13,6 +13,8 @@ module.exports = {
"bundle": ["babel-polyfill", "./src/vector/index.js"], "bundle": ["babel-polyfill", "./src/vector/index.js"],
"indexeddb-worker": "./src/vector/indexeddb-worker.js", "indexeddb-worker": "./src/vector/indexeddb-worker.js",
"mobileguide": "./src/vector/mobile_guide/index.js",
// We ship olm.js as a separate lump of javascript. This makes it get // We ship olm.js as a separate lump of javascript. This makes it get
// loaded via a separate <script/> tag in index.html (which loads it // loaded via a separate <script/> tag in index.html (which loads it
// into the browser global `Olm`, where js-sdk expects to find it). // into the browser global `Olm`, where js-sdk expects to find it).
@ -128,10 +130,16 @@ module.exports = {
// bottom of <head> or the bottom of <body>, and I'm a bit scared // bottom of <head> or the bottom of <body>, and I'm a bit scared
// about moving them. // about moving them.
inject: false, inject: false,
excludeChunks: ['mobileguide'],
vars: { vars: {
og_image_url: og_image_url, og_image_url: og_image_url,
}, },
}), }),
new HtmlWebpackPlugin({
template: './src/vector/mobile_guide/index.html',
filename: 'mobile_guide/index.html',
chunks: ['mobileguide'],
}),
], ],
devtool: 'source-map', devtool: 'source-map',