Merge branch 'develop' into markjh/attachment_iframe_css

This commit is contained in:
Mark Haines 2016-11-28 15:10:49 +00:00
commit 6c21391ff5
12 changed files with 230 additions and 41 deletions

View File

@ -1,3 +1,48 @@
Changes in [0.9.0](https://github.com/vector-im/vector-web/releases/tag/v0.9.0) (2016-11-19)
============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.8.4...v0.9.0)
* Add a cachebuster to /version
[\#2596](https://github.com/vector-im/vector-web/pull/2596)
* Add a 'View decrypted source' button
[\#2587](https://github.com/vector-im/vector-web/pull/2587)
* Fix changelog dialog to read new version format
[\#2577](https://github.com/vector-im/vector-web/pull/2577)
* Build all of the vector dir in the build process
[\#2558](https://github.com/vector-im/vector-web/pull/2558)
* Support for get_app_version
[\#2553](https://github.com/vector-im/vector-web/pull/2553)
* Add CSS for mlist truncation
[\#2565](https://github.com/vector-im/vector-web/pull/2565)
* Add menu option for `external_url` if present
[\#2560](https://github.com/vector-im/vector-web/pull/2560)
* Make auto-update configureable
[\#2555](https://github.com/vector-im/vector-web/pull/2555)
* Missed files electron windows fixes
[\#2556](https://github.com/vector-im/vector-web/pull/2556)
* Add some CSS for scalar error popup
[\#2554](https://github.com/vector-im/vector-web/pull/2554)
* Catch unhandled errors in the electron process
[\#2552](https://github.com/vector-im/vector-web/pull/2552)
* Slight grab-bag of fixes for electron on Windows
[\#2551](https://github.com/vector-im/vector-web/pull/2551)
* Electron app (take 3)
[\#2535](https://github.com/vector-im/vector-web/pull/2535)
* Use webpack-dev-server instead of http-server
[\#2542](https://github.com/vector-im/vector-web/pull/2542)
* Better support no-config when loading from file
[\#2541](https://github.com/vector-im/vector-web/pull/2541)
* Fix loading with no config from HTTP
[\#2540](https://github.com/vector-im/vector-web/pull/2540)
* Move 'new version' support into Platform
[\#2532](https://github.com/vector-im/vector-web/pull/2532)
* Add Notification support to the Web Platform
[\#2533](https://github.com/vector-im/vector-web/pull/2533)
* Use the defaults if given a blank config file
[\#2534](https://github.com/vector-im/vector-web/pull/2534)
* Implement Platforms
[\#2531](https://github.com/vector-im/vector-web/pull/2531)
hanges in [0.8.4](https://github.com/vector-im/vector-web/releases/tag/v0.8.4) (2016-11-04) hanges in [0.8.4](https://github.com/vector-im/vector-web/releases/tag/v0.8.4) (2016-11-04)
============================================================================================ ============================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.8.4-rc.2...v0.8.4) [Full Changelog](https://github.com/vector-im/vector-web/compare/v0.8.4-rc.2...v0.8.4)

View File

@ -31,6 +31,8 @@
"nativePattern": "[^\\s]+/[^\\s]+$" "nativePattern": "[^\\s]+/[^\\s]+$"
}, },
"irc:freenode": { "irc:freenode": {
"protocol": "irc",
"domain": "chat.freenode.net",
"portalRoomPattern": "#freenode_.*:matrix.org", "portalRoomPattern": "#freenode_.*:matrix.org",
"name": "Freenode", "name": "Freenode",
"icon": "//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX", "icon": "//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",
@ -38,6 +40,8 @@
"nativePattern": "^#[^\\s]+$" "nativePattern": "^#[^\\s]+$"
}, },
"irc:mozilla": { "irc:mozilla": {
"protocol": "irc",
"domain": "irc.mozilla.org",
"portalRoomPattern": "#mozilla_.*:matrix.org", "portalRoomPattern": "#mozilla_.*:matrix.org",
"name": "Mozilla", "name": "Mozilla",
"icon": "//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX", "icon": "//matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",

72
electron/config.json Normal file
View File

@ -0,0 +1,72 @@
{
"update_url": "https://riot.im/download/desktop/",
"default_hs_url": "https://matrix.org",
"default_is_url": "https://vector.im",
"brand": "Riot",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"enableLabs": true,
"roomDirectory": {
"servers": [
"matrix.org"
],
"serverConfig": {
"matrix.org": {
"networks": [
"_matrix",
"gitter",
"irc:freenode",
"irc:mozilla",
"irc:snoonet",
"irc:oftc"
]
}
},
"networks": {
"gitter": {
"protocol": "gitter",
"portalRoomPattern": "#gitter_.*:matrix.org",
"name": "Gitter",
"icon": "https://gitter.im/favicon.ico",
"example": "org/community",
"nativePattern": "[^\\s]+/[^\\s]+$"
},
"irc:freenode": {
"protocol": "irc",
"domain": "chat.freenode.net",
"portalRoomPattern": "#freenode_.*:matrix.org",
"name": "Freenode",
"icon": "https://matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",
"example": "#channel",
"nativePattern": "^#[^\\s]+$"
},
"irc:mozilla": {
"protocol": "irc",
"domain": "chat.freenode.net",
"portalRoomPattern": "#mozilla_.*:matrix.org",
"name": "Mozilla",
"icon": "https://matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",
"example": "#channel",
"nativePattern": "^#[^\\s]+$"
},
"irc:snoonet": {
"protocol": "irc",
"domain": "ipv6-irc.snoonet.org",
"portalRoomPattern": "#_snoonet_.*:matrix.org",
"name": "Snoonet",
"icon": "https://matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",
"example": "#channel",
"nativePattern": "^#[^\\s]+$"
},
"irc:oftc": {
"protocol": "irc",
"domain": "irc.oftc.net",
"portalRoomPattern": "#_oftc_.*:matrix.org",
"name": "OFTC",
"icon": "https://matrix.org/_matrix/media/v1/download/matrix.org/DHLHpDDgWNNejFmrewvwEAHX",
"example": "#channel",
"nativePattern": "^#[^\\s]+$"
}
}
}
}

View File

@ -2,7 +2,7 @@
"name": "vector-web", "name": "vector-web",
"productName": "Riot", "productName": "Riot",
"main": "electron/src/electron-main.js", "main": "electron/src/electron-main.js",
"version": "0.8.4", "version": "0.9.0",
"description": "A feature-rich client for Matrix.org", "description": "A feature-rich client for Matrix.org",
"author": "Vector Creations Ltd.", "author": "Vector Creations Ltd.",
"repository": { "repository": {
@ -35,7 +35,7 @@
"build:compile": "babel --source-maps -d lib src", "build:compile": "babel --source-maps -d lib src",
"build:bundle": "NODE_ENV=production webpack -p --progress", "build:bundle": "NODE_ENV=production webpack -p --progress",
"build:bundle:dev": "webpack --optimize-occurence-order --progress", "build:bundle:dev": "webpack --optimize-occurence-order --progress",
"build:electron": "build -lwm", "build:electron": "npm run clean && npm run build && cpx electron/config.json webapp/ && build -lwm",
"build": "node scripts/babelcheck.js && npm run build:res && npm run build:config && npm run build:emojione && npm run build:css && npm run build:bundle", "build": "node scripts/babelcheck.js && npm run build:res && npm run build:config && npm run build:emojione && npm run build:css && npm run build:bundle",
"build:dev": "node scripts/babelcheck.js && npm run build:res && npm run build:config && npm run build:emojione && npm run build:css && npm run build:bundle:dev", "build:dev": "node scripts/babelcheck.js && npm run build:res && npm run build:config && npm run build:emojione && npm run build:css && npm run build:bundle:dev",
"dist": "scripts/package.sh", "dist": "scripts/package.sh",
@ -70,10 +70,10 @@
"matrix-react-sdk": "matrix-org/matrix-react-sdk#develop", "matrix-react-sdk": "matrix-org/matrix-react-sdk#develop",
"modernizr": "^3.1.0", "modernizr": "^3.1.0",
"q": "^1.4.1", "q": "^1.4.1",
"react": "^15.2.1", "react": "^15.4.0",
"react-dnd": "^2.1.4", "react-dnd": "^2.1.4",
"react-dnd-html5-backend": "^2.1.2", "react-dnd-html5-backend": "^2.1.2",
"react-dom": "^15.2.1", "react-dom": "^15.4.0",
"react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef",
"sanitize-html": "^1.11.1", "sanitize-html": "^1.11.1",
"ua-parser-js": "^0.7.10", "ua-parser-js": "^0.7.10",
@ -115,8 +115,8 @@
"mocha": "^2.4.5", "mocha": "^2.4.5",
"parallelshell": "^1.2.0", "parallelshell": "^1.2.0",
"phantomjs-prebuilt": "^2.1.7", "phantomjs-prebuilt": "^2.1.7",
"react-addons-perf": "^15.0", "react-addons-perf": "^15.4.0",
"react-addons-test-utils": "^15.0.1", "react-addons-test-utils": "^15.4.0",
"rimraf": "^2.4.3", "rimraf": "^2.4.3",
"source-map-loader": "^0.1.5", "source-map-loader": "^0.1.5",
"webpack": "^1.12.14", "webpack": "^1.12.14",

View File

@ -15,6 +15,11 @@ fi
npm run clean npm run clean
npm run build$dev npm run build$dev
# include the sample config in the tarball. Arguably this should be done by
# `npm run build`, but it's just too painful.
cp config.sample.json webapp/
mkdir -p dist mkdir -p dist
cp -r webapp vector-$version cp -r webapp vector-$version
echo $version > vector-$version/version echo $version > vector-$version/version

View File

@ -22,7 +22,8 @@ module.exports = React.createClass({
displayName: 'ViewSource', displayName: 'ViewSource',
propTypes: { propTypes: {
onFinished: React.PropTypes.func.isRequired content: React.PropTypes.object.isRequired,
onFinished: React.PropTypes.func.isRequired,
}, },
componentDidMount: function() { componentDidMount: function() {
@ -45,10 +46,9 @@ module.exports = React.createClass({
return ( return (
<div className="mx_ViewSource"> <div className="mx_ViewSource">
<pre> <pre>
{JSON.stringify(this.props.mxEvent.event, null, 2)} {JSON.stringify(this.props.content, null, 2)}
</pre> </pre>
</div> </div>
); );
} }
}); });

View File

@ -47,7 +47,16 @@ module.exports = React.createClass({
onViewSourceClick: function() { onViewSourceClick: function() {
var ViewSource = sdk.getComponent('structures.ViewSource'); var ViewSource = sdk.getComponent('structures.ViewSource');
Modal.createDialog(ViewSource, { Modal.createDialog(ViewSource, {
mxEvent: this.props.mxEvent content: this.props.mxEvent.event,
}, 'mx_Dialog_viewsource');
if (this.props.onFinished) this.props.onFinished();
},
onViewClearSourceClick: function() {
const ViewSource = sdk.getComponent('structures.ViewSource');
Modal.createDialog(ViewSource, {
// FIXME: _clearEvent is private
content: this.props.mxEvent._clearEvent,
}, 'mx_Dialog_viewsource'); }, 'mx_Dialog_viewsource');
if (this.props.onFinished) this.props.onFinished(); if (this.props.onFinished) this.props.onFinished();
}, },
@ -97,6 +106,7 @@ module.exports = React.createClass({
var eventStatus = this.props.mxEvent.status; var eventStatus = this.props.mxEvent.status;
var resendButton; var resendButton;
var viewSourceButton; var viewSourceButton;
var viewClearSourceButton;
var redactButton; var redactButton;
var cancelButton; var cancelButton;
var permalinkButton; var permalinkButton;
@ -133,6 +143,14 @@ module.exports = React.createClass({
</div> </div>
); );
if (this.props.mxEvent.getType() !== this.props.mxEvent.getWireType()) {
viewClearSourceButton = (
<div className="mx_MessageContextMenu_field" onClick={this.onViewClearSourceClick}>
View Decrypted Source
</div>
);
}
if (this.props.eventTileOps) { if (this.props.eventTileOps) {
if (this.props.eventTileOps.isWidgetHidden()) { if (this.props.eventTileOps.isWidgetHidden()) {
unhidePreviewButton = ( unhidePreviewButton = (
@ -174,6 +192,7 @@ module.exports = React.createClass({
{redactButton} {redactButton}
{cancelButton} {cancelButton}
{viewSourceButton} {viewSourceButton}
{viewClearSourceButton}
{unhidePreviewButton} {unhidePreviewButton}
{permalinkButton} {permalinkButton}
{UserSettingsStore.isFeatureEnabled('rich_text_editor') ? quoteButton : null} {UserSettingsStore.isFeatureEnabled('rich_text_editor') ? quoteButton : null}

View File

@ -54,7 +54,6 @@ var UpdateChecker = require("./updater");
var q = require('q'); var q = require('q');
var request = require('browser-request'); var request = require('browser-request');
import UAParser from 'ua-parser-js';
import url from 'url'; import url from 'url';
import {parseQs, parseQsFromFragment} from './url_utils'; import {parseQs, parseQsFromFragment} from './url_utils';
@ -120,6 +119,8 @@ var lastLoadedScreen = null;
// so a web page can update the URL bar appropriately. // so a web page can update the URL bar appropriately.
var onNewScreen = function(screen) { var onNewScreen = function(screen) {
console.log("newscreen "+screen); console.log("newscreen "+screen);
// just remember the most recent screen while we are loading, so that the
// user doesn't see the URL bar doing a dance
if (!loaded) { if (!loaded) {
lastLoadedScreen = screen; lastLoadedScreen = screen;
} else { } else {
@ -142,33 +143,7 @@ var makeRegistrationUrl = function() {
'#/register'; '#/register';
} }
function getDefaultDeviceDisplayName() {
// strip query-string and fragment from uri
let u = url.parse(window.location.href);
u.search = "";
u.hash = "";
let app_name = u.format();
let ua = new UAParser();
return app_name + " via " + ua.getBrowser().name +
" on " + ua.getOS().name;
}
window.addEventListener('hashchange', onHashChange); window.addEventListener('hashchange', onHashChange);
window.onload = function() {
console.log("window.onload");
if (!validBrowser) {
return;
}
UpdateChecker.start();
routeUrl(window.location);
loaded = true;
if (lastLoadedScreen) {
onNewScreen(lastLoadedScreen);
lastLoadedScreen = null;
}
}
function getConfig() { function getConfig() {
let deferred = q.defer(); let deferred = q.defer();
@ -259,6 +234,8 @@ async function loadApp() {
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) {
UpdateChecker.start();
var MatrixChat = sdk.getComponent('structures.MatrixChat'); var MatrixChat = sdk.getComponent('structures.MatrixChat');
window.matrixChat = ReactDOM.render( window.matrixChat = ReactDOM.render(
@ -271,10 +248,19 @@ async function loadApp() {
startingFragmentQueryParams={fragparts.params} startingFragmentQueryParams={fragparts.params}
enableGuest={true} enableGuest={true}
onLoadCompleted={onLoadCompleted} onLoadCompleted={onLoadCompleted}
defaultDeviceDisplayName={getDefaultDeviceDisplayName()} defaultDeviceDisplayName={PlatformPeg.get().getDefaultDeviceDisplayName()}
/>, />,
document.getElementById('matrixchat') document.getElementById('matrixchat')
); );
routeUrl(window.location);
// we didn't propagate screen changes to the URL bar while we were loading; do it now.
loaded = true;
if (lastLoadedScreen) {
onNewScreen(lastLoadedScreen);
lastLoadedScreen = null;
}
} }
else { else {
console.error("Browser is missing required features."); console.error("Browser is missing required features.");
@ -285,7 +271,6 @@ async function loadApp() {
validBrowser = true; validBrowser = true;
console.log("User accepts the compatibility risks."); console.log("User accepts the compatibility risks.");
loadApp(); loadApp();
window.onload(); // still do the same code paths for compatible clients
}} />, }} />,
document.getElementById('matrixchat') document.getElementById('matrixchat')
); );

View File

@ -35,6 +35,27 @@ function onUpdateDownloaded(ev, releaseNotes, ver, date, updateURL) {
}); });
} }
function platformFriendlyName() {
console.log(window.process);
switch (window.process.platform) {
case 'darwin':
return 'macOS';
case 'freebsd':
return 'FreeBSD';
case 'openbsd':
return 'OpenBSD';
case 'sunos':
return 'SunOS';
case 'win32':
return 'Windows';
default:
// Sorry, Linux users: you get lumped into here,
// but only because Linux's capitalisation is
// normal. We do care about you.
return window.process.platform[0].toUpperCase + window.process.platform.slice(1);
}
}
export default class ElectronPlatform extends VectorBasePlatform { export default class ElectronPlatform extends VectorBasePlatform {
setNotificationCount(count: number) { setNotificationCount(count: number) {
super.setNotificationCount(count); super.setNotificationCount(count);
@ -101,4 +122,8 @@ export default class ElectronPlatform extends VectorBasePlatform {
// it should exit. // it should exit.
electron.ipcRenderer.send('install_update'); electron.ipcRenderer.send('install_update');
} }
getDefaultDeviceDisplayName() {
return "Riot Desktop on " + platformFriendlyName();
}
} }

View File

@ -39,4 +39,12 @@ export default class VectorBasePlatform extends BasePlatform {
*/ */
installUpdate() { installUpdate() {
} }
/**
* Get a sensible default display name for the
* device Vector is running on
*/
getDefaultDeviceDisplayName() {
return "Unknown device";
}
} }

View File

@ -23,6 +23,9 @@ import request from 'browser-request';
import dis from 'matrix-react-sdk/lib/dispatcher.js'; import dis from 'matrix-react-sdk/lib/dispatcher.js';
import q from 'q'; import q from 'q';
import url from 'url';
import UAParser from 'ua-parser-js';
export default class WebPlatform extends VectorBasePlatform { export default class WebPlatform extends VectorBasePlatform {
constructor() { constructor() {
super(); super();
@ -128,8 +131,18 @@ export default class WebPlatform extends VectorBasePlatform {
_getVersion() { _getVersion() {
const deferred = q.defer(); const deferred = q.defer();
// We add a cachebuster to the request to make sure that we know about
// the most recent version on the origin server. That might not
// actually be the version we'd get on a reload (particularly in the
// presence of intermediate caching proxies), but still: we're trying
// to tell the user that there is a new version.
request( request(
{ method: "GET", url: "version" }, {
method: "GET",
url: "version",
qs: { cachebuster: Date.now() },
},
(err, response, body) => { (err, response, body) => {
if (err || response.status < 200 || response.status >= 300) { if (err || response.status < 200 || response.status >= 300) {
if (err == null) err = { status: response.status }; if (err == null) err = { status: response.status };
@ -170,4 +183,16 @@ export default class WebPlatform extends VectorBasePlatform {
installUpdate() { installUpdate() {
window.location.reload(); window.location.reload();
} }
getDefaultDeviceDisplayName() {
// strip query-string and fragment from uri
let u = url.parse(window.location.href);
u.search = "";
u.hash = "";
let app_name = u.format();
let ua = new UAParser();
return app_name + " via " + ua.getBrowser().name +
" on " + ua.getOS().name;
}
} }

View File

@ -57,7 +57,8 @@ module.exports = {
alias: { alias: {
// alias any requires to the react module to the one in our path, otherwise // alias any requires to the react module to the one in our path, otherwise
// we tend to get the react source included twice when using npm link. // we tend to get the react source included twice when using npm link.
react: path.resolve('./node_modules/react'), "react": path.resolve('./node_modules/react'),
"react-dom": path.resolve('./node_modules/react-dom'),
"react-addons-perf": path.resolve('./node_modules/react-addons-perf'), "react-addons-perf": path.resolve('./node_modules/react-addons-perf'),
// same goes for js-sdk // same goes for js-sdk