Merge branch 'develop' into new-guest-access
|
@ -5,6 +5,7 @@
|
||||||
/key.pem
|
/key.pem
|
||||||
/lib
|
/lib
|
||||||
/node_modules
|
/node_modules
|
||||||
|
/electron/node_modules
|
||||||
/packages/
|
/packages/
|
||||||
/webapp
|
/webapp
|
||||||
/.npmrc
|
/.npmrc
|
||||||
|
|
21
CHANGELOG.md
|
@ -1,3 +1,24 @@
|
||||||
|
Changes in [0.9.9](https://github.com/vector-im/riot-web/releases/tag/v0.9.9) (2017-04-25)
|
||||||
|
==========================================================================================
|
||||||
|
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.9-rc.2...v0.9.9)
|
||||||
|
|
||||||
|
* No changes
|
||||||
|
|
||||||
|
|
||||||
|
Changes in [0.9.9-rc.2](https://github.com/vector-im/riot-web/releases/tag/v0.9.9-rc.2) (2017-04-24)
|
||||||
|
====================================================================================================
|
||||||
|
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.9-rc.1...v0.9.9-rc.2)
|
||||||
|
|
||||||
|
* Fix bug where links to Riot would fail to open.
|
||||||
|
|
||||||
|
|
||||||
|
Changes in [0.9.9-rc.1](https://github.com/vector-im/riot-web/releases/tag/v0.9.9-rc.1) (2017-04-21)
|
||||||
|
====================================================================================================
|
||||||
|
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.8...v0.9.9-rc.1)
|
||||||
|
|
||||||
|
* Update js-sdk and matrix-react-sdk to fix registration without a captcha (https://github.com/vector-im/riot-web/issues/3621)
|
||||||
|
|
||||||
|
|
||||||
Changes in [0.9.8](https://github.com/vector-im/riot-web/releases/tag/v0.9.8) (2017-04-12)
|
Changes in [0.9.8](https://github.com/vector-im/riot-web/releases/tag/v0.9.8) (2017-04-12)
|
||||||
==========================================================================================
|
==========================================================================================
|
||||||
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.8-rc.3...v0.9.8)
|
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.9.8-rc.3...v0.9.8)
|
||||||
|
|
|
@ -135,7 +135,7 @@ To run as a desktop app:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm install electron
|
npm install electron
|
||||||
node_modules/.bin/electron .
|
npm run electron
|
||||||
```
|
```
|
||||||
|
|
||||||
To build packages, use electron-builder. This is configured to output:
|
To build packages, use electron-builder. This is configured to output:
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"brand": "Riot",
|
"brand": "Riot",
|
||||||
"integrations_ui_url": "https://scalar.vector.im/",
|
"integrations_ui_url": "https://scalar.vector.im/",
|
||||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||||
"bug_report_endpoint_url": "https://vector.im/bugs",
|
"bug_report_endpoint_url": "https://riot.im/bugreports/submit",
|
||||||
"enableLabs": true,
|
"enableLabs": true,
|
||||||
"roomDirectory": {
|
"roomDirectory": {
|
||||||
"servers": [
|
"servers": [
|
||||||
|
|
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 673 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 102 KiB |
After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "riot-web",
|
||||||
|
"productName": "Riot",
|
||||||
|
"main": "src/electron-main.js",
|
||||||
|
"version": "0.9.9",
|
||||||
|
"description": "A feature-rich client for Matrix.org",
|
||||||
|
"author": "Vector Creations Ltd.",
|
||||||
|
"dependencies": {
|
||||||
|
"electron-window-state": "^4.1.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,8 @@ const tray = require('./tray');
|
||||||
|
|
||||||
const VectorMenu = require('./vectormenu');
|
const VectorMenu = require('./vectormenu');
|
||||||
|
|
||||||
|
const windowStateKeeper = require('electron-window-state');
|
||||||
|
|
||||||
let vectorConfig = {};
|
let vectorConfig = {};
|
||||||
try {
|
try {
|
||||||
vectorConfig = require('../../webapp/config.json');
|
vectorConfig = require('../../webapp/config.json');
|
||||||
|
@ -187,11 +189,21 @@ electron.app.on('ready', () => {
|
||||||
process.platform == 'win32' ? 'ico' : 'png'
|
process.platform == 'win32' ? 'ico' : 'png'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Load the previous window state with fallback to defaults
|
||||||
|
let mainWindowState = windowStateKeeper({
|
||||||
|
defaultWidth: 1024,
|
||||||
|
defaultHeight: 768,
|
||||||
|
});
|
||||||
|
|
||||||
mainWindow = new electron.BrowserWindow({
|
mainWindow = new electron.BrowserWindow({
|
||||||
icon: icon_path,
|
icon: icon_path,
|
||||||
width: 1024, height: 768,
|
|
||||||
show: false,
|
show: false,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
|
|
||||||
|
x: mainWindowState.x,
|
||||||
|
y: mainWindowState.y,
|
||||||
|
width: mainWindowState.width,
|
||||||
|
height: mainWindowState.height,
|
||||||
});
|
});
|
||||||
mainWindow.loadURL(`file://${__dirname}/../../webapp/index.html`);
|
mainWindow.loadURL(`file://${__dirname}/../../webapp/index.html`);
|
||||||
electron.Menu.setApplicationMenu(VectorMenu);
|
electron.Menu.setApplicationMenu(VectorMenu);
|
||||||
|
@ -230,6 +242,8 @@ electron.app.on('ready', () => {
|
||||||
onLinkContextMenu(ev, params);
|
onLinkContextMenu(ev, params);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mainWindowState.manage(mainWindow);
|
||||||
});
|
});
|
||||||
|
|
||||||
electron.app.on('window-all-closed', () => {
|
electron.app.on('window-all-closed', () => {
|
31
package.json
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "riot-web",
|
"name": "riot-web",
|
||||||
"productName": "Riot",
|
"productName": "Riot",
|
||||||
"main": "electron/src/electron-main.js",
|
"main": "electron_app/src/electron-main.js",
|
||||||
"version": "0.9.8",
|
"version": "0.9.9",
|
||||||
"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": {
|
||||||
|
@ -33,13 +33,15 @@
|
||||||
"build:bundle": "cross-env NODE_ENV=production webpack -p --progress",
|
"build:bundle": "cross-env NODE_ENV=production webpack -p --progress",
|
||||||
"build:bundle:dev": "webpack --optimize-occurence-order --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 && build -wml --ia32 --x64",
|
||||||
"build": "node scripts/babelcheck.js && npm run build:res && npm run build:bundle",
|
"build": "npm run build:res && npm run build:bundle",
|
||||||
"build:dev": "node scripts/babelcheck.js && npm run build:res && npm run build:bundle:dev",
|
"build:dev": "npm run build:res && npm run build:bundle:dev",
|
||||||
"dist": "scripts/package.sh",
|
"dist": "scripts/package.sh",
|
||||||
|
"install:electron": "install-app-deps",
|
||||||
|
"electron": "npm run install:electron && electron .",
|
||||||
"start:res": "node scripts/copy-res.js -w",
|
"start:res": "node scripts/copy-res.js -w",
|
||||||
"start:js": "webpack-dev-server --output-filename=bundles/_dev_/[name].js --output-chunk-file=bundles/_dev_/[name].js -w --progress",
|
"start:js": "webpack-dev-server --output-filename=bundles/_dev_/[name].js --output-chunk-file=bundles/_dev_/[name].js -w --progress",
|
||||||
"start:js:prod": "cross-env NODE_ENV=production webpack-dev-server -w --progress",
|
"start:js:prod": "cross-env NODE_ENV=production webpack-dev-server -w --progress",
|
||||||
"start": "node scripts/babelcheck.js && parallelshell \"npm run start:res\" \"npm run start:js\"",
|
"start": "parallelshell \"npm run start:res\" \"npm run start:js\"",
|
||||||
"start:prod": "parallelshell \"npm run start:res\" \"npm run start:js:prod\"",
|
"start:prod": "parallelshell \"npm run start:res\" \"npm run start:js:prod\"",
|
||||||
"lint": "eslint src/",
|
"lint": "eslint src/",
|
||||||
"lintall": "eslint src/ test/",
|
"lintall": "eslint src/ test/",
|
||||||
|
@ -145,10 +147,12 @@
|
||||||
"dereference": true,
|
"dereference": true,
|
||||||
"//files": "We bundle everything, so we only need to include webapp/",
|
"//files": "We bundle everything, so we only need to include webapp/",
|
||||||
"files": [
|
"files": [
|
||||||
"electron/src/**",
|
"node_modules/**",
|
||||||
"electron/img/**",
|
"src/**",
|
||||||
"webapp/**",
|
"img/**"
|
||||||
"package.json"
|
],
|
||||||
|
"extraResources": [
|
||||||
|
"webapp/**/*"
|
||||||
],
|
],
|
||||||
"linux": {
|
"linux": {
|
||||||
"target": "deb",
|
"target": "deb",
|
||||||
|
@ -159,10 +163,11 @@
|
||||||
},
|
},
|
||||||
"win": {
|
"win": {
|
||||||
"target": "squirrel"
|
"target": "squirrel"
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"buildResources": "electron_app/build",
|
||||||
|
"output": "electron_app/dist",
|
||||||
|
"app": "electron_app"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"directories": {
|
|
||||||
"buildResources": "electron/build",
|
|
||||||
"output": "electron/dist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
release.sh
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Script to perform a release of vector-web.
|
# Script to perform a release of vector-web.
|
||||||
#
|
#
|
||||||
|
@ -9,4 +9,17 @@ set -e
|
||||||
|
|
||||||
cd `dirname $0`
|
cd `dirname $0`
|
||||||
|
|
||||||
|
|
||||||
|
# bump Electron's package.json first
|
||||||
|
release="${1#v}"
|
||||||
|
tag="v${release}"
|
||||||
|
echo "electron npm version"
|
||||||
|
|
||||||
|
cd electron_app
|
||||||
|
npm version --no-git-tag-version "$release"
|
||||||
|
git commit package.json -m "$tag"
|
||||||
|
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
exec ./node_modules/matrix-js-sdk/release.sh -z "$@"
|
exec ./node_modules/matrix-js-sdk/release.sh -z "$@"
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
var exec = require('child_process').exec;
|
|
||||||
|
|
||||||
// Makes sure the babel executable in the path is babel 6 (or greater), not
|
|
||||||
// babel 5, which it is if you upgrade from an older version of react-sdk and
|
|
||||||
// run 'npm install' since the package has changed to babel-cli, so 'babel'
|
|
||||||
// remains installed and the executable in node_modules/.bin remains as babel
|
|
||||||
// 5.
|
|
||||||
|
|
||||||
// This script is duplicated from matrix-react-sdk because it can't reliably
|
|
||||||
// be pulled in from react-sdk while npm install is failing, as it will do
|
|
||||||
// if the environment is in the erroneous state this script checks for.
|
|
||||||
|
|
||||||
exec("babel -V", function (error, stdout, stderr) {
|
|
||||||
if ((error && error.code) || parseInt(stdout.substr(0,1), 10) < 6) {
|
|
||||||
console.log("\033[31m\033[1m"+
|
|
||||||
'*****************************************\n'+
|
|
||||||
'* vector-web has moved to babel 6 *\n'+
|
|
||||||
'* Please "rm -rf node_modules && npm i" *\n'+
|
|
||||||
'* then restore links as appropriate *\n'+
|
|
||||||
'*****************************************\n'+
|
|
||||||
"\033[91m");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -90,8 +90,8 @@ npm run build:electron
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
distdir="$builddir/electron/dist"
|
distdir="$builddir/electron_app/dist"
|
||||||
pubdir="$projdir/electron/pub"
|
pubdir="$projdir/electron_app/pub"
|
||||||
rm -r "$pubdir" || true
|
rm -r "$pubdir" || true
|
||||||
mkdir -p "$pubdir"
|
mkdir -p "$pubdir"
|
||||||
|
|
||||||
|
@ -120,11 +120,11 @@ cp $distdir/win/*.nupkg "$pubdir/update/win32/x64/"
|
||||||
cp $distdir/win/RELEASES "$pubdir/update/win32/x64/"
|
cp $distdir/win/RELEASES "$pubdir/update/win32/x64/"
|
||||||
|
|
||||||
# Move the debs to the main project dir's dist folder
|
# Move the debs to the main project dir's dist folder
|
||||||
rm -r "$projdir/electron/dist" || true
|
rm -r "$projdir/electron_app/dist" || true
|
||||||
mkdir -p "$projdir/electron/dist"
|
mkdir -p "$projdir/electron_app/dist"
|
||||||
cp $distdir/*.deb "$projdir/electron/dist/"
|
cp $distdir/*.deb "$projdir/electron_app/dist/"
|
||||||
|
|
||||||
rm -rf "$builddir"
|
rm -rf "$builddir"
|
||||||
|
|
||||||
echo "Riot Desktop is ready to go in $pubdir: this directory can be hosted on your web server."
|
echo "Riot Desktop is ready to go in $pubdir: this directory can be hosted on your web server."
|
||||||
echo "deb archives are in electron/dist/ - these should be added into your debian repository"
|
echo "deb archives are in electron_app/dist/ - these should be added into your debian repository"
|
||||||
|
|
|
@ -4,16 +4,24 @@ use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
|
|
||||||
use Net::GitHub;
|
use Net::GitHub;
|
||||||
use DateTime;
|
use Time::Moment;
|
||||||
use DateTime::Format::ISO8601;
|
use Term::ReadPassword;
|
||||||
|
|
||||||
|
# This version of the script emits the cumulative number of bugs, split into open & closed
|
||||||
|
# suitable for drawing the 'top' and 'bottom' of a burndown graph.
|
||||||
|
#
|
||||||
|
# N.B. this doesn't take into account issues changing priority over time, but only their most recent priority.
|
||||||
|
#
|
||||||
|
# If you want instead the number of open issues on a given day, then look at issues-no-state.pl
|
||||||
|
|
||||||
my $gh = Net::GitHub->new(
|
my $gh = Net::GitHub->new(
|
||||||
login => 'ara4n', pass => 'secret'
|
login => 'ara4n', pass => read_password("github password: "),
|
||||||
);
|
);
|
||||||
|
|
||||||
$gh->set_default_user_repo('vector-im', 'vector-web');
|
$gh->set_default_user_repo('vector-im', 'vector-web');
|
||||||
|
|
||||||
my @issues = $gh->issue->repos_issues({ state => 'all', milestone => 3 });
|
#my @issues = $gh->issue->repos_issues({ state => 'all', milestone => 3 });
|
||||||
|
my @issues = $gh->issue->repos_issues({ state => 'all' });
|
||||||
while ($gh->issue->has_next_page) {
|
while ($gh->issue->has_next_page) {
|
||||||
push @issues, $gh->issue->next_page;
|
push @issues, $gh->issue->next_page;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +38,7 @@ while ($gh->issue->has_next_page) {
|
||||||
|
|
||||||
my $days = {};
|
my $days = {};
|
||||||
my $schema = {};
|
my $schema = {};
|
||||||
my $now = DateTime->now();
|
my $now = Time::Moment->now;
|
||||||
|
|
||||||
foreach my $issue (@issues) {
|
foreach my $issue (@issues) {
|
||||||
next if ($issue->{pull_request});
|
next if ($issue->{pull_request});
|
||||||
|
@ -56,10 +64,10 @@ foreach my $issue (@issues) {
|
||||||
my $priority = &$extract_labels(qw(p1 p2 p3 p4 p5)) || "unprioritised";
|
my $priority = &$extract_labels(qw(p1 p2 p3 p4 p5)) || "unprioritised";
|
||||||
my $severity = &$extract_labels(qw(minor major critical cosmetic network)) || "no-severity";
|
my $severity = &$extract_labels(qw(minor major critical cosmetic network)) || "no-severity";
|
||||||
|
|
||||||
my $start = DateTime::Format::ISO8601->parse_datetime($issue->{created_at});
|
my $start = Time::Moment->from_string($issue->{created_at});
|
||||||
|
|
||||||
do {
|
do {
|
||||||
my $ymd = $start->ymd();
|
my $ymd = $start->strftime('%F');
|
||||||
|
|
||||||
$days->{ $ymd }->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
|
$days->{ $ymd }->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
|
||||||
$schema->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
|
$schema->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
|
||||||
|
@ -68,13 +76,14 @@ foreach my $issue (@issues) {
|
||||||
$schema->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
|
$schema->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$start = $start->add(days => 1);
|
$start = $start->plus_days(1);
|
||||||
} while (DateTime->compare($start, $now) < 0);
|
# print STDERR "^";
|
||||||
|
} while ($start->compare($now) < 0);
|
||||||
|
|
||||||
if ($state eq 'closed') {
|
if ($state eq 'closed') {
|
||||||
my $end = DateTime::Format::ISO8601->parse_datetime($issue->{closed_at});
|
my $end = Time::Moment->from_string($issue->{closed_at});
|
||||||
do {
|
do {
|
||||||
my $ymd = $end->ymd();
|
my $ymd = $end->strftime('%F');
|
||||||
|
|
||||||
$days->{ $ymd }->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
|
$days->{ $ymd }->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
|
||||||
$schema->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
|
$schema->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ total }++;
|
||||||
|
@ -83,9 +92,12 @@ foreach my $issue (@issues) {
|
||||||
$schema->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
|
$schema->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$end = $end->add(days => 1);
|
$end = $end->plus_days(1);
|
||||||
} while (DateTime->compare($end, $now) < 0);
|
} while ($end->compare($now) < 0);
|
||||||
|
# print STDERR "v";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# print STDERR "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
print "day,";
|
print "day,";
|
||||||
|
|
|
@ -6,14 +6,22 @@ use strict;
|
||||||
use Net::GitHub;
|
use Net::GitHub;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use DateTime::Format::ISO8601;
|
use DateTime::Format::ISO8601;
|
||||||
|
use Term::ReadPassword;
|
||||||
|
|
||||||
|
# This version of the script emits the total number of bugs open on a given day,
|
||||||
|
# split by various tags.
|
||||||
|
#
|
||||||
|
# If you want instead the cumulative number of open & closed issues on a given day,
|
||||||
|
# then look at issues-burndown.pl
|
||||||
|
|
||||||
my $gh = Net::GitHub->new(
|
my $gh = Net::GitHub->new(
|
||||||
login => 'ara4n', pass => 'secret'
|
login => 'ara4n', pass => read_password("github password: "),
|
||||||
);
|
);
|
||||||
|
|
||||||
$gh->set_default_user_repo('vector-im', 'vector-web');
|
$gh->set_default_user_repo('vector-im', 'vector-web');
|
||||||
|
|
||||||
my @issues = $gh->issue->repos_issues({ state => 'all', milestone => 3 });
|
#my @issues = $gh->issue->repos_issues({ state => 'all', milestone => 3 });
|
||||||
|
my @issues = $gh->issue->repos_issues({ state => 'all' });
|
||||||
while ($gh->issue->has_next_page) {
|
while ($gh->issue->has_next_page) {
|
||||||
push @issues, $gh->issue->next_page;
|
push @issues, $gh->issue->next_page;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ cp "$tmpdir/256.png" "$tmpdir/Riot.iconset/icon_256x256.png"
|
||||||
cp "$tmpdir/512.png" "$tmpdir/Riot.iconset/icon_256x256@2x.png"
|
cp "$tmpdir/512.png" "$tmpdir/Riot.iconset/icon_256x256@2x.png"
|
||||||
cp "$tmpdir/512.png" "$tmpdir/Riot.iconset/icon_512x512.png"
|
cp "$tmpdir/512.png" "$tmpdir/Riot.iconset/icon_512x512.png"
|
||||||
cp "$tmpdir/1024.png" "$tmpdir/Riot.iconset/icon_512x512@2x.png"
|
cp "$tmpdir/1024.png" "$tmpdir/Riot.iconset/icon_512x512@2x.png"
|
||||||
iconutil -c icns -o electron/build/icon.icns "$tmpdir/Riot.iconset"
|
iconutil -c icns -o electron_app/build/icon.icns "$tmpdir/Riot.iconset"
|
||||||
|
|
||||||
cp "$tmpdir/36.png" "res/vector-icons/android-chrome-36x36.png"
|
cp "$tmpdir/36.png" "res/vector-icons/android-chrome-36x36.png"
|
||||||
cp "$tmpdir/48.png" "res/vector-icons/android-chrome-48x48.png"
|
cp "$tmpdir/48.png" "res/vector-icons/android-chrome-48x48.png"
|
||||||
|
@ -79,15 +79,17 @@ cp "$tmpdir/144.png" "res/vector-icons/mstile-144x144.png"
|
||||||
cp "$tmpdir/150.png" "res/vector-icons/mstile-150x150.png"
|
cp "$tmpdir/150.png" "res/vector-icons/mstile-150x150.png"
|
||||||
cp "$tmpdir/310.png" "res/vector-icons/mstile-310x310.png"
|
cp "$tmpdir/310.png" "res/vector-icons/mstile-310x310.png"
|
||||||
cp "$tmpdir/310x150.png" "res/vector-icons/mstile-310x150.png"
|
cp "$tmpdir/310x150.png" "res/vector-icons/mstile-310x150.png"
|
||||||
|
cp "$tmpdir/180.png" "electron_app/img/riot.png"
|
||||||
|
|
||||||
convert "$tmpdir/16.png" "$tmpdir/32.png" "$tmpdir/64.png" "$tmpdir/128.png" "$tmpdir/256.png" "res/vector-icons/favicon.ico"
|
convert "$tmpdir/16.png" "$tmpdir/32.png" "$tmpdir/64.png" "$tmpdir/128.png" "$tmpdir/256.png" "res/vector-icons/favicon.ico"
|
||||||
|
|
||||||
cp "res/vector-icons/favicon.ico" "electron/build/icon.ico"
|
cp "res/vector-icons/favicon.ico" "electron_app/build/icon.ico"
|
||||||
|
cp "res/vector-icons/favicon.ico" "electron_app/img/riot.ico"
|
||||||
|
|
||||||
# https://github.com/electron-userland/electron-builder/blob/3f97b86993d4ea5172e562b182230a194de0f621/src/targets/LinuxTargetHelper.ts#L127
|
# https://github.com/electron-userland/electron-builder/blob/3f97b86993d4ea5172e562b182230a194de0f621/src/targets/LinuxTargetHelper.ts#L127
|
||||||
for i in 24 96 16 48 64 128 256 512
|
for i in 24 96 16 48 64 128 256 512
|
||||||
do
|
do
|
||||||
cp "$tmpdir/$i.png" "electron/build/icons/${i}x${i}.png"
|
cp "$tmpdir/$i.png" "electron_app/build/icons/${i}x${i}.png"
|
||||||
done
|
done
|
||||||
|
|
||||||
rm -r "$tmpdir"
|
rm -r "$tmpdir"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
@ -22,7 +22,14 @@ 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
|
|
||||||
|
# if $version looks like semver with leading v, strip it before writing to file
|
||||||
|
if [[ ${version} =~ ^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(-.+)?$ ]]; then
|
||||||
|
echo ${version:1} > vector-$version/version
|
||||||
|
else
|
||||||
|
echo ${version} > vector-$version/version
|
||||||
|
fi
|
||||||
|
|
||||||
tar chvzf dist/vector-$version.tar.gz vector-$version
|
tar chvzf dist/vector-$version.tar.gz vector-$version
|
||||||
rm -r vector-$version
|
rm -r vector-$version
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2017 Vector Creations 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.
|
||||||
|
@ -14,13 +15,8 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
import React from 'react';
|
||||||
|
import sdk from 'matrix-react-sdk';
|
||||||
var React = require('react');
|
|
||||||
var ReactDOM = require('react-dom');
|
|
||||||
var sdk = require('matrix-react-sdk')
|
|
||||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
|
||||||
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
|
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'BottomLeftMenu',
|
displayName: 'BottomLeftMenu',
|
||||||
|
@ -30,121 +26,28 @@ module.exports = React.createClass({
|
||||||
teamToken: React.PropTypes.string,
|
teamToken: React.PropTypes.string,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
|
||||||
return({
|
|
||||||
directoryHover : false,
|
|
||||||
roomsHover : false,
|
|
||||||
homeHover: false,
|
|
||||||
peopleHover : false,
|
|
||||||
settingsHover : false,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// Room events
|
|
||||||
onDirectoryClick: function() {
|
|
||||||
dis.dispatch({ action: 'view_room_directory' });
|
|
||||||
},
|
|
||||||
|
|
||||||
onDirectoryMouseEnter: function() {
|
|
||||||
this.setState({ directoryHover: true });
|
|
||||||
},
|
|
||||||
|
|
||||||
onDirectoryMouseLeave: function() {
|
|
||||||
this.setState({ directoryHover: false });
|
|
||||||
},
|
|
||||||
|
|
||||||
onRoomsClick: function() {
|
|
||||||
dis.dispatch({ action: 'view_create_room' });
|
|
||||||
},
|
|
||||||
|
|
||||||
onRoomsMouseEnter: function() {
|
|
||||||
this.setState({ roomsHover: true });
|
|
||||||
},
|
|
||||||
|
|
||||||
onRoomsMouseLeave: function() {
|
|
||||||
this.setState({ roomsHover: false });
|
|
||||||
},
|
|
||||||
|
|
||||||
// Home button events
|
|
||||||
onHomeClick: function() {
|
|
||||||
dis.dispatch({ action: 'view_home_page' });
|
|
||||||
},
|
|
||||||
|
|
||||||
onHomeMouseEnter: function() {
|
|
||||||
this.setState({ homeHover: true });
|
|
||||||
},
|
|
||||||
|
|
||||||
onHomeMouseLeave: function() {
|
|
||||||
this.setState({ homeHover: false });
|
|
||||||
},
|
|
||||||
|
|
||||||
// People events
|
|
||||||
onPeopleClick: function() {
|
|
||||||
dis.dispatch({ action: 'view_create_chat' });
|
|
||||||
},
|
|
||||||
|
|
||||||
onPeopleMouseEnter: function() {
|
|
||||||
this.setState({ peopleHover: true });
|
|
||||||
},
|
|
||||||
|
|
||||||
onPeopleMouseLeave: function() {
|
|
||||||
this.setState({ peopleHover: false });
|
|
||||||
},
|
|
||||||
|
|
||||||
// Settings events
|
|
||||||
onSettingsClick: function() {
|
|
||||||
dis.dispatch({ action: 'view_user_settings' });
|
|
||||||
},
|
|
||||||
|
|
||||||
onSettingsMouseEnter: function() {
|
|
||||||
this.setState({ settingsHover: true });
|
|
||||||
},
|
|
||||||
|
|
||||||
onSettingsMouseLeave: function() {
|
|
||||||
this.setState({ settingsHover: false });
|
|
||||||
},
|
|
||||||
|
|
||||||
// Get the label/tooltip to show
|
|
||||||
getLabel: function(label, show) {
|
|
||||||
if (show) {
|
|
||||||
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
|
|
||||||
return <RoomTooltip className="mx_BottomLeftMenu_tooltip" label={label} />;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var TintableSvg = sdk.getComponent('elements.TintableSvg');
|
const HomeButton = sdk.getComponent('elements.HomeButton');
|
||||||
|
const StartChatButton = sdk.getComponent('elements.StartChatButton');
|
||||||
|
const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton');
|
||||||
|
const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton');
|
||||||
|
const SettingsButton = sdk.getComponent('elements.SettingsButton');
|
||||||
|
|
||||||
var homeButton;
|
var homeButton;
|
||||||
if (this.props.teamToken) {
|
if (this.props.teamToken) {
|
||||||
homeButton = (
|
homeButton = <HomeButton tooltip={true} />;
|
||||||
<AccessibleButton className="mx_BottomLeftMenu_homePage" onClick={ this.onHomeClick } onMouseEnter={ this.onHomeMouseEnter } onMouseLeave={ this.onHomeMouseLeave } >
|
|
||||||
<TintableSvg src="img/icons-home.svg" width="25" height="25" />
|
|
||||||
{ this.getLabel("Welcome page", this.state.homeHover) }
|
|
||||||
</AccessibleButton>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_BottomLeftMenu">
|
<div className="mx_BottomLeftMenu">
|
||||||
<div className="mx_BottomLeftMenu_options">
|
<div className="mx_BottomLeftMenu_options">
|
||||||
{ homeButton }
|
{ homeButton }
|
||||||
<AccessibleButton className="mx_BottomLeftMenu_people" onClick={ this.onPeopleClick } onMouseEnter={ this.onPeopleMouseEnter } onMouseLeave={ this.onPeopleMouseLeave } >
|
<StartChatButton tooltip={true} />
|
||||||
<TintableSvg src="img/icons-people.svg" width="25" height="25" />
|
<RoomDirectoryButton tooltip={true} />
|
||||||
{ this.getLabel("Start chat", this.state.peopleHover) }
|
<CreateRoomButton tooltip={true} />
|
||||||
</AccessibleButton>
|
<span className="mx_BottomLeftMenu_settings">
|
||||||
<AccessibleButton className="mx_BottomLeftMenu_directory" onClick={ this.onDirectoryClick } onMouseEnter={ this.onDirectoryMouseEnter } onMouseLeave={ this.onDirectoryMouseLeave } >
|
<SettingsButton tooltip={true} />
|
||||||
<TintableSvg src="img/icons-directory.svg" width="25" height="25"/>
|
</span>
|
||||||
{ this.getLabel("Room directory", this.state.directoryHover) }
|
|
||||||
</AccessibleButton>
|
|
||||||
<AccessibleButton className="mx_BottomLeftMenu_createRoom" onClick={ this.onRoomsClick } onMouseEnter={ this.onRoomsMouseEnter } onMouseLeave={ this.onRoomsMouseLeave } >
|
|
||||||
<TintableSvg src="img/icons-create-room.svg" width="25" height="25" />
|
|
||||||
{ this.getLabel("Create new room", this.state.roomsHover) }
|
|
||||||
</AccessibleButton>
|
|
||||||
<AccessibleButton className="mx_BottomLeftMenu_settings" onClick={ this.onSettingsClick } onMouseEnter={ this.onSettingsMouseEnter } onMouseLeave={ this.onSettingsMouseLeave } >
|
|
||||||
<TintableSvg src="img/icons-settings.svg" width="25" height="25" />
|
|
||||||
{ this.getLabel("Settings", this.state.settingsHover) }
|
|
||||||
</AccessibleButton>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -204,7 +204,7 @@ module.exports = React.createClass({
|
||||||
}).done(() => {
|
}).done(() => {
|
||||||
modal.close();
|
modal.close();
|
||||||
this.refreshRoomList();
|
this.refreshRoomList();
|
||||||
}, function(err) {
|
}, (err) => {
|
||||||
modal.close();
|
modal.close();
|
||||||
this.refreshRoomList();
|
this.refreshRoomList();
|
||||||
console.error("Failed to " + step + ": " + err);
|
console.error("Failed to " + step + ": " + err);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
Copyright 2017 Vector Creations Ltd
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -29,6 +30,7 @@ var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
|
||||||
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
|
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
|
||||||
var ConstantTimeDispatcher = require('matrix-react-sdk/lib/ConstantTimeDispatcher');
|
var ConstantTimeDispatcher = require('matrix-react-sdk/lib/ConstantTimeDispatcher');
|
||||||
var RoomSubListHeader = require('./RoomSubListHeader.js');
|
var RoomSubListHeader = require('./RoomSubListHeader.js');
|
||||||
|
import Modal from 'matrix-react-sdk/lib/Modal';
|
||||||
|
|
||||||
// turn this on for drag & drop console debugging galore
|
// turn this on for drag & drop console debugging galore
|
||||||
var debug = false;
|
var debug = false;
|
||||||
|
@ -82,6 +84,8 @@ var RoomSubList = React.createClass({
|
||||||
incomingCall: React.PropTypes.object,
|
incomingCall: React.PropTypes.object,
|
||||||
onShowMoreRooms: React.PropTypes.func,
|
onShowMoreRooms: React.PropTypes.func,
|
||||||
searchFilter: React.PropTypes.string,
|
searchFilter: React.PropTypes.string,
|
||||||
|
emptyContent: React.PropTypes.node, // content shown if the list is empty
|
||||||
|
headerItems: React.PropTypes.node, // content shown in the sublist header
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -468,16 +472,15 @@ var RoomSubList = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var connectDropTarget = this.props.connectDropTarget;
|
var connectDropTarget = this.props.connectDropTarget;
|
||||||
var RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget');
|
|
||||||
var TruncatedList = sdk.getComponent('elements.TruncatedList');
|
var TruncatedList = sdk.getComponent('elements.TruncatedList');
|
||||||
|
|
||||||
var label = this.props.collapsed ? null : this.props.label;
|
var label = this.props.collapsed ? null : this.props.label;
|
||||||
|
|
||||||
//console.log("render: " + JSON.stringify(this.state.sortedList));
|
let content;
|
||||||
|
if (this.state.sortedList.length == 0) {
|
||||||
var target;
|
content = this.props.emptyContent;
|
||||||
if (this.state.sortedList.length == 0 && this.props.editable) {
|
} else {
|
||||||
target = <RoomDropTarget label={ 'Drop here to ' + this.props.verb }/>;
|
content = this.makeRoomTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
var roomCount = this.props.list.length > 0 ? this.props.list.length : '';
|
var roomCount = this.props.list.length > 0 ? this.props.list.length : '';
|
||||||
|
@ -497,8 +500,7 @@ var RoomSubList = React.createClass({
|
||||||
if (!this.state.hidden) {
|
if (!this.state.hidden) {
|
||||||
subList = <TruncatedList className={ classes } truncateAt={this.state.truncateAt}
|
subList = <TruncatedList className={ classes } truncateAt={this.state.truncateAt}
|
||||||
createOverflowElement={this._createOverflowTile} >
|
createOverflowElement={this._createOverflowTile} >
|
||||||
{ target }
|
{ content }
|
||||||
{ this.makeRoomTiles() }
|
|
||||||
</TruncatedList>;
|
</TruncatedList>;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -520,6 +522,7 @@ var RoomSubList = React.createClass({
|
||||||
roomNotificationCount={ this.roomNotificationCount() }
|
roomNotificationCount={ this.roomNotificationCount() }
|
||||||
onClick={ this.onClick }
|
onClick={ this.onClick }
|
||||||
onHeaderClick={ this.props.onHeaderClick }
|
onHeaderClick={ this.props.onHeaderClick }
|
||||||
|
headerItems={this.props.headerItems}
|
||||||
/>
|
/>
|
||||||
{ subList }
|
{ subList }
|
||||||
</div>
|
</div>
|
||||||
|
@ -541,6 +544,7 @@ var RoomSubList = React.createClass({
|
||||||
roomNotificationCount={ this.roomNotificationCount() }
|
roomNotificationCount={ this.roomNotificationCount() }
|
||||||
onClick={ this.onClick }
|
onClick={ this.onClick }
|
||||||
onHeaderClick={ this.props.onHeaderClick }
|
onHeaderClick={ this.props.onHeaderClick }
|
||||||
|
headerItems={this.props.headerItems}
|
||||||
/>
|
/>
|
||||||
: undefined }
|
: undefined }
|
||||||
{ (this.props.showSpinner && !this.state.hidden) ? <Loader /> : undefined }
|
{ (this.props.showSpinner && !this.state.hidden) ? <Loader /> : undefined }
|
||||||
|
|
|
@ -14,16 +14,11 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
import React from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
var React = require('react');
|
import sdk from 'matrix-react-sdk';
|
||||||
var ReactDOM = require('react-dom');
|
import { formatCount } from 'matrix-react-sdk/lib/utils/FormattingUtils';
|
||||||
var classNames = require('classnames');
|
import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
|
||||||
var sdk = require('matrix-react-sdk')
|
|
||||||
var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
|
|
||||||
var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
|
|
||||||
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
|
|
||||||
var ConstantTimeDispatcher = require('matrix-react-sdk/lib/ConstantTimeDispatcher');
|
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'RoomSubListHeader',
|
displayName: 'RoomSubListHeader',
|
||||||
|
@ -42,6 +37,7 @@ module.exports = React.createClass({
|
||||||
hidden: React.PropTypes.bool,
|
hidden: React.PropTypes.bool,
|
||||||
onClick: React.PropTypes.func,
|
onClick: React.PropTypes.func,
|
||||||
onHeaderClick: React.PropTypes.func,
|
onHeaderClick: React.PropTypes.func,
|
||||||
|
headerItems: React.PropTypes.node, // content shown in the sublist header
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -63,35 +59,34 @@ module.exports = React.createClass({
|
||||||
// },
|
// },
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
|
|
||||||
var subListNotifications = this.props.roomNotificationCount;
|
const subListNotifications = this.props.roomNotificationCount;
|
||||||
var subListNotifCount = subListNotifications[0];
|
const subListNotifCount = subListNotifications[0];
|
||||||
var subListNotifHighlight = subListNotifications[1];
|
const subListNotifHighlight = subListNotifications[1];
|
||||||
|
|
||||||
var chevronClasses = classNames({
|
const chevronClasses = classNames({
|
||||||
'mx_RoomSubList_chevron': true,
|
'mx_RoomSubList_chevron': true,
|
||||||
'mx_RoomSubList_chevronRight': this.props.hidden,
|
'mx_RoomSubList_chevronRight': this.props.hidden,
|
||||||
'mx_RoomSubList_chevronDown': !this.props.hidden,
|
'mx_RoomSubList_chevronDown': !this.props.hidden,
|
||||||
});
|
});
|
||||||
|
|
||||||
var badgeClasses = classNames({
|
const badgeClasses = classNames({
|
||||||
'mx_RoomSubList_badge': true,
|
'mx_RoomSubList_badge': true,
|
||||||
'mx_RoomSubList_badgeHighlight': subListNotifHighlight,
|
'mx_RoomSubList_badgeHighlight': subListNotifHighlight,
|
||||||
});
|
});
|
||||||
|
|
||||||
var badge;
|
let badge;
|
||||||
if (subListNotifCount > 0) {
|
if (subListNotifCount > 0) {
|
||||||
badge = <div className={badgeClasses}>{ FormattingUtils.formatCount(subListNotifCount) }</div>;
|
badge = <div className={badgeClasses}>{ formatCount(subListNotifCount) }</div>;
|
||||||
}
|
} else if (subListNotifHighlight) {
|
||||||
else if (subListNotifHighlight) {
|
|
||||||
badge = <div className={badgeClasses}>!</div>;
|
badge = <div className={badgeClasses}>!</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When collapsed, allow a long hover on the header to show user
|
// When collapsed, allow a long hover on the header to show user
|
||||||
// the full tag name and room count
|
// the full tag name and room count
|
||||||
var title;
|
let title;
|
||||||
var roomCount = this.props.roomCount;
|
const roomCount = this.props.roomCount;
|
||||||
if (this.props.collapsed) {
|
if (this.props.collapsed) {
|
||||||
title = this.props.label;
|
title = this.props.label;
|
||||||
if (roomCount !== '') {
|
if (roomCount !== '') {
|
||||||
|
@ -99,9 +94,9 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var incomingCall;
|
let incomingCall;
|
||||||
if (this.props.isIncomingCallRoom) {
|
if (this.props.isIncomingCallRoom) {
|
||||||
var IncomingCallBox = sdk.getComponent("voip.IncomingCallBox");
|
const IncomingCallBox = sdk.getComponent("voip.IncomingCallBox");
|
||||||
incomingCall = <IncomingCallBox className="mx_RoomSubList_incomingCall" incomingCall={ this.props.incomingCall }/>;
|
incomingCall = <IncomingCallBox className="mx_RoomSubList_incomingCall" incomingCall={ this.props.incomingCall }/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +104,7 @@ module.exports = React.createClass({
|
||||||
<div className="mx_RoomSubList_labelContainer" title={ title } ref="header">
|
<div className="mx_RoomSubList_labelContainer" title={ title } ref="header">
|
||||||
<AccessibleButton onClick={ this.props.onClick } className="mx_RoomSubList_label" tabIndex="0">
|
<AccessibleButton onClick={ this.props.onClick } className="mx_RoomSubList_label" tabIndex="0">
|
||||||
{ this.props.collapsed ? '' : this.props.label }
|
{ this.props.collapsed ? '' : this.props.label }
|
||||||
|
{this.props.headerItems}
|
||||||
<div className="mx_RoomSubList_roomCount">{ roomCount }</div>
|
<div className="mx_RoomSubList_roomCount">{ roomCount }</div>
|
||||||
<div className={chevronClasses}></div>
|
<div className={chevronClasses}></div>
|
||||||
{ badge }
|
{ badge }
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
@import "./matrix-react-sdk/views/elements/_MemberEventListSummary.scss";
|
@import "./matrix-react-sdk/views/elements/_MemberEventListSummary.scss";
|
||||||
@import "./matrix-react-sdk/views/elements/_ProgressBar.scss";
|
@import "./matrix-react-sdk/views/elements/_ProgressBar.scss";
|
||||||
@import "./matrix-react-sdk/views/elements/_RichText.scss";
|
@import "./matrix-react-sdk/views/elements/_RichText.scss";
|
||||||
|
@import "./matrix-react-sdk/views/elements/_RoleButton.scss";
|
||||||
@import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss";
|
@import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss";
|
||||||
@import "./matrix-react-sdk/views/login/_ServerConfig.scss";
|
@import "./matrix-react-sdk/views/login/_ServerConfig.scss";
|
||||||
@import "./matrix-react-sdk/views/messages/_MEmoteBody.scss";
|
@import "./matrix-react-sdk/views/messages/_MEmoteBody.scss";
|
||||||
|
|
|
@ -160,7 +160,8 @@ hr.mx_RoomView_myReadMarker {
|
||||||
border-bottom: solid 1px $accent-color;
|
border-bottom: solid 1px $accent-color;
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 5px;
|
top: -1px;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_statusArea {
|
.mx_RoomView_statusArea {
|
||||||
|
|
|
@ -20,6 +20,7 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_TextualEvent.mx_MemberEventListSummary_summary {
|
.mx_TextualEvent.mx_MemberEventListSummary_summary {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberEventListSummary_avatars {
|
.mx_MemberEventListSummary_avatars {
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
Copyright 2107 Vector Creations 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.mx_RoleButton {
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoleButton object {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoleButton_tooltip {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
top: -25px;
|
||||||
|
left: 6px;
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2107 Vector Creations 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.
|
||||||
|
@ -37,3 +38,25 @@ limitations under the License.
|
||||||
.mx_RoomList_scrollbar .gm-scrollbar.-vertical {
|
.mx_RoomList_scrollbar .gm-scrollbar.-vertical {
|
||||||
z-index: 6;
|
z-index: 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_RoomList_emptySubListTip {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-left: 18px;
|
||||||
|
margin-right: 18px;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
padding: 5px;
|
||||||
|
border: 1px dashed $accent-color;
|
||||||
|
color: $primary-fg-color;
|
||||||
|
background-color: $droptarget-bg-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomList_emptySubListTip .mx_RoleButton {
|
||||||
|
vertical-align: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomList_headerButtons {
|
||||||
|
position: absolute;
|
||||||
|
right: 60px;
|
||||||
|
}
|
||||||
|
|
|
@ -64,43 +64,25 @@ limitations under the License.
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_homePage,
|
.collapsed .mx_RoleButton {
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_directory,
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_people,
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_settings {
|
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapsed .mx_BottomLeftMenu_homePage,
|
|
||||||
.collapsed .mx_BottomLeftMenu_directory,
|
|
||||||
.collapsed .mx_BottomLeftMenu_createRoom,
|
|
||||||
.collapsed .mx_BottomLeftMenu_people,
|
|
||||||
.collapsed .mx_BottomLeftMenu_settings {
|
|
||||||
margin-right: 0px ! important;
|
margin-right: 0px ! important;
|
||||||
padding-top: 3px ! important;
|
padding-top: 3px ! important;
|
||||||
padding-bottom: 3px ! important;
|
padding-bottom: 3px ! important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_homePage,
|
.mx_BottomLeftMenu_options .mx_RoleButton {
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_directory,
|
margin-left: 0px;
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_people {
|
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_settings {
|
.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings .mx_RoleButton {
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_LeftPanel.collapsed .mx_BottomLeftMenu_settings {
|
.mx_LeftPanel.collapsed .mx_BottomLeftMenu_settings {
|
||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu_tooltip {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
top: -25px;
|
|
||||||
left: 6px;
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,13 +20,11 @@ limitations under the License.
|
||||||
import VectorBasePlatform from './VectorBasePlatform';
|
import VectorBasePlatform from './VectorBasePlatform';
|
||||||
import dis from 'matrix-react-sdk/lib/dispatcher';
|
import dis from 'matrix-react-sdk/lib/dispatcher';
|
||||||
import q from 'q';
|
import q from 'q';
|
||||||
|
import electron, {remote} from 'electron';
|
||||||
const electron = require('electron');
|
|
||||||
const remote = electron.remote;
|
|
||||||
|
|
||||||
remote.autoUpdater.on('update-downloaded', onUpdateDownloaded);
|
remote.autoUpdater.on('update-downloaded', onUpdateDownloaded);
|
||||||
|
|
||||||
function onUpdateDownloaded(ev, releaseNotes, ver, date, updateURL) {
|
function onUpdateDownloaded(ev: Event, releaseNotes: string, ver: string, date: Date, updateURL: string) {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'new_version',
|
action: 'new_version',
|
||||||
currentVersion: remote.app.getVersion(),
|
currentVersion: remote.app.getVersion(),
|
||||||
|
@ -35,7 +33,7 @@ function onUpdateDownloaded(ev, releaseNotes, ver, date, updateURL) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function platformFriendlyName() {
|
function platformFriendlyName(): string {
|
||||||
console.log(window.process);
|
console.log(window.process);
|
||||||
switch (window.process.platform) {
|
switch (window.process.platform) {
|
||||||
case 'darwin':
|
case 'darwin':
|
||||||
|
@ -72,11 +70,11 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
supportsNotifications() : boolean {
|
supportsNotifications(): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
maySendNotifications() : boolean {
|
maySendNotifications(): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +98,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
icon: avatarUrl,
|
icon: avatarUrl,
|
||||||
tag: 'vector',
|
tag: 'vector',
|
||||||
silent: true, // we play our own sounds
|
silent: true, // we play our own sounds
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
notification.onclick = function() {
|
notification.onclick = function() {
|
||||||
|
@ -123,7 +121,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
notif.close();
|
notif.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
getAppVersion() {
|
getAppVersion(): Promise<string> {
|
||||||
return q(remote.app.getVersion());
|
return q(remote.app.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,15 +138,15 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
electron.ipcRenderer.send('install_update');
|
electron.ipcRenderer.send('install_update');
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultDeviceDisplayName() {
|
getDefaultDeviceDisplayName(): string {
|
||||||
return 'Riot Desktop on ' + platformFriendlyName();
|
return 'Riot Desktop on ' + platformFriendlyName();
|
||||||
}
|
}
|
||||||
|
|
||||||
screenCaptureErrorString() {
|
screenCaptureErrorString(): ?string {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
requestNotificationPermission() : Promise {
|
requestNotificationPermission(): Promise<string> {
|
||||||
return q('granted');
|
return q('granted');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ export default class VectorBasePlatform extends BasePlatform {
|
||||||
* Get a sensible default display name for the
|
* Get a sensible default display name for the
|
||||||
* device Vector is running on
|
* device Vector is running on
|
||||||
*/
|
*/
|
||||||
getDefaultDeviceDisplayName() {
|
getDefaultDeviceDisplayName(): string {
|
||||||
return "Unknown device";
|
return "Unknown device";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.favicon.badge(notif, {
|
this.favicon.badge(notif, {
|
||||||
bgColor: bgColor
|
bgColor: bgColor,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(`Failed to set badge count: ${e.message}`);
|
console.warn(`Failed to set badge count: ${e.message}`);
|
||||||
|
@ -75,7 +75,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
* Returns true if the platform supports displaying
|
* Returns true if the platform supports displaying
|
||||||
* notifications, otherwise false.
|
* notifications, otherwise false.
|
||||||
*/
|
*/
|
||||||
supportsNotifications() : boolean {
|
supportsNotifications(): boolean {
|
||||||
return Boolean(global.Notification);
|
return Boolean(global.Notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +83,8 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
* Returns true if the application currently has permission
|
* Returns true if the application currently has permission
|
||||||
* to display notifications. Otherwise false.
|
* to display notifications. Otherwise false.
|
||||||
*/
|
*/
|
||||||
maySendNotifications() : boolean {
|
maySendNotifications(): boolean {
|
||||||
return global.Notification.permission == 'granted';
|
return global.Notification.permission === 'granted';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +94,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
* that is 'granted' if the user allowed the request or
|
* that is 'granted' if the user allowed the request or
|
||||||
* 'denied' otherwise.
|
* 'denied' otherwise.
|
||||||
*/
|
*/
|
||||||
requestNotificationPermission() : Promise {
|
requestNotificationPermission(): Promise<string> {
|
||||||
// annoyingly, the latest spec says this returns a
|
// annoyingly, the latest spec says this returns a
|
||||||
// promise, but this is only supported in Chrome 46
|
// promise, but this is only supported in Chrome 46
|
||||||
// and Firefox 47, so adapt the callback API.
|
// and Firefox 47, so adapt the callback API.
|
||||||
|
@ -113,13 +113,13 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
icon: avatarUrl,
|
icon: avatarUrl,
|
||||||
tag: "vector",
|
tag: "vector",
|
||||||
silent: true, // we play our own sounds
|
silent: true, // we play our own sounds
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
notification.onclick = function() {
|
notification.onclick = function() {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_room',
|
action: 'view_room',
|
||||||
room_id: room.roomId
|
room_id: room.roomId,
|
||||||
});
|
});
|
||||||
global.focus();
|
global.focus();
|
||||||
notification.close();
|
notification.close();
|
||||||
|
@ -132,7 +132,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
}, 5 * 1000);
|
}, 5 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getVersion() {
|
_getVersion(): Promise<string> {
|
||||||
const deferred = q.defer();
|
const deferred = q.defer();
|
||||||
|
|
||||||
// We add a cachebuster to the request to make sure that we know about
|
// We add a cachebuster to the request to make sure that we know about
|
||||||
|
@ -148,19 +148,19 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
},
|
},
|
||||||
(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 };
|
||||||
deferred.reject(err);
|
deferred.reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ver = body.trim();
|
const ver = body.trim();
|
||||||
deferred.resolve(ver);
|
deferred.resolve(ver);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAppVersion() {
|
getAppVersion(): Promise<string> {
|
||||||
if (this.runningVersion !== null) {
|
if (this.runningVersion !== null) {
|
||||||
return q(this.runningVersion);
|
return q(this.runningVersion);
|
||||||
}
|
}
|
||||||
|
@ -169,9 +169,9 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
|
|
||||||
pollForUpdate() {
|
pollForUpdate() {
|
||||||
this._getVersion().done((ver) => {
|
this._getVersion().done((ver) => {
|
||||||
if (this.runningVersion == null) {
|
if (this.runningVersion === null) {
|
||||||
this.runningVersion = ver;
|
this.runningVersion = ver;
|
||||||
} else if (this.runningVersion != ver) {
|
} else if (this.runningVersion !== ver) {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'new_version',
|
action: 'new_version',
|
||||||
currentVersion: this.runningVersion,
|
currentVersion: this.runningVersion,
|
||||||
|
@ -187,19 +187,18 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultDeviceDisplayName() {
|
getDefaultDeviceDisplayName(): string {
|
||||||
// strip query-string and fragment from uri
|
// strip query-string and fragment from uri
|
||||||
let u = url.parse(window.location.href);
|
const u = url.parse(window.location.href);
|
||||||
u.search = "";
|
u.search = "";
|
||||||
u.hash = "";
|
u.hash = "";
|
||||||
let app_name = u.format();
|
const appName = u.format();
|
||||||
|
|
||||||
let ua = new UAParser();
|
const ua = new UAParser();
|
||||||
return app_name + " via " + ua.getBrowser().name +
|
return `${appName} via ${ua.getBrowser().name} on ${ua.getOS().name}`;
|
||||||
" on " + ua.getOS().name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
screenCaptureErrorString() {
|
screenCaptureErrorString(): ?string {
|
||||||
// it won't work at all if you're not on HTTPS so whine whine whine
|
// it won't work at all if you're not on HTTPS so whine whine whine
|
||||||
if (!global.window || global.window.location.protocol !== "https:") {
|
if (!global.window || global.window.location.protocol !== "https:") {
|
||||||
return "You need to be using HTTPS to place a screen-sharing call.";
|
return "You need to be using HTTPS to place a screen-sharing call.";
|
||||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
import pako from 'pako';
|
import pako from 'pako';
|
||||||
import q from "q";
|
import q from "q";
|
||||||
|
|
||||||
|
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
|
||||||
import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
|
import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
|
||||||
|
|
||||||
import rageshake from './rageshake'
|
import rageshake from './rageshake'
|
||||||
|
@ -64,6 +65,8 @@ export default async function sendBugReport(bugReportEndpoint, opts) {
|
||||||
userAgent = window.navigator.userAgent;
|
userAgent = window.navigator.userAgent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const client = MatrixClientPeg.get();
|
||||||
|
|
||||||
console.log("Sending bug report.");
|
console.log("Sending bug report.");
|
||||||
|
|
||||||
const body = new FormData();
|
const body = new FormData();
|
||||||
|
@ -72,6 +75,11 @@ export default async function sendBugReport(bugReportEndpoint, opts) {
|
||||||
body.append('version', version);
|
body.append('version', version);
|
||||||
body.append('user_agent', userAgent);
|
body.append('user_agent', userAgent);
|
||||||
|
|
||||||
|
if (client) {
|
||||||
|
body.append('user_id', client.credentials.userId);
|
||||||
|
body.append('device_id', client.deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
if (opts.sendLogs) {
|
if (opts.sendLogs) {
|
||||||
progressCallback("Collecting logs");
|
progressCallback("Collecting logs");
|
||||||
const logs = await rageshake.getLogsForReport();
|
const logs = await rageshake.getLogsForReport();
|
||||||
|
|